Memperbarui Baris di Set Baris dengan SQLSetPos

Operasi pembaruan SQLSetPos membuat pembaruan sumber data satu atau beberapa baris tabel yang dipilih, menggunakan data dalam buffer aplikasi untuk setiap kolom terikat (kecuali nilai dalam buffer panjang/indikator SQL_COLUMN_IGNORE). Kolom yang tidak terikat tidak akan diperbarui.

Untuk memperbarui baris dengan SQLSetPos, aplikasi melakukan hal berikut:

  1. Tempatkan nilai data baru di buffer set baris. Untuk informasi tentang cara mengirim data panjang dengan SQLSetPos, lihat Data Panjang dan SQLSetPos dan SQLBulkOperations.

  2. Mengatur nilai dalam buffer panjang/indikator setiap kolom seperlunya. Ini adalah panjang byte data atau SQL_NTS untuk kolom yang terikat ke buffer string, panjang byte data untuk kolom yang terikat ke buffer biner, dan SQL_NULL_DATA untuk kolom apa pun yang akan diatur ke NULL.

  3. Mengatur nilai dalam buffer panjang/indikator kolom tersebut yang tidak akan diperbarui ke SQL_COLUMN_IGNORE. Meskipun aplikasi dapat melewati langkah ini dan mengirim ulang data yang ada, ini tidak efisien dan berisiko mengirim nilai ke sumber data yang terpotong saat dibaca.

  4. Memanggil SQLSetPos dengan Operasi diatur ke SQL_UPDATE dan RowNumber diatur ke jumlah baris yang akan diperbarui. Jika RowNumber adalah 0, semua baris dalam set baris diperbarui.

Setelah SQLSetPos kembali, baris saat ini diatur ke baris yang diperbarui.

Saat memperbarui semua baris himpunan baris (RowNumber sama dengan 0), aplikasi dapat menonaktifkan pembaruan baris tertentu dengan mengatur elemen yang sesuai dari array operasi baris (ditunjukkan oleh atribut pernyataan SQL_ATTR_ROW_OPERATION_PTR) ke SQL_ROW_IGNORE. Array operasi baris sesuai dalam ukuran dan jumlah elemen ke array status baris (ditunjukkan oleh atribut pernyataan SQL_ATTR_ROW_STATUS_PTR). Untuk memperbarui hanya baris tersebut dalam kumpulan hasil yang berhasil diambil dan belum dihapus dari set baris, aplikasi menggunakan array status baris dari fungsi yang mengambil set baris sebagai array operasi baris ke SQLSetPos.

Untuk setiap baris yang dikirim ke sumber data sebagai pembaruan, buffer aplikasi harus memiliki data baris yang valid. Jika buffer aplikasi diisi dengan mengambil dan jika array status baris telah dipertahankan, nilainya di masing-masing posisi baris ini tidak boleh SQL_ROW_DELETED, SQL_ROW_ERROR, atau SQL_ROW_NOROW.

Misalnya, kode berikut memungkinkan pengguna untuk menggulir tabel Pelanggan dan memperbarui, menghapus, atau menambahkan baris baru. Ini menempatkan data baru di buffer set baris sebelum memanggil SQLSetPos untuk memperbarui atau menambahkan baris baru. Baris tambahan dialokasikan di akhir buffer set baris untuk menahan baris baru; ini mencegah data yang ada ditimpa ketika data untuk baris baru ditempatkan di buffer.

#define UPDATE_ROW   100  
#define DELETE_ROW   101  
#define ADD_ROW      102  
  
SQLUINTEGER    CustIDArray[11];  
SQLCHAR        NameArray[11][51], AddressArray[11][51],   
               PhoneArray[11][11];  
SQLINTEGER     CustIDIndArray[11], NameLenOrIndArray[11],   
               AddressLenOrIndArray[11],  
               PhoneLenOrIndArray[11];  
SQLUSMALLINT   RowStatusArray[10], Action, RowNum;  
SQLRETURN      rc;  
SQLHSTMT       hstmt;  
  
// Set the SQL_ATTR_ROW_BIND_TYPE statement attribute to use column-wise   
// binding. Declare the rowset size with the SQL_ATTR_ROW_ARRAY_SIZE   
// statement attribute. Set the SQL_ATTR_ROW_STATUS_PTR statement   
// attribute to point to the row status array.  
SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_KEYSET_DRIVEN, 0);  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, 10, 0);  
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);  
  
// Bind arrays to the CustID, Name, Address, and Phone columns.  
SQLBindCol(hstmt, 1, SQL_C_ULONG, CustIDArray, 0, CustIDIndArray);  
SQLBindCol(hstmt, 2, SQL_C_CHAR, NameArray, sizeof(NameArray[0]), NameLenOrIndArray);  
SQLBindCol(hstmt, 3, SQL_C_CHAR, AddressArray, sizeof(AddressArray[0]),  
            AddressLenOrIndArray);  
SQLBindCol(hstmt, 4, SQL_C_CHAR, PhoneArray, sizeof(PhoneArray[0]),  
            PhoneLenOrIndArray);  
  
// Execute a statement to retrieve rows from the Customers table.  
SQLExecDirect(hstmt, "SELECT CustID, Name, Address, Phone FROM Customers", SQL_NTS);  
  
// Fetch and display the first 10 rows.  
rc = SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0);  
DisplayData(CustIDArray, CustIDIndArray, NameArray, NameLenOrIndArray, AddressArray,  
            AddressLenOrIndArray, PhoneArray, PhoneLenOrIndArray, RowStatusArray);  
  
// Call GetAction to get an action and a row number from the user.  
while (GetAction(&Action, &RowNum)) {  
   switch (Action) {  
  
      case SQL_FETCH_NEXT:  
      case SQL_FETCH_PRIOR:  
      case SQL_FETCH_FIRST:  
      case SQL_FETCH_LAST:  
      case SQL_FETCH_ABSOLUTE:  
      case SQL_FETCH_RELATIVE:  
         // Fetch and display the requested data.  
         SQLFetchScroll(hstmt, Action, RowNum);  
         DisplayData(CustIDArray, CustIDIndArray,  
                     NameArray, NameLenOrIndArray,  
                     AddressArray, AddressLenOrIndArray,  
                     PhoneArray, PhoneLenOrIndArray, RowStatusArray);  
         break;  
  
      case UPDATE_ROW:  
         // Place the new data in the rowset buffers and update the   
         // specified row.  
         GetNewData(&CustIDArray[RowNum - 1], &CustIDIndArray[RowNum - 1],  
                  NameArray[RowNum - 1], &NameLenOrIndArray[RowNum - 1],  
                  AddressArray[RowNum - 1], &AddressLenOrIndArray[RowNum - 1],  
                  PhoneArray[RowNum - 1], &PhoneLenOrIndArray[RowNum - 1]);  
         SQLSetPos(hstmt, RowNum, SQL_UPDATE, SQL_LOCK_NO_CHANGE);  
         break;  
  
      case DELETE_ROW:  
         // Delete the specified row.  
         SQLSetPos(hstmt, RowNum, SQL_DELETE, SQL_LOCK_NO_CHANGE);  
         break;  
  
      case ADD_ROW:  
         // Place the new data in the rowset buffers at index 10.   
         // This is an extra element for new rows so rowset data is   
         // not overwritten. Insert the new row. Row 11 corresponds   
         // to index 10.  
         GetNewData(&CustIDArray[10], &CustIDIndArray[10],  
                     NameArray[10], &NameLenOrIndArray[10],  
                     AddressArray[10], &AddressLenOrIndArray[10],  
                     PhoneArray[10], &PhoneLenOrIndArray[10]);  
         SQLSetPos(hstmt, 11, SQL_ADD, SQL_LOCK_NO_CHANGE);  
         break;  
   }  
}  
  
// Close the cursor.  
SQLCloseCursor(hstmt);