トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

ABAP/SELECT

Last-modified: 2016-06-01 (水) 13:01:15 (2878d)
Top > ABAP > SELECT


標準・アドオン問わずテーブルから、データを取得する命令。

概要

この命令を使わないプログラムはない!と言っていいくらい、客先や実装オブジェクトを問わず使用する命令。

それだけに、しっかりとした正しい使い方を身につけたいもの。

用法

主に企業活動のOutputとしてテーブルに格納されているデータを抽出し、レポーティングしたり、更にその結果で後続・付随プロセスを実施したりと、よく利用されている。

基本の文法は、SELECT 項目 FROM テーブル INTO 格納先 WHERE 条件。
抽出できた場合はSUBRCには0、該当データなしの場合は4、UP TO n ROWSのみ8が設定され得る。

サンプル

SINGLE

SELECT SINGLE VKGRP
         FROM VBAK
         INTO L_VKGRP
        WHERE VBELN = L_VBELN.

単一の行あるいはその項目を抜く。
キーの指定が不完全である場合は、最初にヒットしたレコードとなる。

INTO TABLE

SELECT VKGRP
  FROM VBAK
  INTO TABLE L_IT_VKGRP
 WHERE VKORG = L_VKORG.

条件に合致する複数のレコードを抜く。
下手に色々項目を指定したSELECT文を書くよりも、抜いた後で除外した方が速いこともしばしば。

INTO CORRESPONDING FIELD OF

SELECT *
  FROM BSEG 
  INTO CORRESPONDING FIELD OF TABLE T_BSEG
 WHERE BUKRS = P_BUKRS.

SELECT文で指定した項目やその並びと、格納先である構造や内部テーブルのそれが一致していなくても、取得先のテーブルと格納先の項目名を自動で判別し、よしなに取得処理をしてもらえる・・・というと便利そうに聞こえるが、基本的にはNG。

抜く側(データテーブル側)はともかくとして、格納先の項目やその順序は、SORTやATなどの前提となり詳細設計の重要な部分となるが、そこが明示的でなくなりボヤケてしまう。

また、パフォーマンスにかなりの悪影響を与え、サンプルのような書き方をしてしまうと間違いなくダンプする。*1

なので、基本的にはSELECTで定義する項目の順番と構造、内部テーブルで定義する項目の順番を一致させることで対応し、この命令は使わないのが良い。

また、昔は必要な項目を必要な並びで定義し、このオプションは使用せずに受け取ることがよしとされてきたが、「項目を一つ一つ宣言して割り当てることでコードの総量が増える」や「使用する項目が追加されたり仕様変更で使われない項目となったりした場合の修正」などの理由により、使わない項目があろうとテーブルの形そのままを宣言し、そのままの形で全項目受け取る流れになりつつある所見。

SELECT~ENDSELECT

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

SELECT VKGRP
  FROM VBAK
  INTO TABLE L_IT_VKGRP UP TO 100 ROWS
 WHERE VKORG = L_VKORG.

該当するデータを、指定したn件抽出する。
データブラウザ的な。

逆に言うと、そういう「ざっくりとテーブルのデータを眺める」的なニーズ以外では使うべきでない。

CLIENT SPECIFIED

SELECT *
  FROM KNA1 
  CLIENT SPECIFIED
  INTO TABLE T_KNA1
 WHERE KUNNR = P_KUNNR.

クライアント別ユーザIDの登録情報やALEを使用している場合など、複数クライアントを跨る情報取得のために用いる。
むしろ、これくらいしか使わないので普段は意識しなくてもよい。

FOR ALL ENTRIES

SELECT ~
  FROM VBAP
  INTO TABLE IT_VBAP
   FOR ALL ENTRIES IN IT_VBAK
 WHERE VKORG = IT_VBAK-VKORG.

既に存在する内部テーブルの情報に合致するデータのみを抜き出したい場合。例えば、ヘッダや基礎テーブルを先に抜いて明細や拡張テーブルを抜き出したい場合など。

なお、この命令を使用する場合は、内部テーブルに少なくとも1件以上のデータが格納されている事を確認すること。条件指定に使用するテーブルが空の場合は全件検索となってしまい、確実にパフォーマンスが劣化しショートダンプとなることも。

また、抽出項目にすべてのキー項目を指定しないと、distinctみたいな動きが入ってしまうので注意。

その他

SELECT文と汎用モジュールの使い分け

「とりあえずSELECT、なんでもSELECT」というのはあまりに雑というもので、一言で使い分けの基準を言えば、標準汎用モジュールで抜けない場合と言える。
BAPIが最たるものだが、コンフィグ・マスタ・伝票のいずれにしても抽出用の汎用モジュールがそこそこ用意されているもので、是非使っていきたい。
理由は、「SAPが品質を担保しているものが既に提供されており、不具合があったら修正してくれる、そんな手段を使わない理由はない」ということ。
それに、テーブル直読みでは分からない情報も、標準の例外処理で拾ってくれたりするのもポイント。*2
それに該当しなかったり、SAPにマッピングした項目が抽出条件になかったりする場合に用いればよろしい。
特に、マスタ系はともかく伝票系はこのケースが多いはずだ、

SELECT * がダメな理由

パフォーマンス上の理由があげられることが多いが、最も大きな要因は明示的でないこと
書いた人間は「項目追加となっても、あまり修正が入らない」という理由で使うことが多いかと思うが、要は何がしたいのか・肝になる項目は何なのかがアスタで書かれては読み取れないということが一番のまずいかと思う。
ソースコードは、メモ帳でもなければチラシの裏でもない。

ただ、抽出項目が多いとそれだけでSELECT以降の項目の指定行が増えるし、受け皿となるiTabの構造も変えなきゃならないなど保守性やコードの可視性という間手もあることから、対象がBSEGでもなければアスタ検索+テーブルの型そのものでiTab宣言しちゃうのが昨今のマジョリティのように思う。




【スポンサードリンク】
  





コメントはありません。 Comments/ABAP/SELECT?

お名前: