C and C++ host variable arrays
You can use C and C++ host variable arrays for FETCH INTO, INSERT, UPDATE, and DELETE statements that are non-dynamic, when you set the precompiler option COMPATIBILITY_MODE to ORA.
For a host variable array that is declared for an INSERT, UPDATE, or DELETE statement, you must ensure that entire array elements are initialized with a value. Otherwise, unexpected data can get introduced or removed from the table.
When you specify multiple host variable arrays for one database object in an INSERT, UPDATE, or DELETE statement, you must declare the same cardinality for those arrays. Otherwise, the smallest cardinality that is declared among the arrays is used.
The
total number of rows that are successfully processed is stored in
the sqlca.sqlerrd[3]
field. However, the sqlca.sqlerrd[3]
field
does not represent the number of rows that are committed successfully
in the case of INSERT, UPDATE, or DELETE operations.
The total
number of rows that are affected by the INSERT, UPDATE, or DELETE
operation is stored in the sqlca.sqlerrd[2]
field.
sqlca.sqlerrd[2]
and sqlca.sqlerrd[3]
fields:// Declaring host variables with cardinality of 5.
EXEC SQL BEGIN DECLARE SECTION;
sqlint32 arr_in1[5];
char arr_in2[5][11];
EXEC SQL END DECLARE SECTION;
...
// Populating the arrays.
for ( i = 0; i < 5; i++)
{
arr_in1[i] = i + 1;
sprintf(arr_in2[i], "hello%d", i + 1);
}
// A duplicate value is introduced for arr_in1 array.
// arr_in1[0]==arr_in1[4]
arr_in1[4] = 1;
// The C1 column in the table tbl1 requires an unique key
// and doesn’t allow duplicate values.
EXEC SQL INSERT into tbl1 values (:arr_in1, :arr_in2);
printf(“sqlca.sqlcode = %d\n”, sqlca.sqlcode ); // -803
// Since arr_in1[0] and arr_in1[4] have identicle values,
// the INSERT operation fails when arr_in1[4] element is
// processed for the INSERT operation (which is 5th row
// insert attempt).
// The INSERT operation successfully processed 4 rows (not committed).
printf(“sqlca.sqlerrd[3] = %d\n”, sqlca.sqlerrd[3] ); //Prints 4
// The INSERT operation failed and 0 rows are impacted.
printf(“sqlca.sqlerrd[2] = %d\n”, sqlca.sqlerrd[2] ); //Prints 0
// No rows are present in tbl1 as the INSERT operation failed.
// C1 C2
//----------- -----------
// 0 record(s) selected.
Use of C or C++ host variable arrays in FETCH INTO statements
You can declare a cursor and do a bulk fetch into a variable array until the end of the row is reached. Host variable arrays that are used in the same FETCH INTO statement must have same cardinality. Otherwise, the smallest declared cardinality is used for the array.
In one FETCH INTO statement, the maximum number of records that can be retrieved is the cardinality of the array that is declared. If more rows are available after the first fetch, you can repeat the FETCH INTO statement to obtain the next set of rows.
// Declaring host variables
EXEC SQL BEGIN DECLARE SECTION;
char empno[100][8];
char lastname[100][15];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE empcr CURSOR FOR
SELECT empno, lastname FROM employee;
EXEC SQL OPEN empcr;
EXEC SQL WHENEVER NOT FOUND GOTO end_fetch;
while (1) {
EXEC SQL FETCH empcr INTO :empno :lastname; /* bulk fetch */
... /* 100 or less rows */
...
}
end_fetch:
EXEC SQL CLOSE empcr;
Use of C or C++ host variable arrays in INSERT statements
// Declaring host variables.
EXEC SQL BEGIN DECLARE SECTION;
sqlint32 arr_in1[3];
char arr_in2[3][11];
EXEC SQL END DECLARE SECTION;
...
// Populating the arrays.
for ( i = 0; i < 3; i++)
{
arr_in1[i] = 100 + i;
sprintf(arr_in2[i], "hello%d", arr_in1[i]);
}
// The ‘arr_in1’ & ‘arr_in2’ are host variable arrays.
EXEC SQL INSERT into tbl1 values (:arr_in1, :arr_in2);
printf(“sqlca.sqlcode = %d\n”, sqlca.sqlcode ); // 0
// The INSERT operation inserted 3 rows without encounting an error.
printf(“sqlca.sqlerrd[3] = %d\n”, sqlca.sqlerrd[3] ); // 3
// The INSERT operation was successful and 3 rows has been stored in database.
printf(“sqlca.sqlerrd[2] = %d\n”, sqlca.sqlerrd[2] ); // 3
// The tb11 table now contains the following rows:
//C1 C2
//----------- -----------
// 100 hello1
// 101 hello2
// 102 hello3
Use of C or C++ host variable arrays in UPDATE statements
// Declaring host variables
EXEC SQL BEGIN DECLARE SECTION;
sqlint32 arr_in1[3];
sqlint32 arr_in2[2];
EXEC SQL END DECLARE SECTION;
...
// Populating the arrays.
for ( i = 0; i < 3; i++)
{
arr_in1[i] = 100 + i;
}
arr_in2[0] = 1000;
arr_in2[1] = 1001;
// Table tbl2 consists of following rows before an update statement is issued.
//C1 C2
//----------- -----------
// 100 500
// 101 501
// 102 502
// The ‘arr_in1’ array is declared with cardinality of 3 for use in the
// SET clause of an UPDATE statement.
// The 'arr_in2' array is declared with cardinality of 2 for use in the
// WHERE clause of an UPDATE statement.
// The tbl2 table contains 3 rows.
// The following UPDATE statement will affect only 2 rows as per arr_in2
// for column c2 and remaining need to be untouched.
// The ‘arr_in1’ array in the following update statement is treated as
// having cardinality of 2.
EXEC SQL UPDATE tbl2 SET c2 = :arr_in2 + c2 where c1 = :arr_in1;
printf(“sqlca.sqlcode = %d\n”, sqlca.sqlcode ); // 0
// As there is no error in update statement, sqlca.sqlerrd[3]
// contains rows which are updated successfully.
printf(“sqlca.sqlerrd[3] = %d\n”, sqlca.sqlerrd[3] ); // 2
// update successful and 2 rows has been updated in database.
printf(“sqlca.sqlerrd[2] = %d\n”, sqlca.sqlerrd[2] ); // 2
// The tb12 table now contains the following rows:
//C1 C2
//----------- -----------
// 100 1500
// 101 1502
// 102 503
Use of C or C++ host variable arrays in DELETE statements
// Declaring host variables
EXEC SQL BEGIN DECLARE SECTION;
sqlint32 arr_in1[3];
EXEC SQL END DECLARE SECTION;
...
// Populating the arrays.
for ( i = 0; i < 3; i++)
{
arr_in1[i] = 101 + i;
}
// Initial data in the tbl2 table:
// C1 C2
// ----------- -----------
// 100 500
// 101 501
// 102 502
// 103 503
// 104 504
// using array host while executing delete statement in where clause
// The‘arr_in1’ host variable array is used in the WHERE clause of
// an DELETE statement.
EXEC SQL DELETE FROM tbl2 where c1 = :arr_in1;
printf(“sqlca.sqlcode = %d\n”, sqlca.sqlcode ); // 0
// delete successful attempted rows are 3
printf(“sqlca.sqlerrd[3] = %d\n”, sqlca.sqlerrd[3] ); // 3
// delete successful and 3 rows has been deleted in database.
printf(“sqlca.sqlerrd[2] = %d\n”, sqlca.sqlerrd[2] ); // 3
// The tb12 table now contains the following rows:
// C1 C2
// ----------- -----------
// 100 500
// 104 504
Restrictions with C or C++ host variable array support
- Host variables arrays are supported by C or C++ embedded SQL applications that connect to Db2® servers.
- Host variable arrays must be declared in the
DECLARE SECTION
with exact size of the array elements (cardinality). - Specific array element cannot be specified in a SQL statement.
- The INSERT, UPDATE, or DELETE operation with host variable arrays is run as an atomic operation on the database server. If any array element causes an SQL_ERROR, current transaction is rolled back.
- Use of host variable arrays are not supported by dynamically prepared INSERT, UPDATE, or DELETE statements.
- Maximum size of array element (cardinality) is 32672.
- The following C and C++ data types are not supported for use with
host variable arrays:
- Another host variable array (nesting)
- BLOB
- BLOB file reference
- BLOB locator variable
- CLOB
- CLOB file reference
- CLOB locator variable
- User-defined data type
- XML
- FOR N ROWS clause can be used to specify the cardinality for INSERT and MERGE statement, where N can be an integer or a host variable of type int or short. If array host variables are used, it will take the minimum cardinality value among all the host variables that are used in the SQL.
- Host variable array support is not provided for Db2 for z/OS® and Db2 for i servers.