標準・アドオン問わず[[テーブル>SAPのオブジェクト/テーブル]]から、データを取得する命令。
* 概要 [#j4d77dd6]
この命令を使わないプログラムはない!と言っていいくらい、客先や実装オブジェクトを問わず使用する命令。
それだけに、しっかりとした正しい使い方を身につけたいもの。
** 用法 [#m1e61e8f]
主に企業活動のOutputとして[[テーブル>SAPのオブジェクト/テーブル]]に格納されているデータを抽出し、レポーティングしたり、更にその結果で後続・付随プロセスを実施したりと、よく利用されている。
基本の文法は、SELECT 項目 FROM [[テーブル>SAPのオブジェクト/テーブル]] INTO 格納先 WHERE 条件。
抽出できた場合はSUBRCには0、該当データなしの場合は4、UP TO n ROWSのみ8が設定され得る。
** サンプル [#p8e30ede]
*** SINGLE [#fcc02cc3]
SELECT SINGLE VKGRP
FROM VBAK
INTO L_VKGRP
WHERE VBELN = L_VBELN.
単一の行あるいはその項目を抜く。
キーの指定が不完全である場合は、最初にヒットしたレコードとなる。
*** INTO TABLE [#o3361ac4]
SELECT VKGRP
FROM VBAK
INTO TABLE L_IT_VKGRP
WHERE VKORG = L_VKORG.
条件に合致する複数のレコードを抜く。
下手に色々項目を指定したSELECT文を書くよりも、抜いた後で除外した方が速いこともしばしば。
*** INTO CORRESPONDING FIELD OF [#m8637696]
SELECT *
FROM BSEG
INTO CORRESPONDING FIELD OF TABLE T_BSEG
WHERE BUKRS = P_BUKRS.
SELECT文で指定した項目やその並びと、格納先である構造や内部テーブルのそれが一致していなくても、取得先のテーブルと格納先の項目名を自動で判別し、よしなに取得処理をしてもらえる・・・というと便利そうに聞こえるが、基本的にはNG。
抜く側(データテーブル側)はともかくとして、格納先の項目やその順序は、SORTやATなどの前提となり詳細設計の重要な部分となるが、そこが明示的でなくなりボヤケてしまう。
また、パフォーマンスにかなりの悪影響を与え、サンプルのような書き方をしてしまうと間違いなくダンプする。((キー未指定など基本的な個所もあるが))
なので、基本的にはSELECTで定義する項目の順番と構造、内部テーブルで定義する項目の順番を一致させることで対応し、この命令は使わないのが良い。
また、昔は必要な項目を必要な並びで定義し、このオプションは使用せずに受け取ることがよしとされてきたが、「項目を一つ一つ宣言して割り当てることでコードの総量が増える」や「使用する項目が追加されたり仕様変更で使われない項目となったりした場合の修正」などの理由により、使わない項目があろうとテーブルの形そのままを宣言し、そのままの形で全項目受け取る流れになりつつある所見。
*** SELECT~ENDSELECT [#p782c08f]
SELECT VKGRP
FROM VBAK
INTO L_VKGRP
WHERE VKORG = L_VKORG.
...
ENDSELECT.
指定した条件と一致するデータを1件ずつループしながら取得する。
色々理由があり、SAPから使うなとのお達しが。
最悪なのは、SELECT SINGLEを使わずにこの書き方+UP To n ROWSを使うことで1件を抜き出すこと。
そういう書き方をしているABAPerを見たら、要注意。
*** UP TO n ROWS [#u4b63463]
SELECT VKGRP
FROM VBAK
INTO TABLE L_IT_VKGRP UP TO 100 ROWS
WHERE VKORG = L_VKORG.
該当するデータを、指定したn件抽出する。
[[データブラウザ>SAPの共通用語/データブラウザ]]的な。
逆に言うと、そういう「ざっくりとテーブルのデータを眺める」的なニーズ以外では使うべきでない。
*** CLIENT SPECIFIED [#g68c6253]
SELECT *
FROM KNA1
CLIENT SPECIFIED
INTO TABLE T_KNA1
WHERE KUNNR = P_KUNNR.
クライアント別ユーザIDの登録情報やALEを使用している場合など、複数クライアントを跨る情報取得のために用いる。
むしろ、これくらいしか使わないので普段は意識しなくてもよい。
** FOR ALL ENTRIES [#ba8969c9]
SELECT ~
FROM VBAP
INTO TABLE IT_VBAP
FOR ALL ENTRIES IN IT_VBAK
WHERE VKORG = IT_VBAK-VKORG.
既に存在する内部テーブルの情報に合致するデータのみを抜き出したい場合。例えば、ヘッダや基礎テーブルを先に抜いて明細や拡張テーブルを抜き出したい場合など。
なお、この命令を使用する場合は、内部テーブルに少なくとも1件以上のデータが格納されている事を確認すること。条件指定に使用するテーブルが空の場合は全権検索となってしまい、確実にパフォーマンスが劣化しショートダンプとなることも。
なお、この命令を使用する場合は、内部テーブルに少なくとも1件以上のデータが格納されている事を確認すること。条件指定に使用するテーブルが空の場合は全件検索となってしまい、確実にパフォーマンスが劣化しショートダンプとなることも。
また、抽出項目にすべてのキー項目を指定しないと、distinctみたいな動きが入ってしまうので注意。
* その他 [#lb3435f1]
** SELECT文と汎用モジュールの使い分け [#m086a387]
「とりあえずSELECT、なんでもSELECT」というのはあまりに雑というもので、一言で使い分けの基準を言えば、''標準[[汎用モジュール>SAPのオブジェクト/汎用モジュール]]で抜けない場合''と言える。
[[BAPI>SAPのオブジェクト/BAPI]]が最たるものだが、コンフィグ・マスタ・[[伝票>SAPの共通用語/伝票]]のいずれにしても抽出用の[[汎用モジュール>SAPのオブジェクト/汎用モジュール]]がそこそこ用意されているもので、是非使っていきたい。
理由は、「SAPが品質を担保しているものが既に提供されており、不具合があったら修正してくれる、そんな手段を使わない理由はない」ということ。
それに、[[テーブル>SAPのオブジェクト/テーブル]]直読みでは分からない情報も、標準の[[例外処理>アドオン/例外処理]]で拾ってくれたりするのもポイント。((余計なことすんな!ってシーンもあるが))
それに該当しなかったり、SAPにマッピングした項目が抽出条件になかったりする場合に用いればよろしい。
特に、マスタ系はともかく[[伝票>SAPの共通用語/伝票]]系はこのケースが多いはずだ、
** SELECT * がダメな理由 [#o8bc941f]
パフォーマンス上の理由があげられることが多いが、最も大きな要因は''明示的でないこと''。
書いた人間は「項目追加となっても、あまり修正が入らない」という理由で使うことが多いかと思うが、要は''何がしたいのか・肝になる項目は何なのかがアスタで書かれては読み取れないということ''が一番のまずいかと思う。
ソースコードは、メモ帳でもなければチラシの裏でもない。
ただ、抽出項目が多いとそれだけでSELECT以降の項目の指定行が増えるし、受け皿となるiTabの構造も変えなきゃならないなど保守性やコードの可視性という間手もあることから、対象がBSEGでもなければアスタ検索+テーブルの型そのものでiTab宣言しちゃうのが昨今のマジョリティのように思う。
~
~
CENTER:【スポンサードリンク】
#htmlinsert(amazon_book_sap_system_implement)
~
~
----
#pcomment(reply)