Mengikat Array Parameter

Aplikasi yang menggunakan array parameter mengikat array ke parameter dalam pernyataan SQL. Ada dua gaya pengikatan:

  • Mengikat 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 menetapkan atribut pernyataan SQL_ATTR_PARAM_BIND_TYPE untuk menentukan apakah menggunakan pengikatan kolom bijaksana (default) atau baris. Apakah menggunakan pengikatan bijaksana kolom atau baris sebagian besar merupakan masalah preferensi aplikasi. Tergantung pada bagaimana prosesor mengakses memori, pengikatan row-wise mungkin lebih cepat. Namun, perbedaannya kemungkinan dapat diabaikan kecuali untuk sejumlah besar baris parameter.

Pengikatan Bijak Kolom

Saat menggunakan pengikatan kolom 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 bijaksana adalah default. Aplikasi ini juga dapat berubah dari pengikatan row-wise ke pengikatan kolom-bijaksana dengan mengatur atribut pernyataan SQL_ATTR_PARAM_BIND_TYPE. Ilustrasi berikut menunjukkan cara kerja pengikatan kolom bijaksana.

Memperlihatkan cara kerja pengikatan kolom

Misalnya, kode berikut mengikat array 10 elemen ke parameter untuk kolom PartID, Description, dan Price, 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 row-wise, 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 row-wise. Parameter dapat ditempatkan dalam struktur dalam urutan apa pun tetapi ditampilkan dalam urutan berurutan untuk kejelasan.

Memperlihatkan cara kerja pengikatan row-wise

Kode berikut membuat struktur dengan elemen untuk nilai yang akan disimpan di kolom PartID, Description, dan Price. Kemudian mengalokasikan array 10 elemen dari struktur ini dan mengikatnya ke parameter untuk kolom PartID, Description, dan Price, menggunakan pengikatan row-wise. 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;  
  
   }