例3 - クエリーから結果セットを受け取る READ コマンド
このSQLServiceの例では、READコマンドを使用して、クエリーから結果セットを受け取る方法が示されます。READコマンドを使用する場合、SET PARAMETER(*MAP)コマンドを使用してフィールド列のマッピングを設定する必要があります。
この例では、JSMJDBC という IBM i のデータベースに接続します (これは IBM i の例であるため、データベース名はライブラリ名になります)。
CONNECTコマンドで使用されるドライバー名は、SQLServiceプロパティ・ファイルで定義されるドライバー名とパスに相当します。アクセスするファイルはTBLNAMEとなります。これは、ID、NAME、AGE、SALARY、DEPT、GRADEの各フィールドで構成されます。
この例では以下のステップを行います。
1. JSMCOMMAND から返されるメッセージを処理するフィールドを定義します;
2. テーブルのフィールドを結果リストの列にマッピングする場合に使用されるフィールドを定義します。ここで定義されるフィールドは、クエリーが実行されるテーブルで定義されたフィールドの長さとタイプに一致していなければなりません。
3. フィールド列のマッピングを入れるために使用されるリストに必要な2つのフィールドを定義します。
4. 列マッピングを入れるリストを定義します。これは2つの列のリストにします。このリストの最初の列には列番号が入り、2番目のフィールドには列名が入ります。
5. ステップ 2 で定義したフィールドを使って、2 つの作業リストを定義します。これらのリストは、READ コマンドを使って、クエリにより作成された結果リストから読み込まれます。この例では、2つの列を使って、必要に応じて結果リストに戻りながら、異なる列にアクセスする方法が示されています。2つの参照リストはこれらの作業リストと同じ形式で定義され、この参照リストを使用して画面に結果が表示されます。作業リストのENTRYS値の意味については、ポイント9を参照してください。
6. 次にJSMを開始し、SQLServiceをロードして、データベース・ドライバーに接続します。
7. 列フィールドのマッピングを定義します。定義するには、#FIELDを適切な列に、#COLUMNを(テーブルの)適切なフィールド名に設定します。各マッピングは、#MAPLST作業リストに新しいエントリーとして追加され、SET PARAMETER(*MAP)コマンドが発行されます。SERVICE_LISTはこのコマンドの一部として渡され、ここで定義するフィールドは、マッピング・リストで使用されるフィールドになります。マッピング・リストは、JSMコマンドのTO_GET部分でも指定する必要があります。
8. コマンドを実行 (EXECUTE) します。この例ではプリペアド・ステートメントは使用されませんが、EXECUTEコマンドに直接入力されます。このJSMコマンドでは作業リストは提供されないことに注意してください。EXECUTE QUERYの場合、通常、作業リストは結果リストを入れるために用意されますが、この場合、代わりにREADコマンドを選択して結果リストにアクセスします。
9. 次に、READ コマンドを発行して結果セットのデータにアクセスします。この例では、異なる列にアクセスするたびにこの操作が2回行われます。この例で実証される機能は、作業リストに入るよりも大きな結果リストがある状況で特に役立ちます。そのため、READで列数を減らすと、管理可能なチャンク単位でデータにアクセスできます。最初のREADにはキーワードSCROLL(*NO)があります。このため、2番目のREADでは、最初のREADで選択された同じレコードの列を選択できます。2番目のREADにはキーワードSCROLL(*YES)があります。このキーワードでは、次のDOWHILEループが開始すると、最初のREADが次のレコード・セットで開始します。各READで読み込まれるレコードの数は、作業リストのサイズによって異なります。この例では、100 - NB ENTRYS(100)に設定されています。READコマンドにはSERVICE_LISTがあります。このキーワードで指定されたフィールドは、JSMコマンドのTO_GET部分に指定された作業リストで定義されたフィールドと同じでなければなりません。
10. 結果の表示後に、サービスとの接続を解除してJSMを閉じます。
- この SQLService 例では、READ コマンドを使って、
- クエリからの結果セットを受け取る方法が示されています。
- READ コマンドの使用時は、SET PARAMETER(*MAP)
- を使って、フィールド列のマッピングを設定する
- 必要があります。
- この例では、JSMJDBC という名前の IBM i データベースに
- 接続していることに注意してください。
- (これは IBM i の例のため、このデータベース名はライブラリ名です)。
- CONNECT コマンドで使用されるドライバ名は、
- SQLService のプロパティ・ファイルに定義されたドライバ名とパスに
- 一致します。アクセスするファイルの名前はTBLNAME で、
- このファイルは、フィールド ID、NAME、AGE、SALARY、
- DEPT、GRADE のフィールドから構成されています。
- 手順の詳細はコード内に示されています:
FUNCTION OPTIONS(*DIRECT) - 1. JSMCOMMAND から戻されるメッセージを
- 処理するフィールドを定義
DEFINE FIELD(#JSMSTS) TYPE(*CHAR) LENGTH(020)
DEFINE FIELD(#JSMMSG) TYPE(*CHAR) LENGTH(256)
DEFINE FIELD(#JSMCMD) TYPE(*CHAR) LENGTH(256) - 2. テーブルのフィールドを結果リストの列に
- マッピングする際に使用するフィールドを定義します。
- これらのフィールドの長さとタイプは、クエリ対象のテーブルに
- 定義されているフィールドと一致していなければいけません。
DEFINE FIELD(#COL1) TYPE(*CHAR) LENGTH(010)
DEFINE FIELD(#COL2) TYPE(*CHAR) LENGTH(020)
DEFINE FIELD(#COL3) TYPE(*DEC) LENGTH(008) DECIMALS(0)
DEFINE FIELD(#COL4) TYPE(*DEC) LENGTH(012) DECIMALS(2)
*3. フィールド列マッピング保持用の - 2 つのフィールドを定義します。.
DEFINE FIELD(#FIELD) TYPE(*CHAR) LENGTH(010)
DEFINE FIELD(#COLUMN) TYPE(*CHAR) LENGTH(030) - 4.列マッピングを入れるリストを定義します。
- このリストは 2 列のリストでなければなりません。
- このリストの最初の列には列番号が、
- 2 番目の列には列名が入ります。
DEF_LIST NAME(#MAPLST) FIELDS(#FIELD #COLUMN) TYPE(*WORKING) - 5. ステップ 2 で定義したフィールドを使って、2 つの作業リストを
- 定義します。これらのリストは、READ コマンドを使って、
- クエリにより作成された結果リストからデータが読み込まれます。
- この例では、2 つの列を使って、必要に応じて
- 何度でも結果リストに戻りながら
- 異なる列にアクセスする方法が示されています。
- 作業リストと同じ形態の 2 つの参照リストが定義され、
- これを使って画面に結果が表示されます。
* この作業リストの ENTRYS 値の重要性については、 - ステップ 9 の内容を参照してください。
DEF_LIST NAME(#WRKLST1) FIELDS(#COL1 #COL3) TYPE(*WORKING) ENTRYS(100)
DEF_LIST NAME(#WRKLST2) FIELDS(#COL1 #COL2 #COL4) TYPE(*WORKING) ENTRYS(100)
DEF_LIST NAME(#BRWLST1) FIELDS(#COL1 #COL3) ENTRYS(100)
DEF_LIST NAME(#BRWLST2) FIELDS(#COL1 #COL2 #COL4) ENTRYS(100)
*6. 次に JSM を開始後、SQLService をロード (LOAD) して - データベース・ドライバに接続 (CONNECT) します。
USE BUILTIN(JSM_OPEN) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG)
USE BUILTIN(JSM_COMMAND) WITH_ARGS('SERVICE_LOAD SERVICE(SQLSERVICE) TRACE(*NO)') TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG)
CHANGE FIELD(#JSMCMD) TO('CONNECT DRIVER(DB2) DATABASE(JSMJDBC) USER(PERSON1) PASSWORD(BINGO)')
USE BUILTIN(JSM_COMMAND) WITH_ARGS(#JSMCMD) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG)
- 7. 列フィールドのマッピングを定義します。
- この定義では、#FIELD を適切な列に設定し、
- #COLUMN には (テーブルから).適切なフィールド名が設定されます。
- 各マッピングは新しいエントリーとして作業リスト #MAPLST に
- 追加され、その後 SET PARAMETER(*MAP) コマンドが発
- 行されます。このコマンドの一部として、SERVICE_LIST が
- 渡されていることに注目してください。ここで定義されているフィールドは
- マッピングリストで使われたものです。このマッピングリストは
- JSM コマンドの TO_GET の部分でも指定する必要が
- あります。
CHANGE FIELD(#FIELD) TO(COL1)
CHANGE FIELD(#COLUMN) TO(ID)
ADD_ENTRY TO_LIST(#MAPLST)
CHANGE FIELD(#FIELD) TO(COL2)
CHANGE FIELD(#COLUMN) TO(NAME)
ADD_ENTRY TO_LIST(#MAPLST)
CHANGE FIELD(#FIELD) TO(COL3)
CHANGE FIELD(#COLUMN) TO(AGE)
ADD_ENTRY TO_LIST(#MAPLST)
CHANGE FIELD(#FIELD) TO(COL4)
CHANGE FIELD(#COLUMN) TO(SALARY)
ADD_ENTRY TO_LIST(#MAPLST)
CHANGE FIELD(#JSMCMD) TO('SET PARAMETER(*MAP) SERVICE_LIST(FIELD,COLUMN)')
USE BUILTIN(JSM_COMMAND) WITH_ARGS(#JSMCMD) TO_GET(#JSMSTS #JSMMSG #MAPLST)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG) - 8. コマンドを実行 (EXECUTE) します。この例では、事前に準備された
- ステートメントは使われていませんが、EXECUTE コマンドに
- 直接入力されます。この JSM コマンドでは作業リストが
- 提供されていないことに注意してください。通常、クエリの実行 (EXECUTE QUERY)
- では、結果リストを入れる作業リストが提供されますが、
- この例では、代わりに READ コマンドを利用して、
- 結果リストにアクセスします。
CHANGE FIELD(#JSMCMD) TO('EXECUTE QUERY(SELECT ID,NAME,AGE,SALARY FROM TBLNAME)')
USE BUILTIN(JSM_COMMAND) WITH_ARGS(#JSMCMD) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG) - 9. 次に READ コマンドを使って、結果セットのデータに
- アクセスします。この例では、この操作が 2 回行われますが、
- それぞれ異なる列へのアクセスとなります。
- この例で示されている機能が役に立つのは、
- 結果リストが作業リストが対応できる範囲よりも
- 大きい場合などです。
- READ コマンドがアクセスする列の数を減らすことで、
- データをより処理可能なサイズに抑えることが
- できます。
- 最初の READ コマンドに、キーワード SCROLL(*NO) が
- あります。このキーワードにより、2 番目の READ コマンドは、
- 最初の READ コマンドにより選択された同じレコードから
- 列を読み込みます。2 つめの READ には、キーワード SCROLL(*YES)
- がありますが、これは次の DOWHILE 検索を始め
- 最初の READ は次のレコード・セットを開始することを意味しています。
- 各 READ コマンドにより読み込まれるレコード数は
- 作業リストのサイズにより異なります。
- この例では、100 - NB ENTRYS(100) に設定されています。
- これらの READ コマンドには、SERVICE_LIST が
- 含まれていますが、このキーワードで指定されたフィールドは
- JSM コマンドの TO_GET セクションに指定された
- 作業リストに定義のフィールドと同じある必要が
- あります。
DOWHILE COND('#JSMSTS *EQ OK')
CLR_LIST NAMED(#WRKLST1)
CLR_LIST NAMED(#WRKLST2)
CLR_LIST NAMED(#BRWLST1)
CLR_LIST NAMED(#BRWLST2)
USE BUILTIN(JSM_COMMAND) WITH_ARGS('READ SERVICE_LIST(COL1,COL3) SCROLL(*NO)') TO_GET(#JSMSTS #JSMMSG #WRKLST1)
IF COND('#JSMSTS *EQ NOROW')
LEAVE
ENDIF
SELECTLIST NAMED(#WRKLST1)
ADD_ENTRY TO_LIST(#BRWLST1)
ENDSELECT
DISPLAY BROWSELIST(#BRWLST1)
USE BUILTIN(JSM_COMMAND) WITH_ARGS('READ SERVICE_LIST(COL1,COL2,COL4)') TO_GET(#JSMSTS #JSMMSG #WRKLST2)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG)
SELECTLIST NAMED(#WRKLST2)
ADD_ENTRY TO_LIST(#BRWLST2)
ENDSELECT
DISPLAY BROWSELIST(#BRWLST2)
ENDWHILE - 10. 結果を表示後、サービスの接続を解除して、
- JSM を閉じます。
USE BUILTIN(JSM_COMMAND) WITH_ARGS(DISCONNECT) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG)
USE BUILTIN(JSM_CLOSE) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMSTS #JSMMSG) - サブルーチン
SUBROUTINE NAME(CHECK) PARMS((#JSMSTS *RECEIVED) (#JSMMSG *RECEIVED))
IF COND('#JSMSTS *NE OK')
DISPLAY FIELDS(#JSMMSG)
USE BUILTIN(JSM_CLOSE) TO_GET(#JSMSTS #JSMMSG)
MENU MSGTXT('Java service error has occurred')
ENDIF
ENDROUTINE