Mengikat Array Parameter
Aplikasi yang menggunakan array parameter mengikat array ke parameter dalam pernyataan SQL. Ada dua gaya pengikatan:
Ikat array ke setiap parameter. Setiap struktur data (array) berisi semua data untuk satu parameter. Ini disebut pengikatan kolom bijaksana karena mengikat kolom nilai untuk satu parameter.
Tentukan struktur untuk menyimpan data parameter untuk seluruh set parameter dan mengikat array struktur ini. Setiap struktur data berisi data untuk satu pernyataan SQL. Ini disebut pengikatan row-wise karena mengikat baris parameter.
Seperti ketika aplikasi mengikat variabel tunggal ke parameter, aplikasi memanggil SQLBindParameter untuk mengikat array ke parameter. Satu-satunya perbedaan adalah bahwa alamat yang diteruskan adalah alamat array, bukan alamat variabel tunggal. Aplikasi mengatur atribut pernyataan SQL_ATTR_PARAM_BIND_TYPE untuk menentukan apakah menggunakan pengikatan bijaksana kolom (default) atau baris. Apakah menggunakan pengikatan bijaksana kolom atau baris sebagian besar merupakan masalah preferensi aplikasi. Tergantung pada bagaimana prosesor mengakses memori, pengikatan baris mungkin lebih cepat. Namun, perbedaannya kemungkinan dapat diabaikan kecuali untuk sejumlah besar baris parameter.
Pengikatan Bijak Kolom
Saat menggunakan pengikatan kolom yang bijaksana, aplikasi mengikat satu atau dua array ke setiap parameter yang datanya akan disediakan. Array pertama menyimpan nilai data, dan array kedua memegang buffer panjang/indikator. Setiap array berisi elemen sebanyak ada nilai untuk parameter .
Pengikatan kolom yang bijaksana adalah default. Aplikasi ini juga dapat berubah dari pengikatan baris menjadi pengikatan bijaksana kolom dengan mengatur atribut pernyataan SQL_ATTR_PARAM_BIND_TYPE. Ilustrasi berikut menunjukkan cara kerja pengikatan kolom yang bijaksana.
Misalnya, kode berikut mengikat array 10 elemen ke parameter untuk kolom PartID, Deskripsi, dan Harga, dan menjalankan pernyataan untuk menyisipkan 10 baris. Ini menggunakan pengikatan kolom bijaksana.
#define DESC_LEN 51
#define ARRAY_SIZE 10
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description, Price) "
"VALUES (?, ?, ?)";
SQLUINTEGER PartIDArray[ARRAY_SIZE];
SQLCHAR DescArray[ARRAY_SIZE][DESC_LEN];
SQLREAL PriceArray[ARRAY_SIZE];
SQLINTEGER PartIDIndArray[ARRAY_SIZE], DescLenOrIndArray[ARRAY_SIZE],
PriceIndArray[ARRAY_SIZE];
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLULEN ParamsProcessed;
memset(DescLenOrIndArray, 0, sizeof(DescLenOrIndArray));
memset(PartIDIndArray, 0, sizeof(PartIDIndArray));
memset(PriceIndArray, 0, sizeof(PriceIndArray));
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use
// column-wise binding.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
// Specify the number of elements in each parameter array.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
// Specify an array in which to return the status of each set of
// parameters.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
// Specify an SQLUINTEGER value in which to return the number of sets of
// parameters processed.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
// Bind the parameters in column-wise fashion.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
PartIDArray, 0, PartIDIndArray);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
DescArray, DESC_LEN, DescLenOrIndArray);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
PriceArray, 0, PriceIndArray);
// Set part ID, description, and price.
for (i = 0; i < ARRAY_SIZE; i++) {
GetNewValues(&PartIDArray[i], DescArray[i], &PriceArray[i]);
PartIDIndArray[i] = 0;
DescLenOrIndArray[i] = SQL_NTS;
PriceIndArray[i] = 0;
}
// Execute the statement.
SQLExecDirect(hstmt, Statement, SQL_NTS);
// Check to see which sets of parameters were processed successfully.
for (i = 0; i < ParamsProcessed; i++) {
printf("Parameter Set Status\n");
printf("------------- -------------\n");
switch (ParamStatusArray[i]) {
case SQL_PARAM_SUCCESS:
case SQL_PARAM_SUCCESS_WITH_INFO:
printf("%13d Success\n", i);
break;
case SQL_PARAM_ERROR:
printf("%13d Error\n", i);
break;
case SQL_PARAM_UNUSED:
printf("%13d Not processed\n", i);
break;
case SQL_PARAM_DIAG_UNAVAILABLE:
printf("%13d Unknown\n", i);
break;
}
}
Pengikatan Bijak Baris
Saat menggunakan pengikatan baris bijaksana, aplikasi menentukan struktur untuk setiap set parameter. Struktur berisi satu atau dua elemen untuk setiap parameter. Elemen pertama menyimpan nilai parameter, dan elemen kedua memegang buffer panjang/indikator. Aplikasi kemudian mengalokasikan array struktur ini, yang berisi elemen sebanyak ada nilai untuk setiap parameter.
Aplikasi mendeklarasikan ukuran struktur ke driver dengan atribut pernyataan SQL_ATTR_PARAM_BIND_TYPE. Aplikasi mengikat alamat parameter dalam struktur pertama array. Dengan demikian, driver dapat menghitung alamat data untuk baris dan kolom tertentu sebagai
Address = Bound Address + ((Row Number - 1) * Structure Size) + Offset
di mana baris diberi nomor dari 1 hingga ukuran set parameter. Offset, jika ditentukan, adalah nilai yang ditujukkan oleh atribut pernyataan SQL_ATTR_PARAM_BIND_OFFSET_PTR. Ilustrasi berikut menunjukkan cara kerja pengikatan baris-bijaksana. Parameter dapat ditempatkan dalam struktur dalam urutan apa pun tetapi ditampilkan dalam urutan berurutan untuk kejelasan.
Kode berikut membuat struktur dengan elemen agar nilai disimpan di kolom PartID, Deskripsi, dan Harga. Kemudian mengalokasikan array 10 elemen dari struktur ini dan mengikatnya ke parameter untuk kolom PartID, Deskripsi, dan Harga, menggunakan pengikatan baris yang bijaksana. Kemudian menjalankan pernyataan untuk menyisipkan 10 baris.
#define DESC_LEN 51
#define ARRAY_SIZE 10
typedef tagPartStruct {
SQLREAL Price;
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLINTEGER PriceInd;
SQLINTEGER PartIDInd;
SQLINTEGER DescLenOrInd;
} PartStruct;
PartStruct PartArray[ARRAY_SIZE];
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description,
Price) "
"VALUES (?, ?, ?)";
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLULEN ParamsProcessed;
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use
// column-wise binding.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, sizeof(PartStruct), 0);
// Specify the number of elements in each parameter array.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
// Specify an array in which to return the status of each set of
// parameters.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
// Specify an SQLUINTEGER value in which to return the number of sets of
// parameters processed.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
// Bind the parameters in row-wise fashion.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&PartArray[0].PartID, 0, &PartArray[0].PartIDInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
PartArray[0].Desc, DESC_LEN, &PartArray[0].DescLenOrInd);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&PartArray[0].Price, 0, &PartArray[0].PriceInd);
// Set part ID, description, and price.
for (i = 0; i < ARRAY_SIZE; i++) {
GetNewValues(&PartArray[i].PartID, PartArray[i].Desc, &PartArray[i].Price);
PartArray[0].PartIDInd = 0;
PartArray[0].DescLenOrInd = SQL_NTS;
PartArray[0].PriceInd = 0;
}
// Execute the statement.
SQLExecDirect(hstmt, Statement, SQL_NTS);
// Check to see which sets of parameters were processed successfully.
for (i = 0; i < ParamsProcessed; i++) {
printf("Parameter Set Status\n");
printf("------------- -------------\n");
switch (ParamStatusArray[i]) {
case SQL_PARAM_SUCCESS:
case SQL_PARAM_SUCCESS_WITH_INFO:
printf("%13d Success\n", i);
break;
case SQL_PARAM_ERROR:
printf("%13d Error\n", i);
break;
case SQL_PARAM_UNUSED:
printf("%13d Not processed\n", i);
break;
case SQL_PARAM_DIAG_UNAVAILABLE:
printf("%13d Unknown\n", i);
break;
}