6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[ABAP] 7.5xの新しいSELECT文記述方法について(NEW ABAP SQL SELECT IN ABAP 7.5x)(その2)

Last updated at Posted at 2020-08-12

こんにちは。

今回は、SELECT文の書き方についての2回目となります。
7.5xでSELECTでできることは大きく増えていますが、自分で業務で書くコードで必要性が高いと
考えたものについてまとめてみました。
※実行環境がベーシスリリース7.53ですので、最新リリースの7.54については未確認です。
また、ABAP SQLでの検証となりますので、ABAP CDSのみで動作する機能についても
動作確認をしていません。その点のご留意をお願いいたします。

記事一覧

  • [7.5xの新しいSELECT文記述方法について(その1)] (https://qiita.com/Go_Ohta/items/3882caf9149619e8bdd7)

    • これまでの記述方法との比較、FIELDS句、インライン定義
  • [7.5xの新しいSELECT文記述方法について(その2)] ※当記事

    • リテラル・固定値・演算値・文字列編集・条件分岐・型変換
  • [7.5xの新しいSELECT文記述方法について(その3)] (https://qiita.com/Go_Ohta/items/bf7bd6f2964675c97740)

    • 日付系機能・グループ化・内部テーブルをデータソースとして使用・UNION/WITH・RIGHT JOIN/CROSS JOIN

・・・


内容

  • リテラル値・固定値・変数・項目初期値を取得項目に指定する

  • 演算値を取得項目に指定する

    • 数値用機能(Numeric Functions)一覧
  • 文字列編集処理の結果を項目に設定する

    • 文字列編集用機能(String Functions)一覧
  • CASEによる条件分岐

  • COALESCEによる条件分岐

  • CASTによる型変換

  • 次回予定


1.リテラル値・固定値・変数値・項目初期値を取得項目に指定する

リテラル値・CONSTANTSで定義した固定項目値・変数値を、SQLの取得項目として指定できます。
インライン宣言による内部テーブル定義の場合で、項目定義時(=SELECT時)に値を設定できないような場合は、初期値を設定することが可能です。

リテラル値・固定値・変数・初期値
DATA: var1 TYPE char10 VALUE 'VARIABLES'.
CONSTANTS: CONS1 TYPE char10 VALUE 'CONSTANTS'.

SELECT FROM vbak AS t1
    FIELDS
      'LITERAL' AS lit,                  "リテラル値
      @var1 AS  var_field,               "変数
      @CONS1 AS cns_field,               "固定値
      @abap_on as check,                 "予約語
      @( VALUE vbak-erdat( ) ) AS erdat, "初期値
   INTO TABLE @DATA(results).

リテラル値以外は先頭に「@」を付ける必要があります。固定値を設定することのメリットとして、
初期値設定に利用できるという点かな、と思っていました。しかし、その後下記のように、データの存在チェックとして任意の項目値を取得する場合に、取得処理とその後の判定ロジックを使いまわせる点もあるとのことです。

存在チェックサンプル
SELECT FROM MARA as t1
  FIELDS @abap_on 
  where 
  into @lw_exist_chk.
if lw_exist_chk.  "「= abap_on」の記述を省略
" データが存在した場合のロジック
else.
" データが存在しなかった場合のロジック
endif.

※この情報は、下記openSAPの内容から参考にさせていただきました。
openSAP ABAP Development for SAP 3rdWeek Unit.1 Recent Open SQL Enhancements - Part 1


2.演算値を取得項目に指定する

テーブル項目値や変数、数値リテラルを使用した演算結果を項目値として格納することができます。
制限として以下があります。

  • 負の値、小数位を持ったリテラルは使用できない(-10、1.1など)→変数に値を事前定義して使用する

    • ABAP CDSの場合は小数点ありリテラル数値を記載しても適切に動作するようです
  • 除算を使用する場合、後述のDIVかDIVISIONを使う方が便利ですが、「/」を使用する場合は割る側も割られる側もFLTP、DECFLOAT16、DECFLOAT34のどれかににCAST(型変換)するようにとSAPHELPに記載があります。ただし、DECFLOAT16と同34は7.54から導入されたため、結果を確認できていません。

演算値
SELECT FROM vbap
    FIELDS
       netwr,  "項目IDがNETWRで定義される
       kwmeng, "項目IDがkwmengで定義される
       netwr * 100 AS jpy_netwr, "演算結果
       CASE kwmeng "条件分岐
        WHEN 0 THEN 0
        ELSE division( netwr , kwmeng, 3 )
       END AS calc2,
       CASE kwmeng 
         WHEN 0 THEN CAST( 0 AS FLTP )  "結果がFLTP型になるため
         ELSE CAST( netwr AS FLTP ) / CAST( kwmeng AS FLTP )
       END AS calc3
    INTO TABLE @DATA(results).

上記2つのコードは、インライン宣言で内部テーブルを定義しています。それらのFIELDS句の各項目を見ると、
netwr, のようにASで項目名を定義していないものと、
netwr * 100 AS jpy_netwr, のようにASで項目名を定義している2種類があります。
この違いについては以下のとおりです。

  • ASによる項目名定義が必要

    • リテラル値、固定値、変数値
    • 項目名重複などの理由で、DB項目名と内部テーブル項目定義名を異なる名称にする場合
      • netwr AS netwr2 など
    • 演算値、編集加工値、型変換(上記のCAST)、条件分岐(上述のCASE)の結果
  • ASによる項目定義を省略可能

    • DB項目値そのままを取得しDB項目名と同じ名称で内部テーブル項目名を定義する場合
      • kwmeng as kwmeng → kwmeng のみでOK

数値用機能(Numeric Functions)一覧

すでにDIVISIONが上記のサンプルコードに登場していますが、
数値項目処理用の機能概要を以下一覧にまとめます。(以前からあるSUM・AVGなどは省略)。

機能 説明
ABS 対象値の絶対値
CEIL 対象値より小さくない、最大の整数
DIV 対象2値を除算したときの商
※2値の符号が異なる場合は負の値
DIVISION 対象2値の除算結果を指定小数位で丸める
FLOOR 対象値より大きくない、最小の整数
MOD 対象値2値を除算したときの余り
ROUND 対象値を指定された桁で丸め

SAPHELP Arithmetic Functions


3.文字列編集処理の結果を項目に設定する

簡単な文字列の編集処理がSQLでできるようになりました。

文字列編集
SELECT FROM sflight
  FIELDS
    @abap_on AS check, "固定値
    carrid,
    connid,
    concat_with_space( carrid,connid,4 ) AS cws,
    left( planetype, 3 ) AS plane_series1,
    length( planetype ) as plane_series2,
    lpad( CAST( paymentsum AS CHAR ) , 20, '0'  ) AS paymentsum_char,
    concat_with_space( CAST( seatsmax_b AS CHAR ), CAST( seatsocc_b AS CHAR ), 2 ) AS field_concat
 INTO TABLE @DATA(results).

###文字列編集用機能(String Functions)一覧

文字列項目処理用の機能概要を以下一覧にまとめます。

機能 説明
LOWER 対象値内の1バイト英大文字を英小文字に変換
UPPER 対象値内の1バイト英小文字を英大文字に変換
CONCAT 2項目の文字列結合。各項目の後ろの1バイトスペースは無視される。 ※3項目以上の場合はネストする
CONCAT_WITH_SPACE CONCATと同様だが、文字列間に1バイトスペースを指定数分設定する
LEFT 対象値の左側から、文字数分の内容を取得
LPAD 対象値の左側から、指定した長さまで指定文字で埋める
LTRIM 対象値の左側から、指定文字を除去
RIGHT 対象値の右側から、文字数分の内容を取得
RPAD 対象値の右側から、指定した長さまで指定文字で埋める
RTRIM 対象値の右側から、指定文字を除去
INSTR 対象値の中で指定値が最初に発生する位置を返す ※位置が1文字目の場合は1
LENGTH 文字列の文字数を取得
REPLACE 対象値内にある変換前値すべてを、変換後値に変換
SUBSTRING 対象値の指定位置から、指定文字数分の内容を取得

SAPHELP String Functions

なお、文字列リテラルや一部の文字項目(制限あり)を連結する場合は、「&&」を使用した連結が可能です。

文字列連結

FIELDS
  'PARTNER NAME IS ' && ADRC~name1 && ' ' && ADRC~name2 as FIELD1 "&&で結合した場合

  CONCAT( 'PARTNER NAME IS ' , 
          concat_with_space( ADRC~name1, ADRC~name2, 1 ) ) as field1 "CONCAT系で書いた場合

ただし、結合できる項目がリテラル値または、ディクショナリタイプがCHAR、CLNT, CUKY, LANG, UNITのものとなります。
また後述するCASTを使用して文字列への型変換をした値も使用できないため、基本的に「テキスト項目のみを連結する場合のみ」使用可能と
考えておくのが良いかと思います。


4.CASEによる条件分岐

上述のコードでもう使用済みですが、条件分岐を使用して項目の設定値を決定することが可能となりました。
値(演算値や編集加工値含む)による分岐と、設定値ごとに条件を記述していく2つのパターンがあります。

4.1.値による条件分岐

CASE1
   CASE kwmeng                         "演算値、編集加工値なども使用可能
    WHEN 0 THEN 0                      "WHENは最低1つ必要。THENが必要
    WHEN 1 THEN netwr                  "2つめ以降のWHENは省略可能
    ELSE division( netwr , kwmeng, 3 ) "ELSE省略可能
    END AS calc2,                      "ENDCASEではなくEND

4.2.複雑な条件分岐

CASE1
   CASE                                             "何も書かない
    WHEN matnr is initial  THEN 'MATERIAL IS BLANK' "各判定条件をWHENの後に記述
    WHEN matnr = 'DUMMY' and TYPE = 'DUNNY' THEN 'DUMMY MATERIAL' "複数の判定条件を書くことが可能
    WHEN matnr <> 'DUMMY' and TYPE = 'DUMMY' THEN 'INVALID DATA'
    WHEN matnr = 'DUMMY' and TYPE <> 'DUMMY' THEN 'INVALID DATA'
    else 'VALID DATA'
    END AS ERRMSG1

どちらの場合も、

  • WHENは最低1つ必要、ELSEはなくても可
  • 演算値や文字列編集値を判定用項目や条件、設定値に使用可能
  • 1つのWHEN内の判定条件内に、ANDやORなどを利用して複数の条件を記述可能

SAPHELP CASE


5.COALESCEによる条件分岐

COALESCE(コアレス)を使用すると、「列挙した値のうち、最初にNull値でない値」を項目値に設定することが可能です。

COALESCE
COALESCE( A, B, C, D ) as FIELD1

上記の場合、A、B、Cの順番で値が確認され、最初にNull値でない値があるとその値がFIELD1に設定されます。
もし、すべての値がNullの場合は、最後に設定されたdの値が設定されます。
上記をCASEで書き換えると以下のようになります。

COALESCE→CASE

CASE 
  WHEN A is not null then A
  WHEN B is not null then B
  WHEN C is not null then C
  ELSE D
  end as FIELD1

SAPHELP COALESCE


6.CASTによる型変換

こちらも上述のコードに出てきていますが、CASTを使用して項目の型を変更することが可能です。
ABAPHELPにあるコードに少し追加をしていろいろ試してみました。変換先をCHARにした場合、制限が少ないようです。

CAST

DELETE FROM demo_expressions.
INSERT demo_expressions FROM @( VALUE #(
         id   = 'X'
         num1 = 111                           "INT4型
         numlong1 = '12345678'     "INT8型
         dec3 = '123.456'                   "DEC型
         dats2 = sy-datum                 "DATS型
         char1  = 'ABCDEFGHIJ'         "CHAR型
         char2  = '0000123456'          "NUMC型
        ) ).

SELECT SINGLE
       FROM demo_expressions
       FIELDS
            CAST( num1      AS CHAR( 20 ) ) AS col1,
            CAST( numlong1  AS DEC( 12, 3 ) ) AS col2,
            CAST( dec3      AS CURR( 10, 2 ) ) AS col3,
            CAST( dats2     AS CHAR( 20 ) ) AS col4,
            CAST( char1     AS CHAR( 4 ) ) AS col5,
            CAST( char2     AS NUMC( 5 ) ) AS col6,
            CAST( concat( @sy-datlo, @sy-timlo )  AS char( 20 ) ) AS col7
       WHERE id = 'X'
       INTO @DATA(results).
 cl_demo_output=>display(  results ).

image.png

変換前型と変換後型の組み合わせで一部制限があり、下記SAPHELPにて一覧化されています。
SAPHELP CAST


7.次回予定

次回は、複数のSQLの処理結果を連結するUNION、WITH、内部テーブルを使ったJOINなどを予定しています。
今回の内容は以上です、ありがとうございました。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?