7.85 SELECT_SQL

LANSA

7.85 SELECT_SQL


ネイティブi5/OSデータベース・アクセスを使用する標準のSELECTコマンドとは異なり、SELECT_SQLコマンドは、SQL/400製品を使用してデータベース・アクセスを実行します。

SELECT_SQLコマンドには2つの形式があります。1つは、このセクションで説明する十分に構造化された形式です。この形式では、SQLを正しく構成し、プラットフォームによって異なるオブジェクト名に対応することができますが、SELECTステートメントのタイプは非常に単純なものに制限されます。もう1つは、自由形式のSELECT_SQLです。この形式では、データベース・エンジンが有効な構文として受け入れる任意のSELECTステートメントを入力できますが、LANSAでは、複数のプラットフォームに渡るオブジェクト名の互換性維持について考慮されません。これらの2つの違いにより、SQLが複数のデータベースに渡って予想どおりに実行されない可能性が高くなります。詳細については、「自由形式のSELECT_SQL」を参照してください。

SELECT_SQLコマンドは、ENDSELECTコマンドと対で使用し、1つ以上のテーブル(ファイル)の、1行以上の行(レコード)を処理するための「ループ」を作成します。

例として、以下のSELECT_SQL / ENDSELECT ループはテーブルORDLINの製品および数量の値がすべて選択され、リストに1つずつセットされます:

----> DEF_LIST NAME(#ALIST) FIELDS(#PRODUCT #QUANTITY)
 ---> SELECT_SQL FIELDS(#PRODUCT #QUANTITY)
|               USING('SELECT "PRODUCT", "QUANTITY" FROM "MYDTALIB"."ORDLIN"')
|
|    ADD_ENTRY(#ALIST)
|
 --- ENDSELECT

 

SELECT_SQLの実装方法は、IBM i 上でRPGとして生成されたオブジェクトと、Cとして生成されたオブジェクトとでは異なります。RPGは、SELECT_SQLを静的な埋め込みSQLに実装します。一方、Cは、SELECT_SQLを呼び出しレベル・インターフェース(CLI)に実装するため、動的になります。この違いの効果については、以降、関連する箇所で説明していきます。

SELECT_SQLを使用する前に、以下の点を認識しておいてください。

1.   SELECT_SQLコマンドを含むファンクションをコンパイルするには、ライセンス交付された以下の製品が必要です。

IBM i RPGファンクション:

IBM - SQL DevKit

C実行可能プログラム:

他の製品は不要

      SELECT_SQLを使用するIBM i RPGアプリケーションをコンパイル済みの形式で特定のIBM iから別のIBM i に移植する場合、移植先マシンにライセンス交付済みのIBM製品がインストールされていなくても、そのアプリケーションを実行できます。ただし、移植先マシンでアプリケーションの再コンパイルが必要になった場合、問題が発生します。

2.   SELECT_SQLによってアクセスする情報は読み取り専用です。情報を更新する場合は、一般に、標準のSELECTコマンドを使用する方が簡単です。

3.   SELECT_SQLコマンドは、主に、レポート、画面、または他のテーブルに出力するために、1つ以上のSQLデータベース・テーブル(ファイル)からの複雑な抽出/結合/要約抽出を実行するためのものです。大容量または頻繁に使用される対話型アプリケーションでの使用は想定されていません。このように使用目的に制限がある一方、SELECT_SQLは、結果の出力先が画面、プリンター、または別ファイル(テーブル)のどれであっても、多くの結合/抽出/要約アプリケーションを大幅に単純化し、高速化することのできる非常に強力で便利なコマンドです。

4.   SELECT_SQLコマンドは、SQLデータベース機能で直接サポートされる、非常に強力なデータベース抽出/結合/要約機能を提供します。ただし現時点では、状況によって、i5/OSにおけるSQLの実装に大量のリソースが必要になる場合があります。このコマンドでもたらされる大きな利点と必要リソースのバランスの比較検討およびその適切な使用は、すべてユーザーの責任において行ってください。考慮すべき要因の1つに、WHEREパラメータで非キー・フィールドを使用するかどうかがあります。使用する場合、通常、SELECT_SQLの方がSELECTより高速です。使用しない場合は、SELECTの方が高速です。このことは、IBM i でも実行予定のプログラムをまずVisual LANSAで開発する場合に特に重要になります。これは、Visual LANSAでは、SELECTおよびSELECT_SQL間のパフォーマンスの差がそれほど大きくないためです。

5.   このセクションでは、ユーザーにSQLの'SELECT'コマンドに関する知識があることを前提としています。ここでは、RDMLファンクションからSQLの'SELECT'コマンドに直接アクセスする方法について説明しますが、SQLの'SELECT'コマンドの構文、形式、および使用については扱いません。

6.   WHERE、GROUP_BY、HAVING、およびORDER_BYパラメータが正しく指定されているかどうかの検査は非常に限定的です。

7.   SELECT_SQLはIOモジュール/OAMを使用しないため、リポジトリの検証およびトリガーは省略されます。

8.   ファイルがIBM i 以外のプラッフォームに配布される場合、省略値ではターゲット・プラットフォームのデータ・ライブラリを使用してテーブルが作成されます。ただし、SELECT_SQLへの呼び出しはソース区画のデータ・ライブラリでコンパイルされています。ですから、名前が異なる場合は、組み込み関数DEFINE_OVERRIDE_FILEを使ってテーブル・オーナーを変更する必要があります。

エラー処理

SQL機能がSELECT_SQLにより正しく 使用されていない場合エラーになります。SQLサーバーでは、エラーは例えば次のように表示されます。"SQL error code 16954… Executing SQL directly; no cursor" 同じ理由でも別のエラーコードになることもあります。またデータベースによって異なるエラーコードになります。

これはLANSAにより機能が認識されていない場合に起こり、単語が識別子だと仮定されて表示されています。この回避策としては、SELECT_SQLの自由形式のバージョンのコマンドを使用することです。

IBM i RPGファンクション

コマンドが正しくない場合、以下の2つの時点で失敗する可能性があります。

·         RDMLファンクションのコンパイル時。SQLコマンドのプリプロセッサにより、コマンドにエラーがあることが示されます。LANSAでは、このエラーが結果的なRPGのコンパイル・エラーとして解釈されます。この場合、結果的なRPGに埋め込まれたSQLコマンドで、エラー・メッセージの詳細を調べる必要があります。

·         実行時。アプリケーションをコンパイルしても、SELECT_SQLコマンドが実際に実行されるときに、SQLによってアプリケーションが失敗する場合があります。この場合、発行されたすべてのエラー・メッセージを調べ、正確な原因を突き止めてください。
SQLを使用する際は、SELECT_SQLコマンドにコンパイルする前に、対話型SQLを使用してコマンド(およびその構文)が「期待どおりに動作するかを検査」すると便利です。
実行時エラーに対処する際に、ファンクションでデバッグを使用すると、SQLにより役立つエラー分析情報が提供されます。これは、LANSAではなくSQL/400の機能ですが、通常のLANSAデバッグ・モード(i5/OSのみ)と連携して動作することに注意してください。

C実行可能プログラム

コマンドが正しくない場合、以下の診断を行えます。

·         ファンクション/コンポーネントの作成時に警告メッセージが表示されます。以下の表に、これらのメッセージの一部について説明します。

·         SQLは実行時に評価されるため、ファンクション/コンポーネントのコンパイル時には、それ以上の情報は得られません。すなわち、SQLは動的です。

·         実行時。アプリケーションのコンパイル後も、SELECT_SQLコマンドが実際に実行されるときに、SQLによってアプリケーションが失敗する場合があります。この場合、発行されたすべてのエラー・メッセージを調べ、正確な原因を突き止めてください。

SQLを使用する際は、SELECT_SQLコマンドにコンパイルする前に、対話型SQLを使用してコマンド(およびその構文)が「期待どおりに動作するかを検査」すると便利です。

実行時エラーに対処する際に、ファンクションに対してトレース機能を使用すると、SELECT_SQLコマンドから生成された正確なSQLをキャプチャすることができます。最新のトレース・ファイルを開き、"***ERROR"を検索してください。これは、エラー・メッセージ内のテキストと同じです。8行目または"Preparing"メッセージに戻ると、エラー原因になっているSELECTステートメントがわかります。これをコピーして対話型SQLに貼り付け、問題をさらに診断することができます。

·         サポートを受けるためにSELECT_SQLに関する問題を報告する場合は、トレース・ファイルと、生成されたCソース・コードを提出してください。

IBM i RPGファンクションのみ

·         クロスリファレンス情報は、FIELDSおよびFROM_FILESパラメータからのみ取得されます。現在のリリースでは、このコマンドの他のパラメータに埋め込まれたフィールドおよびファイルの参照は、LANSAクロスリファレンス機能に反映されません。

·         SQLからアクセスする際は、データベースの列名を使用する必要があります。C実行可能プログラムでは、データベースの列名、またはLANSAがその列を認識するために使用するフィールド名を使用できます。これは、命名レベル0のファイルを使用している場合は、異なる可能性があります。フィールド名を使用する場合(#なし)、LANSAは実行時にそのフィールド名を列名に変換します。そのため、実行時に使用される名前をすべてのプラットフォーム間で移植することが可能です。この動作は、列名を受け入れるすべてのパラメータで見られます。例として、命名レベル0のファイル#MYFILEを使用する以下のRDMLについて考えます。

      SELECT_SQL FIELDS(#A$ #B) FROM_FILES((#MYFILE)) WHERE('A_ = ''A VALUE''')
      DISPLAY FIELDS(#A$ #B)
      ENDSELECT
 

      このRDMLは、IBM i 以外のプラットフォームでは正常に動作しますが、IBM i では失敗します。A_が、FROM_FILESパラメータで指定されたいずれかのファイルの物理フィールドでない場合、Visual LANSAにより警告PRC1065が発行されます。すべてのLANSAプラットフォームで動作するよう可搬性のある方法で作成するには、以下のようにします。

      SELECT_SQL FIELDS(#A$ #B) FROM_FILES((#MYFILE)) WHERE('A$ = ''A VALUE''')
        DISPLAY FIELDS(#A$ #B)
      ENDSELECT
 

Visual LANSA Cファンクションのみ

·         1つのフィールドを最大50個のSELECT_SQLコマンドで指定できます。

·         SELECT_SQL内で使用されるLANSAフィールドの名前変更は、1つのフィールドにつきファンクションまたはコンポーネント全体で1回のみです。名前変更は、VL外部ファイルおよびIBM i 外部ファイルで使用されます。外部ファイルをロードすると、列が既存のフィールドと一致した場合に別のフィールドが作成されるため、問題が生じることはありません。

·         CLIはデータの取得時に論理ファイルを使用しないため、FROM_FILEパラメータで指定された論理ファイル内の* SELECT/OMIT基準は無視されます。

以下の理由から、SELECT_SQLコマンドを多用することはお勧めしません

·         SQLアクセス・コマンドは、RDMLファンクションに直接埋め込まれます。DBMSアクセスは直接的であり、IOM/OAMアクセス・ルーチンを経由しません。この方法では、読み取り前後のトリガーや、LANSA/スーパーサーバーによって実装された「シン・クライアント」型設計を適切に使用できなくなる可能性があります。

·         SELECT_SQLのコンテンツが画面のフィールドからのものである場合は、エンド・ユーザーがSELECT以外の処理が可能になります。特にプログラム可能な自由形式のバージョンだと次のようなことが簡単にできます。

REQUEST FIELD(#ANYSQL)

Select_Sql Fields(#STD_NUM) Using(#ANYSQL)

endselect.

    また、エンド・ユーザーは画面に次のように入力することも可能です。 "delete from mylib.afile;select count(*) from mylib.afile"

·         埋め込まれたSQL機能を使用すると、アプリケーションがプラットフォームに依存するようになる可能性があります。すべてのSQL機能がすべてのDBMSでサポートされるわけではありません。テーブルに関連付けられたIOM/OAMを省略すると、IOM/OAMによって提供される機能分離が省略されます。DBMSで定義された、プラットフォームに依存する拡張機能であるSQL機能は、アプリケーション設計者の判断で、アプリケーション設計者の責任において使用してください。

·         SELECT_SQLを使用する場合は、その使用を特定のファンクション内に限定し、ユーザー・インターフェース操作から分離してください。こうすることで、クライアント設計モデルでファンクションを"RPC" (リモート・プロシージャ・コール)として呼び出せるようになります。

作成時にVisual LANSAから発行されるメッセージ

LII0898W

あいまいです。フィールド#A$は複数のファイルに存在しており、異なる命名規則を使用しています。

このメッセージは、実行時にフィールドに対して使用されるSQL名に関するものです。このメッセージには、詳細な情報を提供するメッセージがさらに2つ続きます。ジェネレータは、次の優先順位に基づいて、使用する命名アルゴリズムを決定します。(1)古いVisual LANSAファイルではLANSA短縮名(mangled name)を使用(#A$をA_にするなど)、(2) LANSA定義の名前を使用する命名レベル1のファイル(すなわち、SQL名がフィールド名と同じ)、(3) FROM_FILESパラメータで最初に指定されている、VL外部ファイルの命名またはIBM i外部ファイルの命名。

メッセージに対処するために、RDMLを変更する必要はありません。メッセージに対する対応は、アクセスする必要のあるファイルのデータによって異なります。デフォルト以外の動作が必要な場合は、必要とする実際の名前でSQLソース・パラメータを追加します。

実行時およびIBM iでの実行中の成功率を高めるには、以下の警告に対処してください。

PRC1064

** WARNING: Name is not a defined field. Correct it for portability.

フィールド名としていずれかのファイルの実列を使用できるため、選択は機能しますが、LANSAでサポートされるすべてのデータベースで機能するためには、フィールド名(ハッシュ記号なし)を使用する必要があります。

PRC1065

** WARNING: Field <afield> is not a physical field in any of the files in the FROM_FILES parameter.

LANSAは、FROM_FILESパラメータで指定されたいずれかのファイルにおいて、SQLで指定された名前がLANSAで認識されているかどうかを検査します。その名前がLANSA名であるか、変換された名前であるか、または列名の変更であるかを検査する他、予約済みのSQLキーワードであるかどうかも検査します。どれにも該当しない場合、この警告が表示されます。

この警告の原因として、フィールド名の代わりに列名が使用されていることが考えられます。この場合、SQLはVisual LANSAで動作します。または、フィールドが正しくない可能性があり、この場合は実行時に失敗します。

PRC1067

** Fields A$ and A_ both resolve to A_ so A_ in SELECT_SQL will be set with Non-IBM i text A_

同じ名前に解決されるフィールドが複数ある場合、生成されたコードで各フィールドを識別できなくなり、コンパイル・エラーが発生します。SELECT_SQLでは、下位互換性を保つために固定リテラル値が使用されるため、コンパイルは成功します。ただし、これはIBM i で実行されない場合があります。1つのファンクション内でこのように一致するフィールドを使用しないようコードを変更してください。

例えば、列名がA_で固定されている場合、IBM iでは実行されません。代わりにA$を使用してください。

移植性に関する考慮事項

複数のプラットフォームを使用する場合、各プラットフォームで使用されるフィールド長を考慮してください。WHEREパラメータを参照してください。

Visual LANSAからIBM i 上のデータベースに接続するためにこのコマンドを使用しないでください。この目的でSELECT_SQLコマンドを使用しても、IBM i 上のデータベースではなく、PC上へのデータベースにアクセスします。このタイプの接続を行うには、リモート・プロシージャ・コール(すなわち、call_server_function)を使用する必要があります。

参照

SELECT_SQLのパラメータ

SELECT_SQLの列名と列値

SELECT_SQLの使用例

SELECT_SQLの参照ドキュメント

SELECT-SQLの強制変換

                                                         必須

  SELECT_SQL --- FIELDS ------- フィールド名 --- *SAME ----------->

                                |             SQLフィールド・ソース |

                                 ------ 最大1000 --------------

             >-- FROM_FILES ------- フィールド名 -- 相関 --->

                                |                              |

                                 ------------ 最大20 -----------

 -----------------------------------------------------------------

                                                         任意指定

             >-- WHERE -------- 'SQL where条件' ---------->

             >-- GROUP_BY ----- 'SQL group by句' ---------->

             >-- HAVING ------- 'SQL having条件' --------->

             >-- ORDER_BY ----- 'SQL order byパラメータ' ------->

             >-- DISTINCT ----- *NO ---------------------------->

                                *YES

             >-- IO_STATUS ---- フィールド名 --------------------->

                                *STATUS

             >-- IO_ERROR ----- *ABORT -------------------------|

                                *NEXT

                                *RETURN

                                ラベル