SELECT(SINGLE、UP TO n ROWS、条件式)

16.3 SELECT(SINGLE、UP TO n ROWS、条件式)

3. SELECT(SINGLE、UP TO n ROWS、条件式)

SELECTは、データベース上のレコードを抽出するために用いられます。
標準データベーステーブルや、アドオンのデータベーステーブルでも、レコードを抽出することができます。

次の構文は、SELECT命令の形です。

・<項目名>には、抽出したい項目名
 「*」と記述すると、全項目を抽出します。
・FROM句には、抽出先のデータベーステーブル名
・INTO句には、抽出したレコードを格納する構造名か内部テーブル名
・WHERE句には、抽出する条件(論理式)

<項目名>と<内部テーブル名>内の項目数に過不足がある場合は、
エラーまたは警告が表示されるので注意が必要です。

SELECT命令の意味は、
データベーステーブルから、条件に一致するレコードの指定した項目を抽出し、構造または内部テーブルに格納しなさい という命令です。

SELECT命令のイメージ図

SELECT (SINGLE)

SELECT SINGLEは、対象のデータベーステーブルのプライマリーキー(データベースのレコードを一意に識別するための項目)を全て条件にて指定し、1件だけを取得する命令です。

REPORT ZCUSLIST1_K_OPENSQL_1.
DATA: wa_mara TYPE ZDBTBL_TEST_K.

DATA: BEGIN OF line,
        col1(3) TYPE c,
        col2(9) TYPE c,
      END OF line.

DATA itab LIKE TABLE OF line.

*2. 最初の1行だけ取得
SELECT SINGLE *
  FROM ZDBTBL_TEST_K CLIENT SPECIFIED
  INTO wa_mara
  WHERE CLIENT = '800'
  AND NAME = 'GIGI'.

  line-col1 = wa_mara-CLIENT.
  line-col2 = wa_mara-NAME.
  APPEND line TO itab.

LOOP AT itab INTO line.
   WRITE:
   / line-col1,line-col2.
ENDLOOP.

データベーステーブル

実行結果

このサンプルにおけるSELECT SINGLE命令部分の説明

データベーステーブル:ZDBTBL_TEST_Kから、
条件(項目:CLIENT(クライアント)が800、かつ、項目:NAME(名前)がGIGI)に一致するレコードを1行のみ、
全項目を抽出し、
構造:wa_maraに格納しなさい、
という意味の命令になります。

SELECT (UP TO nn ROWS)

SELECT UP T0 nn ROWSでは、指定したレコード数のみ取得することができます。
※ nn は任意の数字。

<DBtab>から抽出した項目すべてを<構造>に格納し、編集した後に<内部テーブル>に格納し、その処理をnn回繰り返す、といった処理になります。

補足(CLIENT SPECIFIEDについて)

「自動クライアント処理を無効」にするために記述しております。
もし、記載していないとエラーが出力することになり、クライアント指定が出来なくなります。
自動クライアント処理とは、自動的にプログラムが実行されるクライアント(800)に紐づくデータの処理が行うことを指します。
基本的に、SAPの仕様として SQL 文にてデータベースの クライアント項目(MANDT)を上書きすることはできないようになっており、その仕様上、SQL 文の WHERE 句でクライアント項目に対して条件を指定することができません。
上記の自動クライアント処理を無効にすることで、上記の制限を抜けることが出来、
WHERE 句でクライアント項目(MANDT)を指定できるようになります。
プログラムの都合上でもし、クライアント項目(MANDT)に関連したデータを抽出したい場合に利用します。

そのクライアント処理を無効にすることによって、クライアント項目(MANDT) を WHERE 句とテーブル作業領域の両方で使用できるようになります。

サンプルコード UP TO n ROWS

REPORT ZCUSLIST1_K_OPENSQL_2.
DATA: wa_mara TYPE ZDBTBL_TEST_K.

DATA: BEGIN OF line,
        col1(3) TYPE c,
        col2(9) TYPE c,
      END OF line.

DATA itab LIKE TABLE OF line.

*1. 最初の2行だけ取得
SELECT * FROM ZDBTBL_TEST_K UP TO 2 ROWS
  INTO wa_mara.
   WRITE:
    / wa_mara-CLIENT, wa_mara-NAME.
   line-col1 = wa_mara-CLIENT.
   line-col2 = wa_mara-NAME.
   APPEND line TO itab.
ENDSELECT.

LOOP AT itab INTO line.
   WRITE:
   / line-col1,line-col2.
ENDLOOP.

データベーステーブル

実行結果

このサンプルにおけるSELECT UP TO n ROWS命令部分の説明

ここでは、データベーステーブル:ZDBTBL_TEST_Kから、2行、全項目を抽出し、実行結果画面に書き出したり、内部テーブル:itabに格納したりしています。

処理の流れは以下となります。

1度目の処理ではデータベーステーブルの1行目を読み込み、2度目の処理ではデータベーステーブルの2行目を読み込みます。

よって、この処理では
 クライアント:800、名前:GIGI
 クライアント:800、名前:KAKA
の2行が実行結果画面に出力されるとともに、内部テーブルに格納されます。

(実行結果画面に2度同じ内容が出力されているのは、後続のLOOP処理にて内部テーブルの内容の出力を行っているためです。)

SELECT(条件式)

条件式の部分には、抽出条件を記述します。主にWHERE句で使用します。

※1 %01 :%は、任意の文字列。%01であれば、下2桁が01のものを抽出します。
※2 sel :SELECT-OPTIONSで宣言した項目名またはレンジテーブルを指定できます。

サンプルコード UP TO n ROWS

REPORT ZCUSLIST1_K_OPENSQL_3.
DATA: wa_mara TYPE ZDBTBL_TEST_K.

DATA: BEGIN OF line,
        col1(3) TYPE c,
        col2(9) TYPE c,
      END OF line.

DATA itab LIKE TABLE OF line.

*1. 最初の2行だけ取得
SELECT * FROM ZDBTBL_TEST_K UP TO 2 ROWS
  INTO wa_mara
  WHERE NAME = 'GIGI'.
   WRITE:
    / wa_mara-CLIENT, wa_mara-NAME.
   line-col1 = wa_mara-CLIENT.
   line-col2 = wa_mara-NAME.
   APPEND line TO itab.
ENDSELECT.

LOOP AT itab INTO line.
   WRITE:
   / line-col1,line-col2.
ENDLOOP.

実行結果

SELECT (INTO TABLE)

SELECT INTO TABLEでは、条件に一致するレコードを取得し、内部テーブルに格納します。

<DBtab>から、<条件式>に一致するレコードの<項目>を抽出し、<内部テーブル>に格納します。

内部テーブルには、複数のレコードが一括で格納されます。
対象レコードが1件の場合は、1件のみ格納されます。

SELECT SINGLE、および、SELECT UP TO nn ROWSとの違い

SELECT SINGLEは、対象レコードを1件抽出し、構造に格納します。

SELECT UP TO nn ROWSは、対象レコードを1件ずつ抽出し、構造に格納することを、nn回繰り返します。

SELECT INTO TABLEは、対象レコードを一括で抽出し、内部テーブルに格納します。

サンプルコード SELECT INTO TABLE

REPORT ZR2111ABAPSQL_KANDA04.
*構造定義
DATA: BEGIN OF WK_LINE,
  NUM            TYPE ZTEST_TBL_001-NUM,     "出席番号
  LASTNAME  TYPE ZTEST_TBL_001-LASTNAME,     "姓
  FIRSTNAME	TYPE ZTEST_TBL_001-FIRSTNAME,    "名
END OF WK_LINE.
*内部テーブル定義
DATA IT_TAB LIKE TABLE OF WK_LINE.

*選択画面定義
PARAMETERS: P_GRADE TYPE ZTEST_TBL_001-GRADE DEFAULT 1,                  "学年
                       P_CLASS TYPE ZTEST_TBL_001-CLASS DEFAULT 'A'.     "組

START-OF-SELECTION.
*DBテーブル:ZTEST_TBL_001から、GRADE(学年)、CLASS(組)が選択画面の
*条件に一致するレコードの項目:NUM(出席番号)、LASTNAME(姓)、FIRSTNAME(名)を
*複数件一括で抽出し、内部テーブルに格納
SELECT NUM LASTNAME FIRSTNAME
  FROM ZTEST_TBL_001
  INTO TABLE IT_TAB
  WHERE GRADE = P_GRADE            "学年
    AND   CLASS  = P_CLASS.        "組

*抽出できなかった場合、処理終了
IF SY-SUBRC <> 0.
  MESSAGE S001(Z_MSGCLASS).
  LEAVE LIST-PROCESSING.
ENDIF.

*抽出結果を出力
WRITE: /1'出席番号',15'姓',30'名'.
LOOP AT IT_TAB INTO WK_LINE.
   WRITE: /1   WK_LINE-NUM,         "出席番号
          15 WK_LINE-LASTNAME,      "姓
          30 WK_LINE-FIRSTNAME.     "名
ENDLOOP.

選択画面

データベーステーブル:ZTEST_TBL_001

SELECT INTO TABLE命令実行後の内部テーブル: IT_TABの内容

実行結果

このサンプルにおけるSELECT INTO TABLE命令部分の説明

ここでは、データベーステーブル:ZTEST_TBL_001から、
項目:GRADE(学年)が選択画面のGRADE(学年)に等しく、かつ、
項目:CLASS(組)が選択画面のCLASS(組)に等しいレコードの
項目:NUM(出席番号)、LASTNAME(姓)、FIRSTNAME(名)を
一括で抽出し、内部テーブル:IT_TABに格納しています。

この例ですと、GRADE(学年)が1、CLASS(組)がAのレコードは、
データベーステーブル:ZTEST_TBL_001には6件ありますので、
6レコードが内部テーブル:IT_TABに格納されます。


NEXT>> 16.4 デバッグ機能