複合文で1つ以上のSQL文を繰り返し実行できます。「FOR文」、「REPEAT文」および「WHILE文」も参照してください。
LOOP制御文は、次の環境の複合文内でのみ使用できます。
- 対話型SQL内
- プリコンパイル対象のホスト言語プログラムに埋め込まれる場合
- SQLモジュールのプロシージャの一部として
- 動的SQLで動的に実行される文として
beginning-label:
制御ループに名前を割り当てます。LEAVE文とともに開始ラベルを使用することにより、ループの終了を制御できます。名前付きループはラベル付きループ文と呼ばれます。終了ラベルを含める場合、その終了ラベルは対応する開始ラベルと同じである必要があります。開始ラベルは、そのラベルが含まれているプロシージャ内で一意である必要があります。compound-use-statement
複合文ブロックで許可されたSQL文を識別します。有効な文のリストは、「複合文」を参照してください。END LOOP ending-label
制御ループの終了をマークします。オプションの終了ラベルを含める場合、その終了ラベルは対応する開始ラベルと正確に一致している必要があります。終了ラベルは、そのラベルが含まれているプロシージャ内で一意である必要があります。オプションのend-label引数により、特に非常に複雑な複数文プロシージャ・ブロックの場合に、複数文プロシージャが読みやすくなります。
LOOP
制御ループの開始をマークします。LOOP文を使用すると、複合文と呼ばれる関連付けられた一連のSQL文を実行できます。SQLでループ内の文の実行が完了すると、次の文を実行するために制御はループの先頭にあるLOOP文に返されます。SQLでエラー例外が発生するか、LEAVE文が実行されるまでループは続行されます。どちらの場合も、SQLは、LOOPブロックからそのLOOP文の直後の文に制御を渡します。
終了条件が含まれている場合を除き、LOOPは無制限に繰り返されます。
例1: ループ文の実行
SQL> create table ENROLLMENTS cont> (last_name char(20), cont> first_name char(10), cont> middle_initial char, cont> class_name char(10)); SQL> SQL> begin cont> declare :n integer default 5; cont> loop cont> insert into ENROLLMENTS cont> values ('Jones', 'Robert', 'A', cont> 'Class ' || CAST(:n as char(1))); cont> set :n = :n - 1; cont> if :n <= 0 then cont> leave; cont> end if; cont> end loop; cont> end; SQL> SQL> select * from ENROLLMENTS; LAST_NAME FIRST_NAME MIDDLE_INITIAL CLASS_NAME Jones Robert A Class 5 Jones Robert A Class 4 Jones Robert A Class 3 Jones Robert A Class 2 Jones Robert A Class 1 5 rows selected SQL>
カーソルをオープンして、カーソルの結果表の行をFETCH文で取得できるようにします。OPEN文は、カーソルの結果表の最初の行の前にカーソルを配置します。
OPEN文は次の環境で使用できます。
- 対話型SQL内
- プリコンパイル対象のホスト言語プログラムに埋め込まれる場合
- SQLモジュールのプロシージャの一部として
cursor-name
parameter
オープンするカーソルの名前を指定します。このカーソル名で参照されるカーソルが動的DECLARE CURSOR文によって実行時に宣言されている場合は、パラメータを使用します。拡張動的DECLARE CURSOR文のカーソル名に使用されたパラメータを指定します。OPEN文が拡張動的カーソルを参照している場合のみ、パラメータを使用してカーソル名を参照できます。
USING parameter
USING qualified-parameter
USING DESCRIPTOR descriptor-name
動的SQLパラメータ(プリコンパイルされたOPEN文のホスト言語変数またはSQLモジュール言語プロシージャの一部であるOPEN文の仮パラメータ)または修飾パラメータ(構造体)で指定します。この修飾パラメータの値は、カーソル宣言で指定されている準備されたSELECT文のパラメータ・マーカーを置き換えるためにSQLで使用されます。これらのパラメータは、対話型SQLでは使用されません。SQLは、カーソルのSELECT文の評価時にパラメータ・マーカーをホスト言語変数の値に置き換えます。SQLモジュール言語およびSQLプリコンパイラの詳細は、第3章と第4章をそれぞれ参照してください。次の両方の条件を満たしているときはUSING句を指定する必要があります。
- オープンするカーソルの宣言で、準備されたSELECT文の名前が指定されている場合。
- 準備されたSELECT文の文字列にパラメータ・マーカーが含まれている場合。
準備されたSELECT文に基づいていないカーソルでは、OPEN文でUSING句を使用できません。パラメータ・マーカーの詳細は、「PREPARE文」、および『Oracle Rdb7 Guide to SQL Programming』の動的SQLに関する章を参照してください。
USING句のパラメータの指定には、次の2つの方法があります。
- パラメータのリストを使用します。リストのパラメータの数は、準備されたSELECT文のパラメータ・マーカーの数と同じである必要があります。(OPEN文のパラメータのいずれかがホスト構造体である場合、SQLは、USING句のパラメータの数と準備されたSELECT文のパラメータ・マーカーの数を比較するときに、このホスト構造体の変数の数をカウントします。)
- SQLDAに対応している記述子の名前を使用します。記述子の名前をUSING DESCRIPTOR句で指定します。INCLUDE文を使用してプログラムにSQLDAを挿入する場合、記述子名にはそのままSQLDAが使用されます。
SQLDAは、動的SQLでのみ使用される変数のコレクションです。OPEN文では、SQLDAは、準備されたSELECT文のパラメータ・マーカーを置き換えるホスト言語変数の数を指し示します。変数の数は、パラメータ・マーカーの数と一致している必要があります。
ホスト言語変数のデータ型は、カーソルの行の対応する列の値と互換性を持つ必要があります。
- SQLでは、一度にオープンできるカーソルの数に制限がありません。複数のカーソルを同時に宣言およびオープンできます。
- オープンしている表カーソルは、次のように配置されます。
- カーソルの結果表の行の前。SQLでOPEN文が実行されると、最初の行の前にカーソルが配置されます。カーソルを参照しているDELETE文が実行されると、削除された行の直後の行の前にカーソルが配置されます。
- カーソルの結果表の行(最後の行を除くいずれかの行に対するFETCH文の実行後)。
- カーソルの結果表の最後の行の後。カーソルが最後の行に配置されると、そのカーソルのFETCH文またはDELETE文が最後の行の後にカーソルを配置します。
- カーソルは、DECLARE CURSOR文で宣言されるまでオープンできません。
- すでにオープンしているカーソルに対してOPEN文を発行すると、エラー・メッセージが生成されます。OPEN文はこのカーソルに影響を与えません。
- SQLは、カーソルのOPEN文の実行時にDECLARE CURSOR文の選択式のパラメータを評価します。パラメータの再評価は、カーソルをクローズして再度オープンするまで実行されません。
- オープンしているリスト・カーソルは、次のように配置されます。
- リストの要素の前。SQLでOPEN文が実行されると、最初の要素の前にカーソルが配置されます。
- リストの要素(最後の要素を除くいずれかの要素に対するFETCH文の実行後)。
- カーソルの結果表の最後の要素の後。カーソルが最後の要素に配置されると、そのカーソルのFETCH文が最後の要素の後にカーソルを配置します。
- リスト・カーソルをオープンするときは、その行コンテキストを提供する表カーソルがオープンして、行に配置されている必要があります。
例1: PL/Iプログラムで宣言されたカーソルのオープン
このプログラムの一部では埋め込まれたDECLARE CURSOR文、OPEN文およびFETCH文が使用され、マネージャの名前と部門が取得および出力されます。OPEN文は、フェッチされる行の先頭にカーソルを配置します。
/* Declare the cursor: */ EXEC SQL DECLARE MANAGER CURSOR FOR SELECT E.FIRST_NAME, E.LAST_NAME, D.DEPARTMENT_NAME FROM EMPLOYEES E, DEPARTMENTS D WHERE E.EMPLOYEE_ID = D.MANAGER_ID ; /* Open the cursor: */ EXEC SQL OPEN MANAGER; /* Start a loop to process the rows of the cursor: */ DO WHILE (SQLCODE = 0); /* Retrieve the rows of the cursor and put the value in host language variables: */ EXEC SQL FETCH MANAGER INTO :FNAME, :LNAME, :DNAME; /* Print the values in the variables: */ . . . END; /* Close the cursor: */ EXEC SQL CLOSE MANAGER;
例2: リスト・データの挿入に使用するカーソルのオープン
次の対話型SQLの例では、カーソルを使用して、サンプルの人事データベースのRESUMES表に新規行を追加します。
SQL> DECLARE TBLCURSOR INSERT ONLY TABLE CURSOR FOR cont> SELECT EMPLOYEE_ID, RESUME FROM RESUMES; SQL> DECLARE LSTCURSOR INSERT ONLY LIST CURSOR FOR cont> SELECT RESUME WHERE CURRENT OF TBLCURSOR; SQL> OPEN TBLCURSOR; SQL> INSERT INTO CURSOR TBLCURSOR (EMPLOYEE_ID) cont> VALUES ("00167"); 1 row inserted SQL> OPEN LSTCURSOR; SQL> INSERT INTO CURSOR LSTCURSOR cont> VALUES ("This is the resume for 00167"); SQL> INSERT INTO CURSOR LSTCURSOR cont> VALUES ("Boston, MA"); SQL> INSERT INTO CURSOR LSTCURSOR cont> VALUES ("Oracle Corporation"); SQL> CLOSE LSTCURSOR; SQL> CLOSE TBLCURSOR; SQL> COMMIT;
SQL内からオペレーティング・システムのコマンドライン環境へのアクセスを可能にします。ドル記号($)は、サブプロセスを生成して、行の残りの部分を処理するためにオペレーティング・システムに渡すようにSQLに伝えます。ドル記号の後にオペレーティング・システム・コマンドを続ける必要があります。コマンドの処理を完了すると、オペレーティング・システムはサブプロセスのプロセスからログアウトしてSQLに制御を返します。
オペレーティング・システム・コマンドは、対話型SQLでのみ起動できます。
operating-system-command
有効なオペレーティング・システム・コマンドを指定します。
- SQLは、オペレーティング・システム・コマンドを実行するためにサブプロセスを生成するため、ドル記号のコマンドを使用して現在の対話型セッションに影響する論理名を作成できません。たとえば、ドル記号のコマンドを使用してSQL$DATABASE論理の値を変更できません。
- 対話型SQLは、ドル記号($)で始まるコマンドラインをオペレーティング・システム・コマンドラインの開始点と解釈します。ドル記号が前の行の文字列リテラルの続きでも同様に解釈されるため、混乱を招く結果が生じる可能性があります。
SQL> INSERT INTO EMPLOYEES (CITY) VALUES("DollarSign - cont> $City") %DCL-W-IVVERB, unrecognized command verb - check validity and spelling \CITY");\ cont> ; %SQL-F-UNTSTR, Unterminated string found SQL>
例1: SQL内からのDCL DIRECTORYコマンドの使用
SQL> $ DIRECTORY *.SQL Directory DISK2:[DEPT3.ACCT] DEFPRO.SQL;6 NOTEQUAL.SQL;1 QUERY.SQL;1 REFEXAM.SQL;12 STORE.SQL;1 UPDATE.SQL;2 Total of 6 files. SQL>
プログラムによって動的に生成されるSQL文を実行に向けて準備し、その文に名前を割り当てます。動的SQLでは、SQLモジュール言語プロシージャとは対照的に、プログラムは実行時にSQL文を受け入れたり生成できます。プリコンパイルされたSQLまたはSQLモジュール言語文とは異なり、動的に実行されるこのようなSQL文は、必ずしもプログラムのソース・コードの一部ではありませんが、プログラムの実行中に生成できます。動的SQLは、プログラムが処理する必要のあるSQL文のタイプを予測できない場合に便利です。
PREPARE...INTO文は、準備された文の選択リスト項目の数とデータ型をSQLDAに格納します。SQLDAでは、動的SQL文の情報をプログラムに、そのプログラムによって割り当てられたメモリーの情報をSQLに提供します。
付録Dには、SQLDAの特定のフィールドの詳細と、プログラムがSQLDAを使用して、準備された文の選択リスト項目と通信する方法の詳細が記載されています。
PREPARE文は次の環境で使用できます。
- プリコンパイル対象のホスト言語プログラムに埋め込まれる場合
- SQLモジュールのプロシージャの一部として
descriptor-name
SQLが選択リスト項目の情報を書き込むSQLDAとして、ホスト・プログラムで宣言された構造体の名前を指定します。プリコンパイルされたプログラムは、埋込みSQL文のINCLUDE SQLDAを使用して、プログラムのプリコンパイル時に、SQLDAと呼ばれるSQLDA構造体の宣言をプログラムに自動的に挿入できます。SQLモジュール言語を使用するプログラムは、SQLDAを明示的に宣言する必要があります。プリコンパイルされたプログラムまたはSQLモジュール言語プログラムは、追加のSQLDAを明示的に宣言できますが、SQLDAはそれぞれ一意の名前で宣言する必要があります。SQLDA構造体のサンプル宣言は、付録D.3節を参照してください。FROM statement-string
FROMパラメータ
動的実行のために準備されるSQL文を指定します。文の文字列を一重引用符で囲んで直接指定するか、または文の文字列を含むパラメータ(プリコンパイルされたPREPARE文のホスト言語変数またはSQLモジュール言語プロシージャの一部であるPREPARE文の仮パラメータ)で指定します。直接指定、パラメータによる指定のいずれの場合も、文の文字列は動的に実行SQL文である文字列である必要があります。(動的に実行可能なSQL文のリストは、「使用方法」を参照してください。)文の文字列を直接指定する場合、最大長は1024文字です。文の文字列をパラメータで指定する場合、文の文字列の最大長は65535文字です。
文の形式は、次の点を除き埋込みSQL文と同じです。
- 文字列はEXEC SQLで開始できません。
- SQLが埋込み文のホスト言語変数を許可している場所では、かわりにパラメータ・マーカーを指定する必要があります。
無効な文を準備しようとすると、SQLCODEの値、SQLCAのSQLCODEフィールドの値またはSQLSTATEのステータス・パラメータの値がエラーを示します。
SQLCODEフィールドに返される値の詳細は、付録Cを参照してください。返されたエラー・メッセージを確認するには、メッセージ・ベクターをチェックしてください。必要な場合は、エラー・メッセージの説明とデフォルト設定のユーザー処理をSQL HELP ERRORSで参照します。
パラメータ・マーカーとは疑問符(?)であり、PREPARE文の文字列にあるパラメータを表します。準備された文がEXECUTE文またはOPEN文によって実行されると、パラメータ・マーカーはパラメータの値または動的メモリーの値に置き換えられます。
SELECT LIST INTO
文の文字列の選択リスト項目の数およびデータ型の情報をSQLがSQLDAに書き込むように指定します。オプションのSELECT LISTキーワードは、INTO句の効果を明確にします。PREPARE文でSELECT LIST句を使用すると、個別のDESCRIBE...INPUT文を発行できます。詳細は、「DESCRIBE文」を参照してください。
PREPARE文のSELECT LIST句は廃止予定の構文です。廃止予定の構文の詳細は、付録Fを参照してください。
注意
PREPARE文のLISTキーワードは、LISTデータ型またはリスト・カーソルに関連付けられていません。
statement-name
statement-id-parameter
FROM句で指定されたSQL文の準備されたバージョンを識別します。準備されたSQL文のタイプによっては、DESCRIBE文、EXECUTE文および動的DECLARE CURSOR文は、PREPARE文で割り当てられた文の名前を参照できます。パラメータまたはコンパイル時の文名を指定できます。パラメータを指定すると、SQLは実行時にプログラムの識別子を設定します。SQLが返した文識別子を含むには、整数パラメータを使用します。SQLに渡す文の名前を含むには、文字列パラメータを使用します。
1セットの動的SQL文(PREPARE、DESCRIBE、EXECUTE、拡張動的DECLARE CURSOR)によって、任意の数の動的に実行される文を処理できます。パラメータを使用する場合は、準備された文を参照する文(DESCRIBE、EXECUTE、拡張動的DECLARE CURSOR)でも、明示的な文の名前のかわりにパラメータを使用する必要があります。
動的DECLARE CURSOR文で使用されるPREPARE文を示す例は、「DECLARE CURSOR文、動的」を参照してください。
- PREPARE文は、SQLCAの値を設定して、文の入力パラメータと出力パラメータの数をレポートします。これらの値によって、入力および出力のSQLDA構造体にメモリーを割り当てることができます。
SQLERRD配列がゼロ・ベースであると仮定すると、SQLはSQLERRD[2]に出力パラメータの数を設定し、SQLERRD[3]に入力パラメータの数を設定します。値はゼロにできます。その場合は、INOUT型のCALLパラメータが入力と出力の両方の数に表示されます。
Oracle Rdbリリース7.1.3より前はSQLCAが設定されていなかったため、PREPAREコールの前に、SQLERRD[2]の値およびSQLERRD[3]の値を既知の値(-1など)に設定することをお薦めします。値を-1のままにすると、この数自体がアプリケーションで推定されます。- INSERT、DELETEなどの一部の文は、SQLCAのSQLERRD[2]フィールドの(文の操作対象である)行の数を返します。この動作を利用するには、ステータス・パラメータとしてSQLCAを使用して文を準備する必要があります。SQLERRD[2]フィールドの詳細は、付録Cを参照してください。
- 同一の準備された文を何度でも実行できます。ただし、動的に実行する文が選択リスト項目またはパラメータ・マーカーを含まず、プログラムで文を1回のみ実行する必要がある場合は、EXECUTE IMMEDIATE文を使用すると、1つのステップで文を準備して実行できます。
- PREPARE文のPREPARE...SELECT LIST形式では、実行のための文の準備に加えて、選択リスト項目の数およびデータ型の情報がSQLDAに格納されます。ただし、PREPARE文の形式はDESCRIBE...INPUT文に対応していません。パラメータ・マーカーの情報をSQLDAに格納するには、DESCRIBE...INPUT文を使用する必要があります。
SQLDAを使用するには、ホスト言語がポインタ変数をサポートする必要があります。ポインタ変数では、変数に直接データを格納するのではなくデータのアドレスを格納して記憶域に間接的にアクセスします。ポインタ変数もサポートするSQLプリコンパイラによってサポートされる言語は、Ada、C、およびPL/Iです。ポインタ変数をサポートする他の言語はSQLDAを使用できますが、ソース・コードに直接SQL文を埋め込むのではなく、SQL文を含むSQLモジュール・プロシージャをコールする必要があります。- statement-id-parameterを使用すると、次の動作のいずれかが発生します。
- 文IDがゼロ以外で、一致する準備された文がない場合(IDが古いか、IDにランダム値が含まれる場合)は、次のエラーが発生します。
%SQL-F-BADPREPARE, Cannot use DESCRIBE or EXECUTE on a statement that is not prepared
- 文IDがゼロ以外か、または文名が以前に使用されたものであり、既存の準備された文と一致する場合、その文は新しい文が準備される前に自動的に解放されます。詳細は、「RELEASE文」を参照してください。
- 文IDがゼロであるか、または自動的に解放された場合、新しい文IDの割当ておよび文の準備が行われます。
statement-id-parameterのかわりにstatement-nameを使用すると、SQLはアプリケーションで使用するIDを暗黙的に宣言します。したがって、記述したセマンティクスはstatement-nameの使用時にも同様に適用されます。詳細は、「RELEASE文」を参照してください。- 事前に準備された文に対してEXECUTE文を発行するとき、SQLCODEステータス・パラメータで返される成功コードまたは失敗コード以外の情報取得を必要とする場合があります。たとえば、DELETE文またはUPDATE文の実行によって影響を受けた行の数を知る必要がある場合があります。SQLCAステータス・パラメータを使用すると、このタイプの情報にアクセスできます。
ただし、準備された文の実行時にSQLCAパラメータを使用する場合、その文を準備したときにSQLCAパラメータを最初に使用している必要があります。たとえば、CによるSQLモジュール言語のコールを使用すると、コードが次のようになる場合があります。ここで、SQLCAパラメータは両方のプロシージャに渡されます。
static struct SQLCA sqlca; /* ... */ PREPARE_STMT(&sqlca, statement, &stmt_id); /* ... */ EXECUTE_STMT(&sqlca, &stmt_id);
- プリコンパイルされたプログラムへの埋込みが可能な文や、SQLモジュール言語プロシージャに含まれる文の中には動的に実行できないものもあります。動的に実行できない文を次に示します。
- CLOSE
- DECLARE CURSOR
- DECLARE STATEMENT
- DECLARE TABLE
- DESCRIBE
- EXECUTE
- FETCH
- INCLUDE
- OPEN
- PREPARE
- RELEASE
- WHENEVER
表6-11に、動的に実行可能なSQL文を示します。この表は、処理を必要とする場合があるパラメータ・マーカーまたは選択リスト項目を文で使用可能かどうか、および文を動的に処理するために使用される、関連付けられた動的でないSQL文を示します。
表6-11 動的に実行可能なSQL文 動的に実行可能な文 パラメータ・マーカーの使用 選択リスト項目の使用 関連付けられた動的SQL文 SELECT(一般形式) ○ ○ PREPARE
動的DECLARE CURSOR
拡張動的DECLARE CURSOR
DESCRIBE (オプション)
OPEN
FETCH
CLOSE
RELEASE(オプション)DELETE文
INSERT文
UPDATE文
SET文○ × PREPARE
DESCRIBE(オプション)
EXECUTE
EXECUTE IMMEDIATE(パラメータ・マーカーがない場合)
RELEASE(オプション)複合文
SELECT ... INTO
INSERT ... RETURNING INTO
UPDATE ... RETURNING INTO○ ○ PREPARE
DESCRIBE(オプション)
EXECUTE
EXECUTE IMMEDIATE(パラメータ・マーカーがない場合)
RELEASE(オプション)ALTER
ATTACH
DECLARE TRANSACTION
CREATE
COMMENT ON
COMMIT
DROP
GRANT
RENAME
REVOKE
ROLLBACK
SET TRANSACTION
START TRANSACTION
TRUNCATE× × PREPARE
EXECUTE
EXECUTE IMMEDIATE
RELEASE(オプション)
例1: パラメータ・マーカーを持つINSERT文の準備
このPL/Iプログラムは、動的実行するINSERT文を準備するためにPREPARE文を使用する方法を示しています。COMMAND_STRINGに格納されている文の文字列はパラメータ・マーカーを持つため、プログラムは、動的実行中にパラメータ・マーカーの代替となるホスト言語変数の値を割り当てる必要があります。
この場合、DESCRIBE文はパラメータ・マーカーの情報をSQLDAに書き込み、プログラムは変数のアドレスをSQLDAに書き込みます。プログラムは変数に値を格納し、EXECUTE文は、SQLDAのアドレスを使用してINSERT文のパラメータ・マーカーを変数の値に置き換えます。
例を短くするために、このプログラムは次のように簡略化されています。
- プログラムは、ソース・コードの一部としてINSERT文を含んでいます。このようなコーディングされたSQL文を含むプログラムでは、動的SQLの使用をまったく必要とせず、INSERT文をプログラムに直接そのまま埋め込むことができます。実行時に生成されるSQL文の処理を必要とするプログラムは、動的SQLを要求するタイプのプログラムのみです。
- プログラムは、パラメータ・マーカーに対するホスト言語変数を宣言します。その際、SQLDAのホスト言語変数の記述を最初にチェックしません。通常、アプリケーションは、パラメータ・マーカーにメモリーを割り当てる前に、SQLDAを調べて文の文字列のパラメータ・マーカーの数およびデータ型を確認する必要があります。
PREP_INTO: procedure options(main); /* * Illustrate a dynamic INSERT statement * with parameter markers: */ declare FILESPEC char(20), EMP_ID CHAR(5), FNAME CHAR(10), LNAME CHAR(14), CITY CHAR(20), COMMAND_STRING char(256); /* Declare communication area (SQLCA) * and descriptor area (SQLDA): */ EXEC SQL INCLUDE SQLDA; EXEC SQL INCLUDE SQLCA; /* Declare the database: */ EXEC SQL DECLARE SCHEMA RUNTIME FILENAME :FILESPEC; /* * * procedure division * */ /* * Assign values to FILESPEC and COMMAND_STRING, * and allocate memory for the SQLDA: */ FILESPEC = 'SQL$DATABASE'; COMMAND_STRING = 'INSERT INTO EMPLOYEES (EMPLOYEE_ID, FIRST_NAME, LAST_NAME, CITY) VALUES (?,?,?,?)'; SQLSIZE = 10; ALLOCATE SQLDA SET (SQLDAPTR); SQLN = 10; /* * Prepare the statement assigned to COMMAND_STRING: */ EXEC SQL PREPARE STMT3 FROM COMMAND_STRING; /* Use a DESCRIBE statement to write information * about the parameter markers in the statement string * to the SQLDA: */ EXEC SQL DESCRIBE STMT3 MARKERS INTO SQLDA; /* Assign values to the variables: */ EMP_ID = '99999'; FNAME = 'Bob'; LNAME = 'Addams'; CITY = 'Francestown'; /* * Assign the addresses of the variables to the SQLDATA field * of the SQLDA: */ SQLDATA(1) = ADDR(EMP_ID); SQLDATA(2) = ADDR(FNAME); SQLDATA(3) = ADDR(LNAME); SQLDATA(4) = ADDR(CITY); /* Execute STMT3:*/ EXEC SQL EXECUTE STMT3 USING DESCRIPTOR SQLDA; /* * Display the contents of table S to make sure * it has the proper contents and clean it up: */ CALL DUMP_S; EXEC SQL DELETE FROM EMPLOYEES WHERE EMPLOYEE_ID = "99999"; EXEC SQL COMMIT WORK; RETURN; DUMP_S: PROC; EXEC SQL DECLARE X CURSOR FOR SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, CITY FROM EMPLOYEES WHERE EMPLOYEE_ID = "99999"; /* * Declare a structure to hold values of rows from the table: */ DCL 1 S, 2 EMP_ID CHAR(5), 2 FNAME CHAR(10), 2 LNAME CHAR(14), 2 CITY CHAR(20); /* Declare indicator vector for the preceding structure: */ DCL S_IND (4) FIXED(15) BIN; PUT EDIT ('Dump the contents of S') (SKIP, SKIP, A); EXEC SQL OPEN X; EXEC SQL FETCH X INTO :S:S_IND; DO WHILE (SQLCODE = 0); PUT EDIT (S_IND(1), ' ', S.EMP_ID, ' ') (SKIP, F(6), A, A, A); PUT EDIT (S_IND(2), ' ', S.FNAME, ' ') (F(6), A, A, A); PUT EDIT (S_IND(3), ' ', S.LNAME, ' ') (F(6), A, A, A); PUT EDIT (S_IND(4), ' ', S.CITY) (F(6), A, A); EXEC SQL FETCH X INTO :S:S_IND; END; EXEC SQL CLOSE X; RETURN; END DUMP_S; END PREP_INTO;