Symfoware Server SQLビギナーズガイド - FUJITSU -
目次 索引 前ページ次ページ

第7章 アプリケーションの実行時に動的SQL文を実行する方法> 7.3 SQL文の条件を動的に変更して実行する

7.3.4 変数の属性がわかっている被準備文を実行する

アプリケーションの作成時に、被準備文の動的パラメタ指定の値の属性や個数、または取り出す選択リストの属性や個数がわかっている場合は、SQLDA構造体またはSQL記述子域を使用しなくても、USING引を使用して値の設定や実行結果の取り出しを行うことができます。

USING引数で被準備文の動的パラメタ指定の値を設定する場合は、引数に設定する値を代入しておくことが必要です。このとき、被準備文の動的パラメタ指定の個数と引数の数が一致していることが必要です。また、動的パラメタ指定のデータ型と引数のデータ型が比較可能であることが必要です。NULL値を指定する場合は、標識変数を使用します。

USING引数で被準備文の実行結果を取り出す場合は、実行結果を受け取る引数を指定します。このとき、被準備文の選択リストの個数と引数の数が一致していることが必要です。また、選択リストのデータ型と引数のデータ型が比較可能であることが必要です。なお、比較可能なデータ型については、“表:比較可能なデータ型”を参照してください。

それぞれの指定例を以下に示します。

■EXECUTEで動的パラメタ指定の値を設定する

EXECUTE文にUSING引数を指定し、動的パラメタ指定の値を設定します。

例1

在庫表に製品番号が“400”、製品名が“ビデオテープ”、在庫数量が“500”の行を追加します。このとき、製品番号、製品名、在庫数量のデータ型と、その値を設定する3つの引数のデータ型がそれぞれ比較可能であることが必要です。

■EXECUTE文で実行結果の取り出しを行う

EXECUTE文にUSING引数を指定し、実行結果の取り出しを行います。

例2

在庫表から、製品番号が“110”の製品名、在庫数量を取り出します。このとき、製品名、在庫数量のデータ型と、その結果を取り出す2つの引数のデータ型がそれぞれ比較可能であることが必要です。

■EXECUTE文で動的パラメタ指定の値の設定と実行結果の取り出しを行う

EXECUTE文にUSING引数を指定し、動的パラメタ指定の値の設定と実行結果の取り出しを行います。

例3

在庫表から、製品番号が“240”の製品名、在庫数量を取り出します。このとき、製品番号のデータ型とその値を設定する引数のデータ型、また、製品名、在庫数量のデータ型とそれらの結果を取り出す2つの引数のデータ型がそれぞれ比較可能であることが必要です。

■動的FETCH文で実行結果の取り出しを行う

動的FETCH文にUSING引数を指定し、実行結果の取り出しを行います。

例4

在庫表から、製品番号が“200”より大きい製品名、在庫数量を取り出します。このとき、製品名、在庫数量のデータ型とその結果を取り出す2つの引数のデータ型がそれぞれ比較可能であることが必要です。

■動的OPENで動的パラメタ指定の値を設定し、動的FETCHで実行結果の取り出しを行う

動的OPEN文と動的FETCH文にUSING引数を指定し、動的パラメタ指定の値の設定と実行結果の取り出しを行います。

例5

在庫表から、製品番号が“140”以上かつ“240”以下の製品名を取り出します。このとき、製品番号のデータ型とその値を設定する2つの引数のデータ型、また、製品名のデータ型とその結果を取り出す引数のデータ型がそれぞれ比較可能であることが必要です。

USING引数を使用したアプリケーションの例を以下に示します。

例6

動的パラメタ指定が2つある動的SELECT文の例です。端末から入力した製品番号と在庫数量の値を探索条件としてデータを取り出し、その位置づけられた行に対して、端末から入力した倉庫番号の値に更新します。

[図:USING引数を使用したアプリケーションの例]

 #include <stdio.h>
 #include <string.h>

 EXEC SQL BEGIN DECLARE SECTION;
     char     SQLSTATE[6];
     char     SQLMSG[256];
     VARCHAR  str1[100];
     VARCHAR  str2[100];
     short    indata1;
     long     indata2;
     short    indata3;
     short    outdata;
 EXEC SQL END DECLARE SECTION;

 main()
 {
     memset(SQLSTATE, 0x00, 6);                                             …(1)
     memset(SQLMSG, 0x00, 256);                                             …(1)
     memset(&str1, 0x00, sizeof(str1));                                     …(1)
     memset(&str2, 0x00, sizeof(str2));                                     …(1)

     EXEC SQL CONNECT TO DEFAULT;                                           …(2)
     EXEC SQL DECLARE CU1 CURSOR FOR STM1;
     EXEC SQL WHENEVER SQLERROR GOTO :ERR;
     EXEC SQL WHENEVER NOT FOUND GOTO :NOTFND;

     strcpy( str1.sqlvar, "SELECT 倉庫番号 FROM 在庫管理.在庫表 "           …(3)
                                 "WHERE 製品番号 < ? AND 在庫数量 >= ?" ); 
     str1.sqllen = strlen( str1.sqlvar );
     strcpy( str2.sqlvar, "UPDATE 在庫管理.在庫表 SET 倉庫番号 = ? "        …(4)
                                                  "WHERE CURRENT OF CU1" ); 
     str2.sqllen = strlen( str2.sqlvar );
     EXEC SQL PREPARE STM1 FROM :str1;                                      …(5)
     printf( "製品番号の値を指定してください \n" );
     scanf( "%hd", &indata1 );                                              …(6)
     printf( "在庫数量の値を指定してください \n" );
     scanf( "%ld", &indata2 );                                              …(7)
     EXEC SQL OPEN CU1 USING :indata1, :indata2;                            …(8)
     EXEC SQL PREPARE STM2 FROM :str2;                                      …(9)
     printf( "倉庫番号の値を指定してください \n" );
     scanf( "%hd", &indata3 );                                              …(10)
     for(;;) {
         EXEC SQL FETCH CU1 INTO :outdata;                                  …(11)
         EXEC SQL EXECUTE STM2 USING :indata3;                              …(12)
     }
 NOTFND:
      EXEC SQL CLOSE CU1;                                                   …(13)
      EXEC SQL DEALLOCATE PREPARE STM1;                                     …(14)
      EXEC SQL COMMIT WORK;
      EXEC SQL DISCONNECT DEFAULT;
      return;
 ERR:
      EXEC SQL WHENEVER SQLERROR CONTINUE;
      printf( "SQLERROR  SQLSTATE = %s SQLMSG = %s\n", SQLSTATE, SQLMSG );
      EXEC SQL ROLLBACK WORK;
      EXEC SQL DISCONNECT DEFAULT;
      return;
 }

(1) ホスト変数を初期化します。

(2) カーソルCU1を宣言します。カーソル指定としてSQL文識別子STM1を指定します。

(3) SQL文(動的SELECT文)をSQL文変数str1に格納します。

(4) SQL文(準備可能動的UPDATE文:位置づけ)をSQL文変数str2に格納します。

(5) str1のSQL文を実行できるようにするための準備処理を行います。STM1はSQL文識別子です。

(6) 動的パラメタ指定(製品番号)の値を端末から入力し、ホスト変数indata1に格納します。

(7) 動的パラメタ指定(在庫数量)の値を端末から入力し、ホスト変数indata2に格納します。

(8) (6)、(7)の値を使用して、カーソルCU1をオープンします。

(9) str2のSQL文を実行できるようにするための準備処理を行います。STM2はSQL文識別子です。

(10) 動的パラメタ指定(倉庫番号)の値を端末から入力し、ホスト変数indata3に格納します。

(11) カーソルCU1の位置づけおよびデータの読込みを行います。このとき、ホスト変数outdataに実行結果の値が設定されます。

(12) 動的FETCH文で位置づけられた行に対して、(10)の値で更新処理を行います。

(13) カーソルCU1をクローズします。

(14) SQL文識別子STM1に対応する被準備文(動的SELECT文)を解放します。STM1に対応するカーソルCU1を参照している被準備文(準備可能動的UPDATE文:位置づけ)も同時に解放されます。

備考. 製品番号に“200”、在庫数量に“100”、倉庫番号に“3”が指定された場合は、以下のような結果になります。


目次 索引 前ページ次ページ

All Rights Reserved, Copyright (C) 富士通株式会社 2007