Fungsi SQLBulkOperations

Kesesuaian
Versi Diperkenalkan: Kepatuhan Standar ODBC 3.0: ODBC

Ringkasan
SQLBulkOperations melakukan penyisipan massal dan operasi bookmark massal, termasuk memperbarui, menghapus, dan mengambil berdasarkan marka buku.

Sintaks

  
SQLRETURN SQLBulkOperations(  
     SQLHSTMT       StatementHandle,  
     SQLUSMALLINT   Operation);  

Argumen

StatementHandle
[Input] Handel pernyataan.

Operasi
[Input] Operasi yang akan dilakukan:

SQL_ADD SQL_UPDATE_BY_BOOKMARK SQL_DELETE_BY_BOOKMARK SQL_FETCH_BY_BOOKMARK

Untuk informasi selengkapnya, lihat "Komentar."

Kembali

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, atau SQL_INVALID_HANDLE.

Diagnostik

Ketika SQLBulkOperations mengembalikan SQL_ERROR atau SQL_SUCCESS_WITH_INFO, nilai SQLSTATE terkait dapat diperoleh dengan memanggil SQLGetDiagRec dengan HandleType SQL_HANDLE_STMT dan Handle of StatementHandle. Tabel berikut mencantumkan nilai SQLSTATE yang biasanya dikembalikan oleh SQLBulkOperations dan menjelaskan masing-masing dalam konteks fungsi ini; notasi "(DM)" mendahului deskripsi SQLSTATEs yang dikembalikan oleh Driver Manager. Kode pengembalian yang terkait dengan setiap nilai SQLSTATE SQL_ERROR, kecuali disebutkan sebaliknya.

Untuk semua SQLSTATEs yang dapat mengembalikan SQL_SUCCESS_WITH_INFO atau SQL_ERROR (kecuali 01xxxx SQLSTATEs), SQL_SUCCESS_WITH_INFO dikembalikan jika kesalahan terjadi pada satu atau beberapa, tetapi tidak semua, baris operasi multirow, dan SQL_ERROR dikembalikan jika kesalahan terjadi pada operasi satu baris.

SQLSTATE Kesalahan Deskripsi
01000 Peringatan umum Pesan informasi khusus driver. (Fungsi mengembalikan SQL_SUCCESS_WITH_INFO.)
01004 Pemotongan kanan data string Argumen Operasi SQL_FETCH_BY_BOOKMARK, dan string atau data biner dikembalikan untuk kolom atau kolom dengan jenis data SQL_C_CHAR atau SQL_C_BINARY menghasilkan pemotongan karakter tidak kosong atau data biner non-NULL.
01S01 Kesalahan berturut-turut Argumen Operasi SQL_ADD, dan terjadi kesalahan dalam satu atau beberapa baris saat melakukan operasi tetapi setidaknya satu baris berhasil ditambahkan. (Fungsi mengembalikan SQL_SUCCESS_WITH_INFO.)

(Kesalahan ini dimunculkan hanya ketika aplikasi bekerja dengan ODBC 2.x driver.)
01S07 Pemotongan pecahan Argumen Operasi SQL_FETCH_BY_BOOKMARK, jenis data buffer aplikasi tidak SQL_C_CHAR atau SQL_C_BINARY, dan data yang dikembalikan ke buffer aplikasi untuk satu atau beberapa kolom terpotong. (Untuk jenis data C numerik, bagian pecahan dari angka dipotong. Untuk jenis data waktu, tanda waktu, dan interval C yang berisi komponen waktu, bagian pecahan waktu dipotong.)

(Fungsi mengembalikan SQL_SUCCESS_WITH_INFO.)
07006 Pelanggaran atribut jenis data terbatas Argumen Operasi SQL_FETCH_BY_BOOKMARK, dan nilai data kolom dalam tataan hasil tidak dapat dikonversi ke jenis data yang ditentukan oleh argumen TargetType dalam panggilan ke SQLBindCol.

Argumen Operasi SQL_UPDATE_BY_BOOKMARK atau SQL_ADD, dan nilai data dalam buffer aplikasi tidak dapat dikonversi ke jenis data kolom dalam tataan hasil.
07009 Indeks deskriptor tidak valid Argumen Operasi SQL_ADD, dan kolom terikat dengan jumlah kolom yang lebih besar dari jumlah kolom dalam tataan hasil.
21S02 Tingkat tabel turunan tidak cocok dengan daftar kolom Operasi argumen SQL_UPDATE_BY_BOOKMARK; dan tidak ada kolom yang dapat diperbarui karena semua kolom tidak terikat atau baca-saja, atau nilai dalam buffer panjang/indikator terikat SQL_COLUMN_IGNORE.
22001 Pemotongan kanan data string Penetapan karakter atau nilai biner ke kolom dalam tataan hasil menghasilkan pemotongan karakter atau byte nonblank (untuk karakter) atau non-null (untuk biner).
22003 Nilai numerik di luar rentang Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK, dan penetapan nilai numerik ke kolom dalam kumpulan hasil menyebabkan seluruh (dibandingkan dengan pecahan) bagian dari angka yang akan dipotong.

Argumen Operasi SQL_FETCH_BY_BOOKMARK, dan mengembalikan nilai numerik untuk satu atau beberapa kolom terikat akan menyebabkan hilangnya digit signifikan.
22007 Format tanggalwaktu tidak valid Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK, dan penetapan nilai tanggal atau tanda waktu ke kolom dalam kumpulan hasil menyebabkan bidang tahun, bulan, atau hari berada di luar rentang.

Argumen Operasi SQL_FETCH_BY_BOOKMARK, dan mengembalikan nilai tanggal atau tanda waktu untuk satu atau beberapa kolom terikat akan menyebabkan bidang tahun, bulan, atau hari berada di luar rentang.
22008 Bidang tanggal/waktu meluap Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK, dan performa aritmatika tanggalwaktu pada data yang dikirim ke kolom dalam kumpulan hasil menghasilkan bidang tanggalwaktu (bidang tahun, bulan, hari, jam, menit, atau bidang kedua) dari hasil yang berada di luar rentang nilai yang diizinkan untuk bidang atau tidak valid berdasarkan aturan alami kalender Gregorian untuk tanggalwaktu.

Argumen Operasi SQL_FETCH_BY_BOOKMARK, dan performa aritmatika tanggalwaktu pada data yang diambil dari kumpulan hasil menghasilkan bidang tanggalwaktu (bidang tahun, bulan, hari, jam, menit, atau kedua) dari hasil yang berada di luar rentang nilai yang diizinkan untuk bidang atau tidak valid berdasarkan aturan alami kalender Gregorian untuk tanggalwaktu.
22015 Meluapnya bidang interval Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK, dan penetapan jenis C numerik atau interval yang tepat ke jenis data SQL interval menyebabkan hilangnya digit signifikan.

Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK; saat menetapkan ke jenis SQL interval, tidak ada representasi nilai jenis C dalam jenis SQL interval.

Argumen Operasi SQL_FETCH_BY_BOOKMARK, dan menetapkan dari jenis SQL numerik atau interval yang tepat ke jenis C interval menyebabkan hilangnya digit signifikan di bidang depan.

Argumen Operasi SQL_FETCH_BY_BOOKMARK; saat menetapkan ke tipe C interval, tidak ada representasi nilai jenis SQL dalam jenis C interval.
22018 Nilai karakter tidak valid untuk spesifikasi cast Argumen Operasi SQL_FETCH_BY_BOOKMARK; jenis C tepat atau perkiraan numerik, tanggalwaktu, atau tipe data interval; jenis SQL kolom adalah tipe data karakter; dan nilai dalam kolom bukan harfiah yang valid dari jenis C terikat.

Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK; jenis SQL adalah angka yang tepat atau perkiraan, tanggalwaktu, atau tipe data interval; jenis C SQL_C_CHAR; dan nilai dalam kolom bukan harfiah yang valid dari jenis SQL terikat.
23000 Pelanggaran batasan integritas Argumen Operasi SQL_ADD, SQL_DELETE_BY_BOOKMARK, atau SQL_UPDATE_BY_BOOKMARK, dan batasan integritas dilanggar.

Argumen Operasi SQL_ADD, dan kolom yang tidak terikat didefinisikan sebagai NOT NULL dan tidak memiliki default.

Argumen Operasi SQL_ADD, panjang yang ditentukan dalam buffer StrLen_or_IndPtr terikat SQL_COLUMN_IGNORE, dan kolom tidak memiliki nilai default.
24000 Status kursor tidak valid StatementHandle berada dalam status dijalankan, tetapi tidak ada kumpulan hasil yang dikaitkan dengan StatementHandle.
40001 Kegagalan serialisasi Transaksi digulung balik karena kebuntuan sumber daya dengan transaksi lain.
40003 Penyelesaian pernyataan tidak diketahui Koneksi terkait gagal selama eksekusi fungsi ini, dan status transaksi tidak dapat ditentukan.
42000 Kesalahan sintaks atau pelanggaran akses Driver tidak dapat mengunci baris sesuai kebutuhan untuk melakukan operasi yang diminta dalam argumen Operasi .
44000 DENGAN PELANGGARAN OPSI PEMERIKSAAN Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK, dan penyisipan atau pembaruan dilakukan pada tabel yang dilihat (atau tabel yang berasal dari tabel yang dilihat) yang dibuat dengan menentukan WITH CHECK OPTION, sed sehingga satu atau beberapa baris yang terpengaruh oleh sisipan atau pembaruan tidak akan ada lagi dalam tabel yang dilihat.
HY000 Kesalahan umum Terjadi kesalahan yang tidak ada SQLSTATE tertentu dan tidak ada SQLSTATE khusus implementasi yang ditentukan. Pesan kesalahan yang dikembalikan oleh SQLGetDiagRec di buffer *MessageText menjelaskan kesalahan dan penyebabnya.
HY001 Kesalahan alokasi memori Driver tidak dapat mengalokasikan memori yang diperlukan untuk mendukung eksekusi atau penyelesaian fungsi.
HY008 Operasi dibatalkan Pemrosesan asinkron diaktifkan untuk StatementHandle. Fungsi ini dipanggil, dan sebelum selesai dieksekusi, SQLCancel atau SQLCancelHandle dipanggil pada StatementHandle. Kemudian fungsi dipanggil lagi pada StatementHandle.

Fungsi ini dipanggil, dan sebelum selesai dieksekusi, SQLCancel atau SQLCancelHandle dipanggil pada StatementHandle dari utas yang berbeda dalam aplikasi multithread.
HY010 Kesalahan urutan fungsi (DM) Fungsi eksekusi asinkron dipanggil untuk handel koneksi yang terkait dengan StatementHandle. Fungsi asinkron ini masih dijalankan ketika fungsi SQLBulkOperations dipanggil.

(DM) SQLExecute, SQLExecDirect, atau SQLMoreResults dipanggil untuk StatementHandle dan dikembalikan SQL_PARAM_DATA_AVAILABLE. Fungsi ini dipanggil sebelum data diambil untuk semua parameter yang dialirkan.

(DM) StatementHandle yang ditentukan tidak dalam status dijalankan. Fungsi ini dipanggil tanpa terlebih dahulu memanggil fungsi SQLExecDirect, SQLExecute, atau katalog.

(DM) Fungsi eksekusi asinkron (bukan yang ini) dipanggil untuk StatementHandle dan masih dijalankan ketika fungsi ini dipanggil.

(DM) SQLExecute, SQLExecDirect, atau SQLSetPos dipanggil untuk StatementHandle dan dikembalikan SQL_NEED_DATA. Fungsi ini dipanggil sebelum data dikirim untuk semua parameter atau kolom data-at-execution.

(DM) Drivernya adalah ODBC 2.driver x , dan SQLBulkOperations dipanggil untuk StatementHandle sebelum SQLFetchScroll atau SQLFetch dipanggil.

(DM) SQLBulkOperations dipanggil setelah SQLExtendedFetch dipanggil pada StatementHandle.
HY011 Atribut tidak dapat diatur sekarang (DM) Drivernya adalah ODBC 2.driver x , dan atribut pernyataan SQL_ATTR_ROW_STATUS_PTR diatur antara panggilan ke SQLFetch atau SQLFetchScroll dan SQLBulkOperations.
HY013 Kesalahan manajemen memori Panggilan fungsi tidak dapat diproses karena objek memori yang mendasar tidak dapat diakses, mungkin karena kondisi memori yang rendah.
HY090 String atau panjang buffer tidak valid Argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK; nilai data bukan penunjuk null; tipe data C SQL_C_BINARY atau SQL_C_CHAR; dan nilai panjang kolom kurang dari 0, tetapi tidak sama dengan SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS, atau SQL_NULL_DATA, atau kurang dari atau sama dengan SQL_LEN_DATA_AT_EXEC_OFFSET.

Nilai dalam buffer panjang/indikator SQL_DATA_AT_EXEC; jenis SQL SQL_LONGVARCHAR, SQL_LONGVARBINARY, atau jenis data khusus sumber data yang panjang; dan jenis informasi SQL_NEED_LONG_DATA_LEN di SQLGetInfo adalah "Y".

Argumen Operasi SQL_ADD, atribut pernyataan SQL_ATTR_USE_BOOKMARK diatur ke SQL_UB_VARIABLE, dan kolom 0 terikat ke buffer yang panjangnya tidak sama dengan panjang maksimum untuk bookmark untuk tataan hasil ini. (Panjang ini tersedia di bidang SQL_DESC_OCTET_LENGTH IRD dan dapat diperoleh dengan memanggil SQLDescribeCol, SQLColAttribute, atau SQLGetDescField.)
HY092 Pengidentifikasi atribut tidak valid (DM) Nilai yang ditentukan untuk argumen Operasi tidak valid.

Argumen Operasi SQL_ADD, SQL_UPDATE_BY_BOOKMARK, atau SQL_DELETE_BY_BOOKMARK, dan atribut pernyataan SQL_ATTR_CONCURRENCY diatur ke SQL_CONCUR_READ_ONLY.

Argumen Operasi SQL_DELETE_BY_BOOKMARK, SQL_FETCH_BY_BOOKMARK, atau SQL_UPDATE_BY_BOOKMARK, dan kolom bookmark tidak terikat atau atribut pernyataan SQL_ATTR_USE_BOOKMARKS diatur ke SQL_UB_OFF.
HY117 Koneksi ditangguhkan karena status transaksi yang tidak diketahui. Hanya fungsi putuskan sambungan dan baca-saja yang diizinkan. (DM) Untuk informasi selengkapnya tentang status ditangguhkan, lihat Fungsi SQLEndTran.
HYC00 Fitur opsional tidak diimplementasikan Driver atau sumber data tidak mendukung operasi yang diminta dalam argumen Operasi .
HYT00 Waktu habis kedaluwarsa Periode batas waktu kueri kedaluwarsa sebelum sumber data mengembalikan tataan hasil. Periode batas waktu diatur melalui SQLSetStmtAttr dengan argumen Atribut SQL_ATTR_QUERY_TIMEOUT.
HYT01 Kesalahan waktu habis koneksi kedaluwarsa Periode batas waktu koneksi kedaluwarsa sebelum sumber data merespons permintaan. Periode batas waktu koneksi diatur melalui SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Driver tidak mendukung fungsi ini (DM) Driver yang terkait dengan StatementHandle tidak mendukung fungsi.
IM017 Polling dinonaktifkan dalam mode pemberitahuan asinkron Setiap kali model pemberitahuan digunakan, polling dinonaktifkan.
IM018 SQLCompleteAsync belum dipanggil untuk menyelesaikan operasi asinkron sebelumnya pada handel ini. Jika panggilan fungsi sebelumnya pada handel mengembalikan SQL_STILL_EXECUTING dan jika mode pemberitahuan diaktifkan, SQLCompleteAsync harus dipanggil pada handel untuk melakukan pasca-pemrosesan dan menyelesaikan operasi.

Komentar

Perhatian

Untuk informasi tentang pernyataan apa yang menyatakan SQLBulkOperations dapat dipanggil dan apa yang harus dilakukan untuk kompatibilitas dengan ODBC 2.aplikasi x , lihat bagian Kursor Blok, Kursor yang Dapat Digulir, dan Kompatibilitas Mundur di Lampiran G: Panduan Driver untuk Kompatibilitas Mundur.

Aplikasi menggunakan SQLBulkOperations untuk melakukan operasi berikut pada tabel dasar atau tampilan yang sesuai dengan kueri saat ini:

  • Tambahkan baris baru.

  • Perbarui sekumpulan baris di mana setiap baris diidentifikasi oleh marka buku.

  • Hapus sekumpulan baris di mana setiap baris diidentifikasi oleh marka buku.

  • Ambil sekumpulan baris di mana setiap baris diidentifikasi oleh marka buku.

Setelah panggilan ke SQLBulkOperations, posisi kursor blok tidak terdefinisi. Aplikasi harus memanggil SQLFetchScroll untuk mengatur posisi kursor. Aplikasi harus memanggil SQLFetchScroll hanya dengan argumen FetchOrientation SQL_FETCH_FIRST, SQL_FETCH_LAST, SQL_FETCH_ABSOLUTE, atau SQL_FETCH_BOOKMARK. Posisi kursor tidak terdefinisi jika aplikasi memanggil SQLFetch atau SQLFetchScroll dengan argumen FetchOrientation SQL_FETCH_PRIOR, SQL_FETCH_NEXT, atau SQL_FETCH_RELATIVE.

Kolom dapat diabaikan dalam operasi massal yang dilakukan oleh panggilan ke SQLBulkOperations dengan mengatur buffer panjang kolom/indikator yang ditentukan dalam panggilan ke SQLBindCol, ke SQL_COLUMN_IGNORE.

Aplikasi tidak perlu mengatur atribut pernyataan SQL_ATTR_ROW_OPERATION_PTR saat memanggil SQLBulkOperations karena baris tidak dapat diabaikan saat melakukan operasi massal dengan fungsi ini.

Buffer yang ditunjukkan oleh atribut pernyataan SQL_ATTR_ROWS_FETCHED_PTR berisi jumlah baris yang terpengaruh oleh panggilan ke SQLBulkOperations.

Ketika argumen Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK dan daftar pilih spesifikasi kueri yang terkait dengan kursor berisi lebih dari satu referensi ke kolom yang sama, itu ditentukan driver apakah kesalahan dihasilkan atau driver mengabaikan referensi duplikat dan melakukan operasi yang diminta.

Untuk informasi selengkapnya tentang cara menggunakan SQLBulkOperations, lihat Memperbarui Data dengan SQLBulkOperations.

Melakukan Penyisipan Massal

Untuk menyisipkan data dengan SQLBulkOperations, aplikasi melakukan urutan langkah-langkah berikut:

  1. Menjalankan kueri yang mengembalikan tataan hasil.

  2. Mengatur atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE ke jumlah baris yang ingin disisipkan.

  3. Memanggil SQLBindCol untuk mengikat data yang ingin disisipkan. Data terikat ke array dengan ukuran yang sama dengan nilai SQL_ATTR_ROW_ARRAY_SIZE.

    Catatan

    Ukuran array yang ditujukkan oleh atribut pernyataan SQL_ATTR_ROW_STATUS_PTR harus sama dengan SQL_ATTR_ROW_ARRAY_SIZE atau SQL_ATTR_ROW_STATUS_PTR harus berupa pointer null.

  4. Memanggil SQLBulkOperations(StatementHandle, SQL_ADD) untuk melakukan penyisipan.

  5. Jika aplikasi telah mengatur atribut pernyataan SQL_ATTR_ROW_STATUS_PTR, aplikasi dapat memeriksa array ini untuk melihat hasil operasi.

Jika aplikasi mengikat kolom 0 sebelum memanggil SQLBulkOperations dengan argumen Operasi SQL_ADD, driver akan memperbarui buffer kolom terikat 0 dengan nilai bookmark untuk baris yang baru disisipkan. Agar hal ini terjadi, aplikasi harus mengatur atribut pernyataan SQL_ATTR_USE_BOOKMARKS ke SQL_UB_VARIABLE sebelum menjalankan pernyataan. (Ini tidak berfungsi dengan ODBC 2.x driver.)

Data panjang dapat ditambahkan di bagian oleh SQLBulkOperations, dengan menggunakan panggilan ke SQLParamData dan SQLPutData. Untuk informasi selengkapnya, lihat "Menyediakan Data Panjang untuk Sisipan dan Pembaruan Massal" nanti dalam referensi fungsi ini.

Aplikasi tidak perlu memanggil SQLFetch atau SQLFetchScroll sebelum memanggil SQLBulkOperations (kecuali saat melawan ODBC 2.x driver; lihat Kompatibilitas Mundur dan Kepatuhan Standar).

Perilaku ditentukan driver jika SQLBulkOperations, dengan argumen Operasi SQL_ADD, dipanggil pada kursor yang berisi kolom duplikat. Driver dapat mengembalikan SQLSTATE yang ditentukan driver, menambahkan data ke kolom pertama yang muncul dalam tataan hasil, atau melakukan perilaku lain yang ditentukan driver.

Melakukan Pembaruan Massal dengan Menggunakan Marka Buku

Untuk melakukan pembaruan massal dengan menggunakan marka buku dengan SQLBulkOperations, aplikasi melakukan langkah-langkah berikut secara berurutan:

  1. Mengatur atribut pernyataan SQL_ATTR_USE_BOOKMARKS ke SQL_UB_VARIABLE.

  2. Menjalankan kueri yang mengembalikan tataan hasil.

  3. Mengatur atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE ke jumlah baris yang ingin diperbarui.

  4. Memanggil SQLBindCol untuk mengikat data yang ingin diperbarui. Data terikat ke array dengan ukuran yang sama dengan nilai SQL_ATTR_ROW_ARRAY_SIZE. Ini juga memanggil SQLBindCol ke kolom ikat 0 (kolom bookmark).

  5. Menyalin marka buku untuk baris yang tertarik untuk memperbarui ke dalam array yang terikat ke kolom 0.

  6. Memperbarui data di buffer terikat.

    Catatan

    Ukuran array yang ditujukkan oleh atribut pernyataan SQL_ATTR_ROW_STATUS_PTR harus sama dengan SQL_ATTR_ROW_ARRAY_SIZE atau SQL_ATTR_ROW_STATUS_PTR harus berupa pointer null.

  7. Memanggil SQLBulkOperations(StatementHandle, SQL_UPDATE_BY_BOOKMARK).

    Catatan

    Jika aplikasi telah mengatur atribut pernyataan SQL_ATTR_ROW_STATUS_PTR, aplikasi dapat memeriksa array ini untuk melihat hasil operasi.

  8. Secara opsional memanggil SQLBulkOperations (StatementHandle, SQL_FETCH_BY_BOOKMARK) untuk mengambil data ke buffer aplikasi terikat untuk memverifikasi bahwa pembaruan telah terjadi.

  9. Jika data telah diperbarui, driver mengubah nilai dalam array status baris untuk baris yang sesuai menjadi SQL_ROW_UPDATED.

Pembaruan massal yang dilakukan oleh SQLBulkOperations dapat menyertakan data panjang dengan menggunakan panggilan ke SQLParamData dan SQLPutData. Untuk informasi selengkapnya, lihat "Menyediakan Data Panjang untuk Sisipan dan Pembaruan Massal" nanti dalam referensi fungsi ini.

Jika bookmark bertahan di seluruh kursor, aplikasi tidak perlu memanggil SQLFetch atau SQLFetchScroll sebelum memperbarui dengan marka buku. Ini dapat menggunakan marka buku yang telah disimpan dari kursor sebelumnya. Jika marka buku tidak bertahan di seluruh kursor, aplikasi harus memanggil SQLFetch atau SQLFetchScroll untuk mengambil marka buku.

Perilaku ditentukan driver jika SQLBulkOperations, dengan argumen Operasi SQL_UPDATE_BY_BOOKMARK, dipanggil pada kursor yang berisi kolom duplikat. Driver dapat mengembalikan SQLSTATE yang ditentukan driver, memperbarui kolom pertama yang muncul dalam tataan hasil, atau melakukan perilaku lain yang ditentukan driver.

Melakukan Pengambilan Massal Menggunakan Marka Buku

Untuk melakukan pengambilan massal menggunakan marka buku dengan SQLBulkOperations, aplikasi melakukan langkah-langkah berikut secara berurutan:

  1. Mengatur atribut pernyataan SQL_ATTR_USE_BOOKMARKS ke SQL_UB_VARIABLE.

  2. Menjalankan kueri yang mengembalikan tataan hasil.

  3. Mengatur atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE ke jumlah baris yang ingin diambilnya.

  4. Memanggil SQLBindCol untuk mengikat data yang ingin diambilnya. Data terikat ke array dengan ukuran yang sama dengan nilai SQL_ATTR_ROW_ARRAY_SIZE. Ini juga memanggil SQLBindCol ke kolom ikat 0 (kolom bookmark).

  5. Menyalin marka buku untuk baris yang tertarik untuk diambil ke dalam array yang terikat ke kolom 0. (Ini mengasumsikan bahwa aplikasi telah mendapatkan marka buku secara terpisah.)

    Catatan

    Ukuran array yang ditujukkan oleh atribut pernyataan SQL_ATTR_ROW_STATUS_PTR harus sama dengan SQL_ATTR_ROW_ARRAY_SIZE atau SQL_ATTR_ROW_STATUS_PTR harus berupa pointer null.

  6. Memanggil SQLBulkOperations(StatementHandle, SQL_FETCH_BY_BOOKMARK).

  7. Jika aplikasi telah mengatur atribut pernyataan SQL_ATTR_ROW_STATUS_PTR, aplikasi dapat memeriksa array ini untuk melihat hasil operasi.

Jika bookmark bertahan di seluruh kursor, aplikasi tidak perlu memanggil SQLFetch atau SQLFetchScroll sebelum mengambil berdasarkan marka buku. Ini dapat menggunakan marka buku yang telah disimpan dari kursor sebelumnya. Jika marka buku tidak bertahan di seluruh kursor, aplikasi harus memanggil SQLFetch atau SQLFetchScroll satu kali untuk mengambil marka buku.

Melakukan Penghapusan Massal Menggunakan Marka Buku

Untuk melakukan penghapusan massal menggunakan marka buku dengan SQLBulkOperations, aplikasi melakukan langkah-langkah berikut secara berurutan:

  1. Mengatur atribut pernyataan SQL_ATTR_USE_BOOKMARKS ke SQL_UB_VARIABLE.

  2. Menjalankan kueri yang mengembalikan tataan hasil.

  3. Mengatur atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE ke jumlah baris yang ingin dihapusnya.

  4. Memanggil SQLBindCol ke kolom ikat 0 (kolom marka buku).

  5. Menyalin marka buku untuk baris yang tertarik untuk dihapus ke dalam array yang terikat ke kolom 0.

    Catatan

    Ukuran array yang ditujukkan oleh atribut pernyataan SQL_ATTR_ROW_STATUS_PTR harus sama dengan SQL_ATTR_ROW_ARRAY_SIZE atau SQL_ATTR_ROW_STATUS_PTR harus berupa pointer null.

  6. Memanggil SQLBulkOperations(StatementHandle, SQL_DELETE_BY_BOOKMARK).

  7. Jika aplikasi telah mengatur atribut pernyataan SQL_ATTR_ROW_STATUS_PTR, aplikasi dapat memeriksa array ini untuk melihat hasil operasi.

Jika bookmark bertahan di seluruh kursor, aplikasi tidak perlu memanggil SQLFetch atau SQLFetchScroll sebelum menghapus dengan marka buku. Ini dapat menggunakan marka buku yang telah disimpan dari kursor sebelumnya. Jika marka buku tidak bertahan di seluruh kursor, aplikasi harus memanggil SQLFetch atau SQLFetchScroll satu kali untuk mengambil marka buku.

Menyediakan Data Panjang untuk Sisipan dan Pembaruan Massal

Data panjang dapat disediakan untuk sisipan massal dan pembaruan yang dilakukan oleh panggilan ke SQLBulkOperations. Untuk menyisipkan atau memperbarui data panjang, aplikasi melakukan langkah-langkah berikut selain langkah-langkah yang dijelaskan di bagian "Melakukan Penyisipan Massal" dan "Melakukan Pembaruan Massal Menggunakan Marka Buku" sebelumnya dalam topik ini.

  1. Saat mengikat data dengan menggunakan SQLBindCol, aplikasi menempatkan nilai yang ditentukan aplikasi, seperti nomor kolom, di buffer *TargetValuePtr untuk kolom data-at-execution. Nilai dapat digunakan nanti untuk mengidentifikasi kolom.

    Aplikasi menempatkan hasil makro SQL_LEN_DATA_AT_EXEC(panjang) dalam buffer *StrLen_or_IndPtr. Jika jenis data SQL kolom SQL_LONGVARBINARY, SQL_LONGVARCHAR, atau jenis data khusus sumber data panjang dan driver mengembalikan "Y" untuk jenis informasi SQL_NEED_LONG_DATA_LEN di SQLGetInfo, panjangnya adalah jumlah byte data yang akan dikirim untuk parameter; jika tidak, itu harus menjadi nilai nonnegatif dan diabaikan.

  2. Ketika SQLBulkOperations dipanggil, jika ada kolom data-at-execution, fungsi mengembalikan SQL_NEED_DATA dan melanjutkan ke langkah 3, yang mengikuti. (Jika tidak ada kolom data-at-execution, proses selesai.)

  3. Aplikasi memanggil SQLParamData untuk mengambil alamat buffer *TargetValuePtr untuk kolom data-at-execution pertama yang akan diproses. SQLParamData mengembalikan SQL_NEED_DATA. Aplikasi mengambil nilai yang ditentukan aplikasi dari buffer *TargetValuePtr .

    Catatan

    Meskipun parameter data-at-execution menyerupai kolom data-at-execution, nilai yang dikembalikan oleh SQLParamData berbeda untuk masing-masing.

    Kolom data yang dieksekusi adalah kolom dalam kumpulan baris yang datanya akan dikirim dengan SQLPutData saat baris diperbarui atau disisipkan dengan SQLBulkOperations. Mereka terikat dengan SQLBindCol. Nilai yang dikembalikan oleh SQLParamData adalah alamat baris dalam buffer *TargetValuePtr yang sedang diproses.

  4. Aplikasi memanggil SQLPutData satu atau beberapa kali untuk mengirim data untuk kolom. Lebih dari satu panggilan diperlukan jika semua nilai data tidak dapat dikembalikan dalam buffer *TargetValuePtr yang ditentukan dalam SQLPutData; beberapa panggilan ke SQLPutData untuk kolom yang sama hanya diperbolehkan saat mengirim data C karakter ke kolom dengan tipe data khusus karakter, biner, atau sumber data atau saat mengirim data C biner ke kolom dengan karakter, biner, atau jenis data khusus sumber data.

  5. Aplikasi memanggil SQLParamData lagi untuk memberi sinyal bahwa semua data telah dikirim untuk kolom .

    • Jika ada lebih banyak kolom data saat eksekusi, SQLParamData mengembalikan SQL_NEED_DATA dan alamat buffer TargetValuePtr untuk kolom data-at-execution berikutnya yang akan diproses. Aplikasi mengulangi langkah 4 dan 5.

    • Jika tidak ada lagi kolom data-at-execution, proses selesai. Jika pernyataan berhasil dijalankan, SQLParamData mengembalikan SQL_SUCCESS atau SQL_SUCCESS_WITH_INFO; jika eksekusi gagal, maka akan mengembalikan SQL_ERROR. Pada titik ini, SQLParamData dapat mengembalikan SQLSTATE apa pun yang dapat dikembalikan oleh SQLBulkOperations.

Jika operasi dibatalkan atau terjadi kesalahan di SQLParamData atau SQLPutData setelah SQLBulkOperations mengembalikan SQL_NEED_DATA dan sebelum data dikirim untuk semua kolom data yang sedang dieksekusi, aplikasi hanya dapat memanggil SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData, atau SQLPutData untuk pernyataan atau koneksi yang terkait dengan pernyataan. Jika memanggil fungsi lain untuk pernyataan atau koneksi yang terkait dengan pernyataan, fungsi mengembalikan SQL_ERROR dan SQLSTATE HY010 (Kesalahan urutan fungsi).

Jika aplikasi memanggil SQLCancel saat driver masih memerlukan data untuk kolom data yang sedang dieksekusi, driver membatalkan operasi. Aplikasi kemudian dapat memanggil SQLBulkOperations lagi; membatalkan tidak memengaruhi status kursor atau posisi kursor saat ini.

Array Status Baris

Array status baris berisi nilai status untuk setiap baris data dalam set baris setelah panggilan ke SQLBulkOperations. Driver mengatur nilai status dalam array ini setelah panggilan ke SQLFetch, SQLFetchScroll, SQLSetPos, atau SQLBulkOperations. Array ini awalnya diisi oleh panggilan ke SQLBulkOperations jika SQLFetch atau SQLFetchScroll belum dipanggil sebelum SQLBulkOperations. Array ini ditujukkan oleh atribut pernyataan SQL_ATTR_ROW_STATUS_PTR. Jumlah elemen dalam array status baris harus sama dengan jumlah baris dalam set baris (seperti yang ditentukan oleh atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE). Untuk informasi tentang array status baris ini, lihat SQLFetch.

Contoh Kode

Contoh berikut mengambil 10 baris data pada satu waktu dari tabel Pelanggan. Kemudian meminta pengguna untuk mengambil tindakan. Untuk mengurangi lalu lintas jaringan, contoh buffer memperbarui, menghapus, dan menyisipkan secara lokal dalam array terikat, tetapi pada offset melewati data set baris. Ketika pengguna memilih untuk mengirim pembaruan, menghapus, dan menyisipkan ke sumber data, kode mengatur offset pengikatan dengan tepat dan memanggil SQLBulkOperations. Untuk kesederhanaan, pengguna tidak dapat menyangga lebih dari 10 pembaruan, menghapus, atau menyisipkan.

// SQLBulkOperations_Function.cpp  
// compile with: ODBC32.lib  
#include <windows.h>  
#include <sqlext.h>  
#include "stdio.h"  
  
#define UPDATE_ROW 100  
#define DELETE_ROW 101  
#define ADD_ROW 102  
#define SEND_TO_DATA_SOURCE 103  
#define UPDATE_OFFSET 10  
#define INSERT_OFFSET 20  
#define DELETE_OFFSET 30  
  
// Define structure for customer data (assume 10 byte maximum bookmark size).  
typedef struct tagCustStruct {  
   SQLCHAR Bookmark[10];  
   SQLINTEGER BookmarkLen;  
   SQLUINTEGER CustomerID;  
   SQLINTEGER CustIDInd;  
   SQLCHAR CompanyName[51];  
   SQLINTEGER NameLenOrInd;  
   SQLCHAR Address[51];  
   SQLINTEGER AddressLenOrInd;  
   SQLCHAR Phone[11];  
   SQLINTEGER PhoneLenOrInd;  
} CustStruct;  
  
// Allocate 40 of these structures. Elements 0-9 are for the current rowset,  
// elements 10-19 are for the buffered updates, elements 20-29 are for  
// the buffered inserts, and elements 30-39 are for the buffered deletes.  
CustStruct CustArray[40];  
SQLUSMALLINT RowStatusArray[10], Action, RowNum, NumUpdates = 0, NumInserts = 0,  
NumDeletes = 0;  
SQLLEN BindOffset = 0;  
SQLRETURN retcode;  
SQLHENV henv = NULL;  
SQLHDBC hdbc = NULL;  
SQLHSTMT hstmt = NULL;  
  
int main() {  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
   retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
   retcode = SQLConnect(hdbc, (SQLCHAR*) "Northwind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
  
   // Set the following statement attributes:  
   // SQL_ATTR_CURSOR_TYPE:           Keyset-driven  
   // SQL_ATTR_ROW_BIND_TYPE:         Row-wise  
   // SQL_ATTR_ROW_ARRAY_SIZE:        10  
   // SQL_ATTR_USE_BOOKMARKS:         Use variable-length bookmarks  
   // SQL_ATTR_ROW_STATUS_PTR:        Points to RowStatusArray  
   // SQL_ATTR_ROW_BIND_OFFSET_PTR:   Points to BindOffset  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(CustStruct), 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)10, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_USE_BOOKMARKS, (SQLPOINTER)SQL_UB_VARIABLE, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);  
   retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &BindOffset, 0);  
  
   // Bind arrays to the bookmark, CustomerID, CompanyName, Address, and Phone columns.  
   retcode = SQLBindCol(hstmt, 0, SQL_C_VARBOOKMARK, CustArray[0].Bookmark, sizeof(CustArray[0].Bookmark), &CustArray[0].BookmarkLen);  
   retcode = SQLBindCol(hstmt, 1, SQL_C_ULONG, &CustArray[0].CustomerID, 0, &CustArray[0].CustIDInd);  
   retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, CustArray[0].CompanyName, sizeof(CustArray[0].CompanyName), &CustArray[0].NameLenOrInd);  
   retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, CustArray[0].Address, sizeof(CustArray[0].Address), &CustArray[0].AddressLenOrInd);  
   retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, CustArray[0].Phone, sizeof(CustArray[0].Phone), &CustArray[0].PhoneLenOrInd);  
  
   // Execute a statement to retrieve rows from the Customers table.  
   retcode = SQLExecDirect(hstmt, (SQLCHAR*)"SELECT CustomerID, CompanyName, Address, Phone FROM Customers", SQL_NTS);  
  
   // Fetch and display the first 10 rows.  
   retcode = SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0);  
   // DisplayCustData(CustArray, 10);  
  
   // Call GetAction to get an action and a row number from the user.  
   // while (GetAction(&Action, &RowNum)) {  
   Action = SQL_FETCH_NEXT;  
   RowNum = 2;  
   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);  
         // DisplayCustData(CustArray, 10);  
         break;  
  
      case UPDATE_ROW:  
         // Check if we have reached the maximum number of buffered updates.  
         if (NumUpdates < 10) {  
            // Get the new customer data and place it in the next available element of  
            // the buffered updates section of CustArray, copy the bookmark of the row  
            // being updated to the same element, and increment the update counter.  
            // Checking to see we have not already buffered an update for this  
            // row not shown.  
            // GetNewCustData(CustArray, UPDATE_OFFSET + NumUpdates);  
            memcpy(CustArray[UPDATE_OFFSET + NumUpdates].Bookmark,  
               CustArray[RowNum - 1].Bookmark,  
               CustArray[RowNum - 1].BookmarkLen);  
            CustArray[UPDATE_OFFSET + NumUpdates].BookmarkLen =  
               CustArray[RowNum - 1].BookmarkLen;  
            NumUpdates++;  
         } else {  
            printf("Buffers full. Send buffered changes to the data source.");  
         }  
         break;  
      case DELETE_ROW:  
         // Check if we have reached the maximum number of buffered deletes.  
         if (NumDeletes < 10) {  
            // Copy the bookmark of the row being deleted to the next available element  
            // of the buffered deletes section of CustArray and increment the delete  
            // counter. Checking to see we have not already buffered an update for  
            // this row not shown.  
            memcpy(CustArray[DELETE_OFFSET + NumDeletes].Bookmark,  
               CustArray[RowNum - 1].Bookmark,  
               CustArray[RowNum - 1].BookmarkLen);  
  
            CustArray[DELETE_OFFSET + NumDeletes].BookmarkLen =  
               CustArray[RowNum - 1].BookmarkLen;  
  
            NumDeletes++;  
         } else  
            printf("Buffers full. Send buffered changes to the data source.");  
         break;  
  
      case ADD_ROW:  
         // reached maximum number of buffered inserts?  
         if (NumInserts < 10) {  
            // Get the new customer data and place it in the next available element of  
            // the buffered inserts section of CustArray and increment insert counter.  
            // GetNewCustData(CustArray, INSERT_OFFSET + NumInserts);  
            NumInserts++;  
         } else  
            printf("Buffers full. Send buffered changes to the data source.");  
         break;  
  
      case SEND_TO_DATA_SOURCE:  
         // If there are any buffered updates, inserts, or deletes, set the array size  
         // to that number, set the binding offset to use the data in the buffered  
         // update, insert, or delete part of CustArray, and call SQLBulkOperations to  
         // do the updates, inserts, or deletes. Because we will never have more than  
         // 10 updates, inserts, or deletes, we can use the same row status array.  
         if (NumUpdates) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumUpdates, 0);  
            BindOffset = UPDATE_OFFSET * sizeof(CustStruct);  
            SQLBulkOperations(hstmt, SQL_UPDATE_BY_BOOKMARK);  
            NumUpdates = 0;  
         }  
  
         if (NumInserts) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumInserts, 0);  
            BindOffset = INSERT_OFFSET * sizeof(CustStruct);  
            SQLBulkOperations(hstmt, SQL_ADD);  
            NumInserts = 0;  
         }  
  
         if (NumDeletes) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumDeletes, 0);  
            BindOffset = DELETE_OFFSET * sizeof(CustStruct);  
            SQLBulkOperations(hstmt, SQL_DELETE_BY_BOOKMARK);  
            NumDeletes = 0;  
         }  
  
         // If there were any updates, inserts, or deletes, reset the binding offset  
         // and array size to their original values.  
         if (NumUpdates || NumInserts || NumDeletes) {  
            SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)10, 0);  
            BindOffset = 0;  
         }  
         break;  
   }  
   // }  
  
   // Close the cursor.  
   SQLFreeStmt(hstmt, SQL_CLOSE);  
}  
Untuk informasi tentang Lihat
Mengikat buffer ke kolom dalam tataan hasil Fungsi SQLBindCol
Membatalkan pemrosesan pernyataan Fungsi SQLCancel
Mengambil blok data atau menggulir melalui kumpulan hasil Fungsi SQLFetchScroll
Mendapatkan satu bidang deskriptor Fungsi SQLGetDescField
Mendapatkan beberapa bidang deskriptor Fungsi SQLGetDescRec
Mengatur satu bidang deskriptor Fungsi SQLSetDescField
Mengatur beberapa bidang deskriptor Fungsi SQLSetDescRec
Memosisikan kursor, merefresh data di himpunan baris, atau memperbarui atau menghapus data dalam set baris Fungsi SQLSetPos
Mengatur atribut pernyataan Fungsi SQLSetStmtAttr

Lihat Juga

Referensi API ODBC
File Header ODBC