コードの分析およびテスト
データ型およびデータ型変換の正しい使用
文字項目の処理
ABAP SQL でのコードプッシュダウンの使用
内部テーブルのパフォーマンスの改善
権限チェックの実装
効果的なオブジェクト指向コードの設計
例外クラスの定義と処理
ABAP コードへの文書の追加

ABAP SQL での式の使用

Objective

After completing this lesson, you will be able to aBAP SQL でいくつかの単純な式を使用します。

リテラル

ABAP SQL のリテラルと定数

最も単純な式はリテラルです。ABAP 自体と同様に、ABAP SQL では、単純な引用符で指定されるテキストリテラルと数値リテラル (正または負の整数) の 2 種類のリテラルが認識されます。ABAP SQL のリテラルのデータ型は ABAP の場合と同じです。テキストリテラルは C 型、数値リテラルは I 型です。

この例では、項目一覧の最初のエレメントはテキストリテラルであり、2 番目と 3 番目のエレメントは数値リテラルであり、一方は正の値を持ち、もう 1 つは負の値です。

注記

逆引用符で指定された文字列リテラルは、ABAP SQL では使用できません。

リテラルを直接使用する代わりに、定数を定義して ABAP SQL 文内で使用することをお奨めします。これにより、読みやすさが向上し、C や I よりも多くのタイプにアクセスできます。ABAP SQL 文で定数を使用する場合、接頭辞 @ は必須です。

この例では、エレメント一覧の 4 番目のエレメントは、タイプ I の名称 C_NUMBER および値 1234 の定数です。

試してみる: リテラル

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいグローバルクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    123456789101112131415161718
    CONSTANTS c_number TYPE i VALUE 1234. SELECT FROM /dmo/carrier FIELDS 'Hello' AS Character, " Type c 1 AS Integer1, " Type i -1 AS Integer2, " Type i @c_number AS constant " Type i (same as constant) INTO TABLE @DATA(result). out->write( EXPORTING data = result name = 'RESULT' ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンソール出力を分析します。
  5. メソッド if_oo_adt_classrun~main( ) の実行をデバッグし、内部テーブル RESULT の列 CHARACTERINTEGER1、および INTEGER2 のデータ型を分析します。
  6. FIELDS 一覧にリテラルを追加して、構文について理解します。

CAST 式

ABAP 自体とは異なり、ABAP SQL では暗黙的なデータ型変換は認識されません。CDS の CAST 式を使用すると、データ型変換を明示的に実装することができます。

データ型変換のオペランドは、リテラルまたはデータソースの項目のみにすることはできません。算術式や定義済み関数など、他のすべての種類の式を使用できます。

ほとんどの事前定義済ディクショナリデータ型 (INT4、CHAR、DEC、FLTP、DATS など) を対象データ型として指定することができます。ABAP SQL では、ディクショナリデータエレメントをターゲットデータ型として使用することはできません。

注記

変換元データ型と変換先データ型の組合せに関しては、制限があります。組合せの中にはまったくサポートされていないものもあります。また、制限付きでのみ機能し、実行時エラーが発生する可能性があるものもあります。組合せの詳細については、ABAP 言語文書を参照してください。

ABAP ディクショナリ内の事前定義済データ型

ABAP ディクショナリでデータ型 (データエレメントなど) を定義する場合は、特定の事前定義済データ型セットが使用されます。このようなディクショナリデータ型を使用して ABAP でデータオブジェクトを型指定する場合、ディクショナリデータ型は特定の事前定義済 ABAP データ型にマッピングされます。たとえば、ディクショナリデータ型 CHAR は ABAP データ型 C、データ型 INT4 はデータ型 I、データ型 FLTP はデータ型 F、データ型 DEC は P などにマッピングされます。

一部のディクショナリデータ型には、ABAP に直接対応するデータ型がありません。たとえば、ディクショナリデータ型 MANDT は、技術的にはデータ型 CHAR(3) と同じですが、データベーステーブル項目に使用される場合は特別な意味があります。この特別な意味が不要な ABAP では、データ型 MANDT がデータ型 C LENGTH 3 にマッピングされます。同様に、ディクショナリデータ型 UNIT および CUKY は ABAP データ型 C および QUAN にマッピングされ、CURR は ABAP データ型 P にマッピングされます。

ディクショナリデータ型 DEC、QUAN、および CURR の長さは、桁数として指定されます。ABAP データ型 P の長さは、バイト数として指定されます。n バイトは 2 *n - 1 桁に対応します。

CAST 式の例

この例では、同じテキストリテラルが異なる互換性のあるターゲット型に変換されます。以下の事実に注意してください。

  • 数値データ型 (INT4、DEC、FLTP) への変換で、ソースリテラルに数字以外の文字が含まれていると、実行時エラーが発生します。
  • データ型 DATS への変換では、8 桁が有効な日付を形成しているかどうかはチェックされません。
  • データ型 CHAR( 4 ) は互換性のあるデータ型ですが、変換によって情報が失われます。

注記

列 DEC_10_2 には小数点以下 1 桁しか表示されないという事実が UI のアーティファクトです。

試してみる: CAST 式

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいグローバルクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    1234567891011121314151617181920
    SELECT FROM /dmo/carrier FIELDS '19891109' AS char_8, CAST( '19891109' AS CHAR( 4 ) ) AS char_4, CAST( '19891109' AS NUMC( 8 ) ) AS numc_8, CAST( '19891109' AS INT4 ) AS integer, CAST( '19891109' AS DEC( 10, 2 ) ) AS dec_10_2, CAST( '19891109' AS FLTP ) AS fltp, CAST( '19891109' AS DATS ) AS date INTO TABLE @DATA(result). out->write( EXPORTING data = result name = 'RESULT' ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンソール出力を分析します。
  5. メソッド if_oo_adt_classrun~main( ) の実行をデバッグし、内部テーブル RESULT のさまざまな列のデータ型を分析します。
  6. FIELDS 一覧にさらに CAST 式を追加して、構文について理解します。

ケース区分

ABAP SQL には、SELECT 命令のエレメント一覧で他の式のオペランドとして使用できるケース区分が用意されています。

ケース区分からは、1 つの値のみが返されます。返される値は、一連の条件によって異なります。ケース区分は、常にキーワード CASE で始まり、キーワード END で終わります。残りは、ケース区分のタイプによって異なります。

単純なケース区分は、ABAP 制御構造 CASE … ENDCASE に対応しています。オペランドの値を一連の他のオペランドと比較します。テーブル項目、リテラル、定数、ABAP 変数、SQL 式など、任意の SQL 式をオペランドとして使用することができます。

複雑なケース区分 (別名: 検索ケース) は、ABAP 制御構造 IF … ENDIF とそのオプション部分 ELSEIF および ELSE に対応します。指定されたシーケンスのキーワード WHEN の後に SQL 条件が評価されます。最初の条件が true の場合は、CASE 式の結果を決定します。どの条件も真でない場合、結果は ELSE オプションによって決定されます。

単純な例では、項目 TITLE の内容を使用して、長いテキストを項目 TITLE_LONG として返します。TITLE に値 "Mr." が含まれ、列 TITLE_LONG に値 "Mister" が含まれています。TITLE に 'Mrs.' が含まれ、列 TITLE_LONG に 'Misses' が含まれています。TITLE のその他の値については、TITLE_LONG に空白が含まれます。

複雑な場合のこの例では、一連の SQL 条件を使用して、新しいカラム BOOKING_STATE の値を決定します。

列 SEATS_OCCUPIED の値が列 SEATS_MAX の値より小さい場合、新しい列ではより多くの座席が利用可能であることを示すテキストが返されます。これに該当しない場合にのみ、次の条件がチェックされます。

試行: ケース区分

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいグローバルクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    123456789101112131415161718192021222324252627282930313233343536373839404142
    SELECT FROM /dmo/customer FIELDS customer_id, title, CASE title WHEN 'Mr.' THEN 'Mister' WHEN 'Mrs.' THEN 'Misses' ELSE ' ' END AS title_long WHERE country_code = 'AT' INTO TABLE @DATA(result_simple). out->write( EXPORTING data = result_simple name = 'RESULT_SIMPLE' ). ********************************************************************** SELECT FROM /DMO/flight FIELDS flight_date, seats_max, seats_occupied, CASE WHEN seats_occupied < seats_max THEN 'Seats Avaliable' WHEN seats_occupied = seats_max THEN 'Fully Booked' WHEN seats_occupied > seats_max THEN 'Overbooked!' ELSE 'This is impossible' END AS Booking_State WHERE carrier_id = 'LH' AND connection_id = '0400' INTO TABLE @DATA(result_complex). out->write( EXPORTING data = result_complex name = 'RESULT_COMPLEX' ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンソール出力を分析します。
  5. CASE 式を使用して、構文について理解します。