データ変更ステートメントの動的実行

データの行を異なる表に入力する場合には、ホスト変数配列を使用してデータ変更ステートメントを動的に実行すると便利です。 また、異なる行数を入力する場合にも有用です。 この処理は、INSERT と MERGE のどちらのステートメントでも同様です。

このタスクについて

例えば、ユーザー提供のアクティビティー ID、アクティビティー・キーワード、およびアクティビティー記述のリストを使用して、複数行 INSERT ステートメントを繰り返し実行する必要があるとします。 次の静的 SQL INSERT ステートメントを使用して、複数行のデータをアクティビティー表に挿入できます。

EXEC SQL
  INSERT INTO DSN8D10.ACT 
    VALUES (:hva_actno, :hva_actkwd, :hva_actdesc)
    FOR :num_rows ROWS;

ただし、データの行をさまざまな表に入力する場合や、異なる行数を入力する場合には、INSERT ステートメントを動的に構成できます。

プロシージャー

データ変更ステートメントを動的に実行するには、次のいずれかの方法を使用します。

  • プログラムで次のアクションを実行して、挿入するデータを含むホスト変数配列を使用します。
    1. 該当する INSERT ステートメントまたは MERGE ステートメントを、ホスト変数に割り当てます。 必要に応じて、CAST仕様を使用して、ホスト変数配列を表すパラメーターマーカーに型を明示的に割り当てます。
      アクティビティー表の場合、準備する INSERT ステートメントを次のストリングに含めます。
      INSERT INTO DSN8D10.ACT 
        VALUES (CAST(? AS SMALLINT), CAST(? AS CHAR(6)), CAST(? AS VARCHAR(20)))
    2. SQL ステートメントの属性をホスト変数に割り当てます。
    3. SQL ステートメントに対する PREPARE ステートメントを組み込みます。
    4. FOR n ROWS 節とともに EXECUTE 文を含めます。
      EXECUTE ステートメントの USING 文節の 各ホスト変数は、SQL ステートメントのターゲットとなる対応列に応じた 値の配列を表します。 行数を変更する際に、SQL ステートメントを再度準備する必要はありません。
    例えば、以下のコードは INSERT ステートメントを準備し、実行します。
    /* Copy the INSERT string into the host variable sqlstmt */
    strcpy(sqlstmt, "INSERT INTO DSN8D10.ACT VALUES (CAST(? AS SMALLINT),");
    strcat(sqlstmt, " CAST(? AS CHAR(6)), CAST(? AS VARCHAR(20)))");
    
    /* Copy the INSERT attributes into the host variable attrvar */
    strcpy(attrvar, "FOR MULTIPLE ROWS");
    
    /* Prepare and execute my_insert using the host-variable arrays */
    EXEC SQL PREPARE my_insert ATTRIBUTES :attrvar FROM :sqlstmt;
    EXEC SQL EXECUTE my_insert USING :hva1, :hva2, :hva3 FOR :num_rows ROWS; 
  • プログラムで次のアクションを実行することにより、記述子を使用してデータを含むホスト変数配列を記述します。
    1. SQLDA構造体で次のフィールドを設定して、INSERTステートメントに挿入する値を含むホスト変数配列に関するデータ型およびその他の情報を指定します。
      • SQLN
      • SQLABC
      • SQLD
      • SQLVAR
      • SQLNAME
      標準の SQLDA 構造宣言、およびその SQLDA 構造を指すプログラム変数の 宣言が、プログラムに組み込まれているとします。 C アプリケーション・プログラムの場合は、次のコード例が SQLDA フィールドを設定します。
      strcpy(sqldaptr->sqldaid,"SQLDA");
      sqldaptr->sqldabc = 192;   /* number of bytes of storage allocated
      for the SQLDA */
      sqldaptr->sqln = 4;                              /* number of SQLVAR
      occurrences */
      sqldaptr->sqld = 4;
      varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]));    /* Point
      to first SQLVAR */
      varptr->sqltype = 500;                                     /* data
      type SMALLINT */
      varptr->sqllen = 2;
      varptr->sqldata = (char *) hva1;
      varptr->sqlname.length = 8;
      memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
      varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]) + 1); /* Point
      to next SQLVAR */
      varptr->sqltype = 452;                                      /* data
      type CHAR(6) */
      varptr->sqllen = 6;
      varptr->sqldata = (char *) hva2;
      varptr->sqlname.length = 8;
      memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
      varptr = (struct sqlvar *) (&(sqldaptr->sqlvar[0]) + 2); /* Point
      to next SQLVAR */
      varptr->sqltype = 448;                                  /* data type
      VARCHAR(20) */
      varptr->sqllen = 20;
      varptr->sqldata = (char *) hva3;
      varptr->sqlname.length = 8;
      memcpy(varptr->sqlname.data, "\x00\x00\x00\x00\x00\x01\x00\x14",varptr->sqlname.length);
      SQLDA 構造には、以下のフィールドがあります。
      • SQLDABC は、SQLDA に割り振るストレージのバイト数を示します。 ストレージには、16 バイトのヘッダーと、 各 SQLVAR フィールドの 44 バイトが含まれます。 値は、この例の場合、SQLN x 44 + 16、または 192 です。
      • SQLNは、SQLVARの出現回数に加えて、FOR n ROWS節に数値 n を含むホスト変数で Db2使用するための1つです。
      • SQLDは、INSERTステートメントを処理するときDb2に使用されるSQLDA内の変数の数です。
      • SQLVARオカレンスは、INSERTのターゲット列に提供された値に対応するホスト変数配列の要素の属性を指定します。 各 SQLVAR 内では、次のようになります。
        • SQLTYPE は、ホスト変数配列のエレメントのデータ型を示します。
        • SQLLENは、ホスト変数配列の単一要素の長さを示します。
        • SQLDATAは、対応するホスト変数配列を指します。 プログラムが、動的変数配列 hva1、hva2、および hva3 を割り振るものとします。
        • SQLNAME には、LENGTH と DATA の 2 つの部分があります。 LENGTH は 8です。 DATA フィールドの最初2 バイトは X'0000'です。 DATA フィールドのバイト 5 と 6 は、変数が配列であるか、または FOR n ROWS 値であるかを示すフラグです。 バイト 7 と 8 は、配列のディメンションを表す 2 バイトの 2 進整数です。
    2. 該当する INSERT ステートメントまたは MERGE ステートメントを、ホスト変数に割り当てます。
      たとえば、次の文字列には、準備されるINSERTステートメントが含まれています。
      INSERT INTO DSN8D10.ACT VALUES (?, ?, ?)
    3. SQL ステートメントの属性をホスト変数に割り当てます。
    4. SQL ステートメントに対する PREPARE ステートメントを組み込みます。
    5. FOR n ROWS 節とともに EXECUTE 文を含めます。 EXECUTE ステートメントの USING 文節のホスト変数には、INSERT ステートメントの パラメーター・マーカーを記述する SQLDA の名前を指定します。
    例えば、以下のコードは INSERT ステートメントを準備し、実行します。
    /* Copy the INSERT string into the host variable sqlstmt */
    strcpy(sqlstmt, "INSERT INTO DSN8D10.ACT VALUES (?, ?, ?)");
    
    /* Copy the INSERT attributes into the host variable attrvar */
    strcpy(attrvar, "FOR MULTIPLE ROWS");
    
    /* Prepare and execute my_insert using the descriptor */
    EXEC SQL PREPARE my_insert ATTRIBUTES :attrvar FROM :sqlstmt;
    EXEC SQL EXECUTE my_insert USING DESCRIPTOR :*sqldaptr FOR :num_rows ROWS;