C 及 C++ 主變數陣列

當您將前置編譯器選項 COMPATIBILITY_MODE 設為 ORA時,您可以針對非動態的 FETCH INTO、INSERT、UPDATE 及 DELETE 陳述式使用 C 及 C++ 主變數陣列。

對於針對 INSERT、UPDATE 或 DELETE 陳述式所宣告的主變數陣列,您必須確保以值起始設定整個陣列元素。 否則,可能會從表格中引進或移除非預期的資料。

當您在 INSERT、UPDATE 或 DELETE 陳述式中為一個資料庫物件指定多個主變數陣列時,必須對那些陣列宣告相同的基數。 否則,會使用在陣列之間宣告的最小基數。

順利處理的總列數儲存在 sqlca.sqlerrd[3] 欄位中。 不過, sqlca.sqlerrd[3] 欄位不代表 INSERT、UPDATE 或 DELETE 作業中順利確定的列數。

受 INSERT、UPDATE 或 DELETE 作業影響的總列數儲存在 sqlca.sqlerrd[2] 欄位中。

在下列範例中,主變數陣列 arr_in1arr_in2 示範如何使用 sqlca.sqlerrd[2]sqlca.sqlerrd[3] 欄位:
// 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.

在 FETCH INTO 陳述式中使用 C 或 C++ 主變數陣列

您可以宣告游標,並對變數陣列執行大量提取,直到到達列的結尾為止。 在相同 FETCH INTO 陳述式中使用的主變數陣列必須具有相同的基數。 否則,會將最小宣告基數用於陣列。

在一個 FETCH INTO 陳述式中,可擷取的記錄數目上限是所宣告陣列的基數。 如果在第一次提取之後有更多列可用,您可以重複 FETCH INTO 陳述式,以取得下一組列。

在下列範例中,會宣告兩個主變數陣列: empnolastname。 每一個最多可以保留 100 個元素。 因為只有一個 FETCH INTO 陳述式,所以此範例會擷取 100 列或更少。
// 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;

在 INSERT 陳述式中使用 C 或 C++ 主變數陣列

在下列範例中,主變數陣列 arr_in1arr_in2 用於 INSERT 陳述式:
// 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

在 UPDATE 陳述式中使用 C 或 C++ 主變數陣列

在下列範例中,主變數陣列 arr_in1arr_in2 用於 UPDATE 陳述式:
// 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

在 DELETE 陳述式中使用 C 或 C++ 主變數陣列

在下列範例中,主變數陣列 arr_in1arr_in2 用於 DELETE 陳述式:
// 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

C 或 C++ 主變數陣列支援的限制

在內嵌式 SQL 應用程式中使用 C 或 C++ 主變數陣列受到下列限制:
  • 連接至 Db2® 伺服器的 C 或 C++ 內嵌式 SQL 應用程式支援主變數陣列。
  • 必須在 DECLARE SECTION 中以陣列元素 (基數) 的確切大小來宣告主變數陣列。
  • 無法在 SQL 陳述式中指定特定的陣列元素。
  • 具有主變數陣列的 INSERT、UPDATE 或 DELETE 作業在資料庫伺服器上作為基本作業執行。 如果任何陣列元素導致 SQL_ERROR ,則會回復現行交易。
  • 動態準備的 INSERT、UPDATE 或 DELETE 陳述式不支援使用主變數陣列。
  • 陣列元素 (基數) 的大小上限為 32672。
  • 不支援下列 C 及 C++ 資料類型與主變數陣列搭配使用:
    • 另一個主變數陣列 (巢狀)
    • BLOB
    • BLOB 檔參照
    • BLOB 定位器變數
    • CLOB
    • CLOB 檔參照
    • CLOB 定位器變數
    • 使用者定義資料類型
    • XML
  • FOR N ROWS 子句可用來指定 INSERT 及 MERGE 陳述式的基數,其中 N 可以是整數或類型 int 或 short 的主變數。 如果使用陣列主變數,則會在 SQL 中使用的所有主變數中取得最小基數值。
  • 未針對 Db2 for z/OS®Db2 for i 伺服器提供主變數陣列支援。