Compound SQL allows multiple statements to be grouped into a executable single block. This block of statements, together with any input parameter values, can then be executed in a single continuous stream, reducing the execution time and network traffic. Compound SQL is most often used to efficiently execute a series of INSERT, UPDATE and DELETE statements.
Any SQL statement that can be prepared dynamically, other than a query, can be executed as a statement inside a compound statement. Statements within a Compound SQL statement are referred to as sub-statements. Compound SQL does not guarantee the order in which the sub-statements are executed, therefore there must be no dependency between the statements.
Compound SQL statements cannot be nested. The authorization ID of the Compound SQL statement must be the appropriate authorization on all the individual sub-statements contained within the Compound SQL statement.
Compound SQL is supported when connected to DB2 Universal Database, or in DRDA environments with DB2 Connect V 2.3 or higher.
A Compound SQL statement block is specified by surrounding the sub-statements by a BEGIN COMPOUND statement and an END COMPOUND statement. The BEGIN COMPOUND syntax is shown below:
>>-BEGIN COMPOUND--+-ATOMIC-----+---STATIC--+----------------------------------+-> '-NOT ATOMIC-' '-STOP AFTER FIRST--?--STATEMENTS--' >--------------------------------------------------------------><
The END COMPOUND syntax is shown below:
>>-END COMPOUND---+--------+----------------------------------->< '-COMMIT-'
Specifying the COMMIT option will commit all the sub-statements if they executed successfully. The COMMIT applies to the current transaction, including statements that precede the compound statement. If COMMIT is specified, and the connection is a coordinated distributed connection (SQL_COORDINATED_TRANS), an error will be returned (SQLSTATE of 25000).
If the COMMIT option is not specified after END COMPOUND, the sub-statements will not be committed unless the application is operating under auto-commit mode, in which case the commit will be issued at the END COMPOUND. For information on the auto-commit mode, refer to Commit or Rollback.
Figure 15 shows the general sequence of function calls required to execute a compound SQL statement. Note that:
If the compound statement is ATOMIC and the END COMPOUND SQLExecDirect() call returns:
Most of the information in the SQLCA reflects values set by the database server when it processed the last sub-statement, such as the SQLCODE and SQLSTATE. If one or more error occurred and none of these are of a serious nature, the SQLERRMC field in the SQLCA will contain information on up to a maximum of seven of these errors.
If the compound statement is NOT ATOMIC and the END COMPOUND SQLExecDirect() call returns:
Note: | Refer to the SQL Reference for details on the contents of an SQLCA after Compound SQL execution. |
The following example executes a compound statement consisting of 4 sub-statements to insert rows into a new AWARDS table.
/* ... */ 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 ) ; }