CLI の手引きおよび解説書

複合 SQL の使用

複合 SQL を利用すると、複数のステートメントを実行可能な 1 つのブロックとしてグループ化することができます。このステートメントのブロックを入力パラメーター値と共に使って、 1 つの連続ストリームで実行することができ、これにより実行時間およびネットワーク通信量を少なくすることができます。複合 SQL は、INSERT、UPDATE、および DELETE ステートメントの集まりを効果的に実行するのに頻繁に使用されます。

動的に作成される SQL ステートメント (照会ステートメントを除く) は、いずれも複合ステートメントの内部にあるステートメントとして実行することができます。複合 SQL ステートメントの中にあるステートメントは、サブステートメントと呼ばれます。複合 SQL は、サブステートメントが実行される順序を保証しないので、ステートメント間に依存性があってはなりません。

複合 SQL ステートメントはネストすることはできません。複合 SQL ステートメントの許可 ID は、複合 SQL ステートメント内に含まれる個々のサブステートメントのすべてについて適切な許可でなければなりません。

複合 SQL がサポートされるのは、DB2 ユニバーサル・データベースに接続する場合、または DB2 コネクト V 2.3 以降の DRDA 環境にある場合です。

ATOMIC および NOT ATOMIC 複合 SQL

複合 SQL ステートメントのブロックを指定する場合は、 BEGIN COMPOUND ステートメントと END COMPOUND ステートメントでサブステートメントを囲みます。 BEGIN COMPOUND 構文を次に示します。

>>-BEGIN COMPOUND--+-ATOMIC-----+---STATIC--+----------------------------------+->
                   '-NOT ATOMIC-'           '-STOP AFTER FIRST--?--STATEMENTS--'
 
>--------------------------------------------------------------><
 

ATOMIC
複合 SQL ステートメント内のいずれかのサブステートメントが失敗した場合、すべてのサブステートメントによってデータベースに加えられたすべての変更がやり直されることを指定します。 ATOMIC は DRDA 環境ではサポートされていません。

NOT ATOMIC
どのサブステートメントが失敗しても、複合 SQL ステートメントは他のサブステートメントによってデータベースに行われた変更をやり直さないことを指定します。

STATIC
すべてのサブステートメントの入力変数が、元の値を保存することを指定します。同じ変数が 2 つ以上のサブステートメントで設定されている場合、複合 SQL ステートメントの後の変数の値は、最後のサブステートメントで設定された値になります。

STOP AFTER FIRST ? STATEMENTS
特定の数のサブステートメントだけを実行するよう指定します。この文節が省略されると、すべてのサブステートメントが実行されます。

END COMPOUND 構文を次に示します。

>>-END COMPOUND---+--------+-----------------------------------><
                  '-COMMIT-'
 

COMMIT オプションを指定すると、すべてのサブステートメントが正常に実行された場合に、それらがコミットされます。 COMMIT は、複合ステートメントの前にあるステートメントも含めて、現行のトランザクションに適用されます。 COMMIT が指定されており、かつ接続が調整分散接続 (SQL_COORDINATED_TRANS) である場合には、エラーが返されます (SQLSTATE 25000)。

END COMPOUND の後に COMMIT オプションを指定しないと、アプリケーションが自動コミット・モードで操作を行っている場合を除いて、サブステートメントはコミットされません。自動コミット・モードで操作されている場合は、END COMPOUND 時にコミットが出されます。自動コミット・モードの詳細については、コミットまたはロールバックを参照してください。

図 15 は、複合 SQL ステートメントを実行する上で必要な関数呼び出しの一般的な順序を示しています。次の点について注意してください。

図 15. 複合 SQL


複合 SQL

複合 SQL のエラー処理

複合ステートメントが ATOMIC で、 END COMPOUND SQLExecDirect() 呼び出しが次のものを返すと、次のようになります。

複合ステートメントが NOT ATOMIC で、 END COMPOUND SQLExecDirect() 呼び出しが次のものを返すと、以下のようになります。

注:複合 SQL 実行後の SQLCA の内容に関する詳細は、SQL 解説書 を参照してください。

複合 SQL の例

次の例では、新規の AWARDS 表に行を挿入するために、 4 つのサブステートメントからなる複合ステートメントを実行します。

/* ... */
    SQLCHAR * stmt[] = {
        "INSERT INTO awards (id, award) "
        "SELECT id, 'Sales Merit' from staff "
        "WHERE job = 'Sales' AND (comm/100 > years)",
        "INSERT INTO awards (id, award) "
        "SELECT id, 'Clerk Merit' from staff "
        "WHERE job = 'Clerk' AND (comm/50 > years)",
        "INSERT INTO awards (id, award) "
        "SELECT id, 'Best ' concat job FROM STAFF "
        "WHERE comm = (SELECT max(comm) FROM staff WHERE job = 'Clerk')",
        "INSERT INTO awards (id, award) "
        "SELECT id, 'Best ' concat job FROM STAFF "
        "WHERE comm = (SELECT max(comm) FROM STAFF WHERE job = 'Sales')",
    } ;
    SQLINTEGER i ;
/* ... */
    /* Prepare 4 substatements */
    for ( i = 1; i < 4; i++ ) {
        rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &cmhstmt[i] ) ;
        CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ;
        rc = SQLPrepare( cmhstmt[i], stmt[i], SQL_NTS ) ;
        CHECK_HANDLE( SQL_HANDLE_STMT, cmhstmt[i], rc ) ;
    }
    rc = SQLExecDirect( hstmt,
                        ( SQLCHAR * ) "BEGIN COMPOUND NOT ATOMIC STATIC",
                        SQL_NTS
                      ) ;
    CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ;
    /* Execute 4 substatements */
    for ( i = 1; i < 4; i++ ) {
        rc = SQLExecute( cmhstmt[i] ) ;
        CHECK_HANDLE( SQL_HANDLE_STMT, cmhstmt[i], rc ) ;
    }
    /* Execute the COMPOUND statement (of 4 sub-statements) */
    printf( "Executing the COMPOUND statement (of 4 sub-statements)\n" ) ;
    rc = SQLExecDirect( hstmt,
                        ( SQLCHAR * ) "END COMPOUND COMMIT",
                        SQL_NTS
                      ) ;
    CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ;
    rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ;
    CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ;
    for ( i = 1; i < 4; i++ ) {
        rc = SQLFreeHandle( SQL_HANDLE_STMT, cmhstmt[i] ) ;
        CHECK_HANDLE( SQL_HANDLE_STMT, cmhstmt[i], rc ) ;
    }
 


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]