データベース(標準テーブル/アドオンテーブル)からレコードを取得するSELECT命令について解説します。
一口にSELECT命令といっても、SELECT~ENDSELECTのようにループする形でレコードを取得する方法や、ORDER BYオプション、UP TO n ROWSオプションなど理解すべき基本事項は複数存在します。
このページでは、ABAPの初心者の方向けに、SELECT文の基本をサンプルコードを用いながら分かりやすく解説します。
ABAPを実際にコーディングしている方や、ABAPを1から学習の方であれば知らないと恥ずかしい基本知識ばかりですので、是非最後までご覧ください。
SELECT文の基本
SELECT(テーブルの項目名)
FROM(テーブル名)
INTO(構造)/ INTO TABLE (内部テーブル)
(ENDSELECT).
SELECT命令はFROM句に指定したデータベーステーブルからレコードを読み込み、INTO句に記述した内部テーブル or 構造に取得したレコードを格納する命令です。
早速、以下のサンプルを見てみましょう。1つ1つ、分かりやすく解説します。
SELECT BKPF~BUKRS BKPF~BELNR BKPF~GJAHR BKPF~BLART FROM BKPF INTO TABLE GDT_BKPF.
SELECT命令
SELECTの直後に、取得したいテーブルの項目名を左から順番に記述します。
SELECT BKPF~BUKRS BKPF~BELNR BKPF~GJAHR BKPF~BLART
記述する順番は、格納先の内部テーブルの項目順と一致している必要があります。
全項目を取得する場合/*
対象のレコードの全項目を取得したい場合は、ワイルドカード「*」アスタリスクを用います。
SELECT * FROM BSEG INTO T_BSEG.
ただし、標準テーブルの場合、テーブルの項目数は数十個存在するケースもあり利用する際には注意が必要です。
「*」で全ての項目を取得するよりも、指定した項目を個別に格納していくほうがパフォーマンスがよくなるため、できるだけ項目をバイネームで指定するようにしましょう。
FROM句
FROM句には、取得元のテーブル名を記述します。標準テーブルでも、アドオンテーブルでも指定することができます。
ただし、内部テーブルを指定することはできません。内部テーブルからレコードを抽出する場合は、READ TABLE命令を利用します。この点、初心者の方ほど誤りやすいので注意して覚えておきましょう。
SELECT BKPF~BUKRS BKPF~BELNR BKPF~GJAHR BKPF~BLART FROM BKPF
INTO句
INTO句には、抽出したレコードを格納する内部テーブル、もしくは構造を指定します。
格納先データオブジェクト | 構文 |
---|---|
構造 | INTO (構造名) |
内部テーブル | INTO TABLE (内部テーブル名) |
後述するSELECT-SINGLEではない限り、基本は格納先のデータオブジェクトは内部テーブルである場合が普通です。
SELECT BKPF~BUKRS BKPF~BELNR BKPF~GJAHR BKPF~BLART FROM BKPF INTO TABLE GDT_BKPF.
SY-SUBRC / SY-DBCNTの値
SELECT命令の実行結果によって、システム項目(SY-SUBRC / SY-DBCNT)が以下のように設定されます。
SELECT命令の後続ロジックで、レコードを取得できた場合・取得できなかった場合で処理を変える場合が多くあるので、以下2つのシステム項目に設定される値は合わせて覚えておくと良いでしょう。
- 0/処理が成功(1件以上のレコードを取得できた場合)
- 4/処理が失敗(レコードが取得できない場合/指定したテーブルにレコードが見つからない場合)
- n(0以上の整数) ⇒ 取得したレコードの数
WHERE句:抽出条件
指定したデータベーステーブルから、特定のレコードのみを取得したい場合にはWHEREオプションを利用します。
SELECT(テーブルの項目名)
FROM(テーブル名)
INTO(内部テーブル or 構造)
WHERE(条件式)
(ENDSELECT).
条件式は、比較演算子を利用して取得条件を記述します。
SELECT BKPF~BUKRS BKPF~BELNR BKPF~GJAHR BKPF~BLART FROM BKPF INTO TABLE GDT_BKPF WHERE BKPF~BUKRS = "1000".
処理対象となるレコード数は少なければ少ないほどパフォーマンス的にGoodなので、WHEREオプションをうまく用いて処理レコードを限定すると良いでしょう。
SELECT命令の処理パターン
SELECT命令では、取得したいレコード数や実現したい機能に応じていくつかの処理パターンを使い分ける必要があります。
ここでは、基本となるSELECT命令の処理パターンを3つに分類して解説します。
レコードを1つのみ取得したい場合―SELECT SINGLE
レコードを1つのみ取得したい場合は「SELECT SINGLE」を利用します。
SELECT SINGLE (項目名)
FROM (テーブル名)
INTO (構造).
SELECT SINGLEについては、押さえておくべきポイントがいくつかあるため別のページで解説しています。詳しく知りたいという方は、こちらのページをご覧ください。
レコード取得とループ処理を同時に行う場合 ①SELECT~ENDSELECT
SELECT (項目名)
FROM (テーブル名)
INTO (構造)
ループ処理
ENDSELECT.
SELECT命令をENDSELECTで閉じる形にすると、対象となるレコードをループしながら取得・格納する処理を実現することができます。
SELECT * FROM BSEG INTO W_BSEG. WRITE: W_BSEG-BURKS, W_BSEG-GJAHR. ENDSELECT.
「①レコードの取得⇒②レコード処理」がループして処理される形になります。②レコード処理を記述しない場合でも用いることが可能です(単純にデータ取得としても利用可能)。
ただし、SELECT~ENDSELECT(SELECTループ)はパフォーマンス悪化の原因となるため、基本的には利用を避けたほうが良い命令として広く知られています。
複数レコードを取得する場合(ループ処理なし) ②SELECT
ループ処理を伴わずにレコードを取得したい場合は、ENDSELECTで閉じる必要はありません。
SELECT (項目名)
FROM (テーブル名)
INTO (内部テーブル).
SELECT~ENDSELECTとの違いは、DBからレコードを一括で取得してくるという点で異なります。

SELECT~ENDSELECTでは1件ずつ①取得と②格納を繰り返すためループ処理が可能ですがその分パフォーマンスが落ちます。ENDSELECTで閉じない場合は、一括でデータを①取得し②格納するのみなので格段にパフォーマンスが向上します。
ORDER BYオプションの利用
ORDER BYオプションで取得したレコードを任意のキー or キー項目でソートすることが可能です。
主キーでソートする場合
SELECT (項目名)
FROM (テーブル名)
INTO (内部テーブル)
ORDER BY PRIMARY KEY.
SELECT * FROM BSEG INTO T_BSEG. ORDER BY PRIMARY KEY.
任意のキーでソートする場合
SELECT (項目名)
FROM (テーブル名)
INTO (内部テーブル)
ORDER BY 項目a 項目b 横目c・・・.
SELECT * FROM BSEG INTO T_BSEG. ORDER BY BURKS ASCENDING BELNR DESCENDING.
ORDER BYオプションを用いない場合、格納されるレコードの順番は一定ではありません。すなわち、1回目に実行した場合と2回目に実行した場合に、格納されるレコードの順番が異なるという可能性があります。
尚、ORDER BYオプションは、格納されるレコードが複数件存在することが前提となるため、SELECT-SINGLEや、SELECT~ENDSELECTとの併用はできない点に注意しましょう。
レコードの順番が毎回同様になっている必要がある場合は、必ずORDER BYオプションを利用しましょう。
UP TO n ROWSオプションの利用
取得するレコード数を指定したい場合は、UP TO n ROWSオプションを利用します。
※n・・・1以上の整数
SELECT (項目名)
FROM (テーブル名)
INTO (内部テーブル)
UP TO n ROWS.
SELECT * FROM BSEG INTO T_BSEG. UP TO 2 ROWS.
2件取得したいのであれば、「UP TO 2 ROWS」を。10件取得したいのであれば、「UP TO 10 ROWS」と記述します。
UP TO n ROWSオプションでは、指定した数のレコードを格納した時点で処理が完了します。そのため、パフォーマンスの向上が期待できます。
ABAPを1から学習したい方は
ABAPを1から学習したい方は、以下の記事をご覧ください。
こちらの記事では、ABAPを用いて簡単な機能を実装できるようにするための必須知識を解説しております。今、本サイトで一番人気の記事ですので是非合わせてご覧ください。