ABAPのSELECT命令のオプション版SELECT SINGLE命令について解説します。
SELECT SINGLEは、取得元のデータベーステーブルから対象のレコードを1件だけ取得したい場合に用いる命令です。
そもそもSELECT命令って何だっけ・・・?という不安な方は初めに以下の記事を読んでおさらいしましょう!
ABAPerを目指す方であれば知らないと恥ずかしい基本知識の1つですので、是非最後までご覧ください。
【復習】SELECT命令とは?
簡単にSELECT命令をおさらいします。
SELECT命令は、簡単に言うとデータベースからレコードを取り出す際に利用するABAP命令です。
SELECT(取得したい項目名) FROM(テーブル名) INTO TABLE (内部テーブル) (ENDSELECT).
SELECT命令はFROM句に指定したデータベーステーブルからレコードを読み込み、INTO句に記述した内部テーブル or 構造に取得したレコードを格納します。
SELECT * FROM DD02L INTO LS_DD02L WHERE TABNAME = 'BKPF' "テーブル AND AS4VERS = 0000. "バージョン
SELECT SINGLEとは?
SELECT SINGLEは、対象のデータベースから1件だけレコードを取得したい場合に利用します。
SELECT SINGLE:構文ルール
SELECT SINGLE (項目名) FROM (テーブル名) INTO (構造).
構文ルールは難しくありません。SELECTの後ろに「SINGLE」と記述するだけです。
ただし、SELECT SINGLEは、データを1件だけ取得する命令のため格納先(INTOの後ろ)には構造を指定します。この場合内部テーブルを指定することはできません。
内部テーブルと構造の区別に自信がない方は、こちらのページをご覧ください。ABAPで用いられるデータオブジェクトの区別を初心者にも分かりやすいよう図解しています!
SELECT SINGLE:サンプルコード
"SELECT-SINGLE" は対象のテーブルから、レコードを1件だけ抽出し、指定した構造に格納します。
SELECT SINGLE VKORG FROM TVKO INTO @DATA(LW_VKORG)
このコードでは
1行目: VKORG というテーブル項目の値を
2行目: TVKO というテーブルから1件だけ取得し
3行目: LW_VKORG という構造に格納する
処理を行われることになります。
もし、取得したい項目が複数ある場合は、以下のように複数の項目を並べて記述すればOK。
SELECT SINGLE VKORG KUNNR BOAVO EKORG FROM TVKO INTO @DATA(LW_VKORG)
SELECT SINGLEの注意点・Tips
SELECT-SINGLE命令は決して難しい命令ではありません。そのため、使い方や構文ルールで迷う点は少ないはずです。
そのうえで、実際にABAPを書いてみた人しかわからない「落とし穴」や「Tips」を最後にご説明します。
注意点1:一致するデータが何件あっても1件だけしか取得しない
SELECT-SINGLEを利用する際に注意すべきなのは、FROM句で指定したテーブルAに該当するデータが複数件あった場合です。以下のテーブル「TABLE_A」をご覧ください。
該当レコード(取得したいレコード)が複数ある場合でも、取得できるのは1件のみです。該当するデータを1件取得した時点で、処理は終了します。
SELECT文は基本的に上のレコードから順に読み込んで取得していくため、上記例でいえば、二つ目のレコードは取得されません。レコードの読み取りさえ行われません。
注意点2:複数項目を取得する場合
以下の構文を見てみましょう。
SELECT SINGLE a b c d FROM TVKO INTO LW_VKORG WHERE VKORG = @P_VKORG.
さて、この場合取得した項目a,b,c,dは、構造「LW_VKORG」にどのように入るでしょうか?これ実は結構な落とし穴です。
よくある間違いが「データ型」が同じになる箇所に自動的にはいっていくのでは?というもの。または「項目名」が同じであればそこに自動的にマッピングされるのでは?というもの。
正解は「a,b,c,d」の順に左から順に格納されていきます。つまり、データを入れる先の構造も「a,b,c,d」の順にデータ型を設定しておく必要があります。
Tips:SELECT-SINGLEを対象データの有無判定に利用する
SELECT-SINGLEは予め対象のレコードが「1件しかないとわかっている場合」もしくは「対象のレコードを1件だけ取得すればよい場合」に利用します。
この考え方をさらに発展させると、対象のテーブルに指定したレコードが1件以上存在するかどうか?を判定するような使い方も可能です。
SELECT SINGLE * FROM DD02L INTO LDS_DD02L WHERE TABNAME = LV_TABNAME " テーブル名 AND AS4VERS = 0000. " バージョン IF SY-SUBRC <> 0. ASSERT 0 = 1. "想定外エラー ENDIF.
少し上級者向けの内容になりますが、上記サンプルコードではASSERT命令を利用しています。
ASSERT命令とは何か?を知りたい方はこちらの記事をご覧ください。
SAP / ABAPを1から学習したい方は
初めてABAPを勉強するのは結構難しいですよね。
でもその悩みを抱えているのは一人じゃありません。全てのABAP使いが同じ道を進んできました。
ABAPをはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?
読者料典 【完全無料】ABAP:学習カリキュラム ←こちらから!