Bagikan melalui


Fungsi SQLBindCol

Kesesuaian
Versi diperkenalkan: Kepatuhan Standar ODBC 1.0: ISO 92

Ringkasan
SQLBindCol mengikat buffer data aplikasi ke kolom dalam tataan hasil.

Sintaks

  
SQLRETURN SQLBindCol(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   ColumnNumber,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_IndPtr);  

Argumen

StatementHandle
[Input] Handel pernyataan.

Nomor Kolom
[Input] Jumlah kolom tataan hasil yang akan diikat. Kolom diberi nomor dalam penambahan urutan kolom mulai dari 0, di mana kolom 0 adalah kolom marka buku. Jika bookmark tidak digunakan - yaitu, atribut pernyataan SQL_ATTR_USE_BOOKMARKS diatur ke SQL_UB_OFF - maka nomor kolom dimulai dari 1.

TargetType
[Input] Pengidentifikasi jenis data C dari buffer *TargetValuePtr . Ketika mengambil data dari sumber data dengan SQLFetch, SQLFetchScroll, SQLBulkOperations, atau SQLSetPos, driver mengonversi data ke jenis ini; ketika mengirim data ke sumber data dengan SQLBulkOperations atau SQLSetPos, driver mengonversi data dari jenis ini. Untuk daftar jenis data C yang valid dan pengidentifikasi jenis, lihat bagian Jenis Data C di Lampiran D: Jenis Data.

Jika argumen TargetType adalah jenis data interval, presisi terdepan interval default (2) dan presisi detik interval default (6), sebagaimana diatur dalam bidang SQL_DESC_DATETIME_INTERVAL_PRECISION dan SQL_DESC_PRECISION ARD, masing-masing digunakan untuk data. Jika argumen TargetType SQL_C_NUMERIC, presisi default (ditentukan driver) dan skala default (0), seperti yang diatur dalam bidang SQL_DESC_PRECISION dan SQL_DESC_SCALE ARD, digunakan untuk data. Jika ada presisi atau skala default yang tidak sesuai, aplikasi harus secara eksplisit mengatur bidang deskriptor yang sesuai dengan panggilan ke SQLSetDescField atau SQLSetDescRec.

Anda juga dapat menentukan jenis data C yang diperluas. Untuk informasi selengkapnya, lihat Jenis Data C di ODBC.

TargetValuePtr
[Input/Output Yang Ditangguhkan] Arahkan ke buffer data untuk mengikat ke kolom. SQLFetch dan SQLFetchScroll mengembalikan data dalam buffer ini. SQLBulkOperations mengembalikan data dalam buffer ini saat Operasi SQL_FETCH_BY_BOOKMARK; SQLBulkOperations mengambil data dari buffer ini saat Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK. SQLSetPos mengembalikan data dalam buffer ini saat Operasi SQL_REFRESH; SQLSetPos mengambil data dari buffer ini saat Operasi SQL_UPDATE.

Jika TargetValuePtr adalah penunjuk null, driver membatalkan ikatan buffer data untuk kolom. Aplikasi dapat membatalkan ikatan semua kolom dengan memanggil SQLFreeStmt dengan opsi SQL_UNBIND. Aplikasi dapat membatalkan ikatan buffer data untuk kolom tetapi masih memiliki buffer panjang/indikator yang terikat untuk kolom, jika argumen TargetValuePtr dalam panggilan ke SQLBindCol adalah penunjuk null tetapi argumen StrLen_or_IndPtr adalah nilai yang valid.

BufferLength
[Input] Panjang buffer *TargetValuePtr dalam byte.

Driver menggunakan BufferLength untuk menghindari penulisan melewati akhir buffer *TargetValuePtr saat mengembalikan data panjang variabel, seperti karakter atau data biner. Perhatikan bahwa driver menghitung karakter penghentian null saat mengembalikan data karakter ke *TargetValuePtr. *Oleh karena itu TargetValuePtr harus berisi ruang untuk karakter penghentian null atau driver akan memotong data.

Ketika driver mengembalikan data panjang tetap, seperti bilangan bulat atau struktur tanggal, driver mengabaikan BufferLength dan mengasumsikan buffer cukup besar untuk menyimpan data. Oleh karena itu, penting bagi aplikasi untuk mengalokasikan buffer yang cukup besar untuk data panjang tetap atau driver akan menulis melewati akhir buffer.

SQLBindCol mengembalikan SQLSTATE HY090 (String tidak valid atau panjang buffer) saat BufferLength kurang dari 0 tetapi tidak ketika BufferLength adalah 0. Namun, jika TargetType menentukan jenis karakter, aplikasi tidak boleh mengatur BufferLength ke 0, karena driver yang mematuhi ISO CLI mengembalikan SQLSTATE HY090 (String tidak valid atau panjang buffer) dalam kasus tersebut.

StrLen_or_IndPtr
[Input/Output Yang Ditangguhkan] Penunjuk ke buffer panjang/indikator untuk mengikat ke kolom. SQLFetch dan SQLFetchScroll mengembalikan nilai dalam buffer ini. SQLBulkOperations mengambil nilai dari buffer ini saat Operasi SQL_ADD, SQL_UPDATE_BY_BOOKMARK, atau SQL_DELETE_BY_BOOKMARK. SQLBulkOperations mengembalikan nilai dalam buffer ini saat Operasi SQL_FETCH_BY_BOOKMARK. SQLSetPos mengembalikan nilai dalam buffer ini saat Operasi SQL_REFRESH; SQLSetPos mengambil nilai dari buffer ini saat Operasi SQL_UPDATE.

SQLFetch, SQLFetchScroll, SQLBulkOperations, dan SQLSetPos dapat mengembalikan nilai berikut dalam buffer panjang/indikator:

  • Panjang data yang tersedia untuk dikembalikan

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

Aplikasi dapat menempatkan nilai berikut dalam buffer panjang/indikator untuk digunakan dengan SQLBulkOperations atau SQLSetPos:

  • Panjang data yang dikirim

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Hasil makro SQL_LEN_DATA_AT_EXEC

  • SQL_COLUMN_IGNORE

Jika buffer indikator dan buffer panjang adalah buffer terpisah, buffer indikator hanya dapat mengembalikan SQL_NULL_DATA, sedangkan buffer panjang dapat mengembalikan semua nilai lainnya.

Untuk informasi selengkapnya, lihat Fungsi SQLBulkOperations, Fungsi SQLFetch, Fungsi SQLSetPos, dan Menggunakan Nilai Panjang/Indikator.

Jika StrLen_or_IndPtr adalah penunjuk null, tidak ada panjang atau nilai indikator yang digunakan. Ini adalah kesalahan saat mengambil data dan data adalah NULL.

Lihat Informasi ODBC 64-Bit, jika aplikasi Anda akan berjalan pada sistem operasi 64-bit.

Kembali

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, atau SQL_INVALID_HANDLE.

Diagnostik

Saat SQLBindCol 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 SQLBindCol 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.

SQLSTATE Kesalahan Deskripsi
01000 Peringatan umum Pesan informasi khusus driver. (Fungsi mengembalikan SQL_SUCCESS_WITH_INFO.)
07006 Pelanggaran atribut jenis data terbatas (DM) Argumen ColumnNumber adalah 0, dan argumen TargetType tidak SQL_C_BOOKMARK atau SQL_C_VARBOOKMARK.
07009 Indeks deskriptor tidak valid Nilai yang ditentukan untuk argumen ColumnNumber melebihi jumlah maksimum kolom dalam tataan hasil.
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.
HY003 Jenis buffer aplikasi tidak valid Argumen TargetType bukan tipe data yang valid atau SQL_C_DEFAULT.
HY010 Kesalahan urutan fungsi (DM) Fungsi eksekusi asinkron dipanggil untuk handel koneksi yang terkait dengan StatementHandle. Fungsi asinkron ini masih dijalankan ketika SQLBindCol 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) Fungsi eksekusi asinkron dipanggil untuk StatementHandle dan masih dijalankan ketika fungsi ini dipanggil.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations, atau SQLSetPos dipanggil untuk StatementHandle dan dikembalikan SQL_NEED_DATA. Fungsi ini dipanggil sebelum data dikirim untuk semua parameter atau kolom data-at-execution.
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 (DM) Nilai yang ditentukan untuk argumen BufferLength kurang dari 0.

(DM) Drivernya adalah ODBC 2.driver x , argumen ColumnNumber diatur ke 0, dan nilai yang ditentukan untuk argumen BufferLength tidak sama dengan 4.
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 konversi yang ditentukan oleh kombinasi argumen TargetType dan jenis data SQL khusus driver dari kolom yang sesuai.

Argumen ColumnNumber adalah 0 dan driver tidak mendukung marka buku.

Driver hanya mendukung ODBC 2.x dan argumen TargetType adalah salah satu dari berikut ini:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

dan salah satu jenis data C interval yang tercantum dalam Jenis Data C di Lampiran D: Jenis Data.

Driver hanya mendukung versi ODBC sebelum 3.50, dan argumen TargetType SQL_C_GUID.
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.

Komentar

SQLBindCol digunakan untuk mengaitkan, atau mengikat, kolom dalam hasil yang diatur ke buffer data dan buffer panjang/indikator dalam aplikasi. Saat aplikasi memanggil SQLFetch, SQLFetchScroll, atau SQLSetPos untuk mengambil data, driver mengembalikan data untuk kolom terikat dalam buffer yang ditentukan; untuk informasi selengkapnya, lihat Fungsi SQLFetch. Saat aplikasi memanggil SQLBulkOperations untuk memperbarui atau menyisipkan baris atau SQLSetPos untuk memperbarui baris, driver mengambil data untuk kolom terikat dari buffer yang ditentukan; untuk informasi selengkapnya, lihat Fungsi SQLBulkOperations atau Fungsi SQLSetPos. Untuk informasi selengkapnya tentang pengikatan, lihat Mengambil Hasil (Dasar).

Perhatikan bahwa kolom tidak harus terikat untuk mengambil data dari kolom tersebut. Aplikasi juga dapat memanggil SQLGetData untuk mengambil data dari kolom. Meskipun dimungkinkan untuk mengikat beberapa kolom secara berturut-turut dan memanggil SQLGetData untuk yang lain, ini tunduk pada beberapa batasan. Untuk informasi selengkapnya, lihat SQLGetData.

Mengikat, Mengikat, dan Mengikat Ulang Kolom

Kolom dapat terikat, tidak terikat, atau rebound kapan saja, bahkan setelah data diambil dari kumpulan hasil. Pengikatan baru berlaku saat berikutnya fungsi yang menggunakan pengikatan dipanggil. Misalnya, aplikasi mengikat kolom dalam tataan hasil dan memanggil SQLFetch. Driver mengembalikan data dalam buffer terikat. Sekarang misalkan aplikasi mengikat kolom ke sekumpulan buffer yang berbeda. Driver tidak menempatkan data untuk baris yang baru diambil di buffer yang baru terikat. Sebagai gantinya, ia menunggu sampai SQLFetch dipanggil lagi dan kemudian menempatkan data untuk baris berikutnya di buffer yang baru terikat.

Catatan

Atribut pernyataan SQL_ATTR_USE_BOOKMARKS harus selalu diatur sebelum mengikat kolom ke kolom 0. Ini tidak diperlukan tetapi sangat disarankan.

Kolom Pengikatan

Untuk mengikat kolom, aplikasi memanggil SQLBindCol dan meneruskan nomor kolom, jenis, alamat, dan panjang buffer data, dan alamat buffer panjang/indikator. Untuk informasi tentang bagaimana alamat ini digunakan, lihat "Alamat Buffer", nanti di bagian ini. Untuk informasi selengkapnya tentang mengikat kolom, lihat Menggunakan SQLBindCol.

Penggunaan buffer ini ditangguhkan; artinya, aplikasi mengikatnya di SQLBindCol tetapi driver mengaksesnya dari fungsi lain - yaitu SQLBulkOperations, SQLFetch, SQLFetchScroll, atau SQLSetPos. Adalah tanggung jawab aplikasi untuk memastikan bahwa pointer yang ditentukan dalam SQLBindCol tetap valid selama pengikatan tetap berlaku. Jika aplikasi memungkinkan pointer ini menjadi tidak valid - misalnya, aplikasi membebaskan buffer - dan kemudian memanggil fungsi yang mengharapkannya valid, konsekuensinya tidak terdefinisi. Untuk informasi selengkapnya, lihat Buffer Yang Ditangguhkan.

Pengikatan tetap berlaku sampai digantikan oleh pengikatan baru, kolom tidak terikat, atau pernyataan dikosongkan.

Unbinding Columns

Untuk membongkar satu kolom, aplikasi memanggil SQLBindCol dengan ColumnNumber yang diatur ke jumlah kolom tersebut dan TargetValuePtr yang diatur ke penunjuk null. Jika ColumnNumber mengacu pada kolom yang tidak terikat, SQLBindCol masih mengembalikan SQL_SUCCESS.

Untuk memisahkan semua kolom, aplikasi memanggil SQLFreeStmt dengan fOption diatur ke SQL_UNBIND. Ini juga dapat dicapai dengan mengatur bidang SQL_DESC_COUNT ARD ke nol.

Mengikat Ulang Kolom

Aplikasi dapat melakukan salah satu dari dua operasi untuk mengubah pengikatan:

  • Panggil SQLBindCol untuk menentukan pengikatan baru untuk kolom yang sudah terikat. Driver menimpa pengikatan lama dengan yang baru.

  • Tentukan offset yang akan ditambahkan ke alamat buffer yang ditentukan oleh panggilan pengikatan ke SQLBindCol. Untuk informasi selengkapnya, lihat bagian berikutnya, "Mengikat Offset."

Offset Pengikatan

Offset pengikatan adalah nilai yang ditambahkan ke alamat data dan buffer panjang/indikator (seperti yang ditentukan dalam argumen TargetValuePtr dan StrLen_or_IndPtr ) sebelum didereferensikan. Ketika offset digunakan, pengikatan adalah "templat" tentang bagaimana buffer aplikasi ditata, dan aplikasi dapat memindahkan "templat" ini ke area memori yang berbeda dengan mengubah offset. Karena offset yang sama ditambahkan ke setiap alamat di setiap pengikatan, offset relatif antara buffer untuk kolom yang berbeda harus sama dalam setiap set buffer. Ini selalu benar ketika pengikatan baris bijaksana digunakan; aplikasi harus dengan hati-hati menjabarkan buffernya agar benar ketika pengikatan bijaksana kolom digunakan.

Menggunakan offset pengikatan pada dasarnya memiliki efek yang sama dengan mengikat ulang kolom dengan memanggil SQLBindCol. Perbedaannya adalah bahwa panggilan baru ke SQLBindCol menentukan alamat baru untuk buffer data dan buffer panjang/indikator, sedangkan penggunaan offset pengikatan tidak mengubah alamat tetapi hanya menambahkan offset ke mereka. Aplikasi dapat menentukan offset baru kapan pun diinginkan, dan offset ini selalu ditambahkan ke alamat yang awalnya terikat. Secara khusus, jika offset diatur ke 0 atau jika atribut pernyataan diatur ke pointer null, driver menggunakan alamat yang awalnya terikat.

Untuk menentukan offset pengikatan, aplikasi mengatur atribut pernyataan SQL_ATTR_ROW_BIND_OFFSET_PTR ke alamat buffer SQLINTEGER. Sebelum aplikasi memanggil fungsi yang menggunakan pengikatan, aplikasi menempatkan offset dalam byte dalam buffer ini. Untuk menentukan alamat buffer yang akan digunakan, driver menambahkan offset ke alamat dalam pengikatan. Jumlah alamat dan offset harus berupa alamat yang valid, tetapi alamat tempat offset ditambahkan tidak harus valid. Untuk informasi selengkapnya tentang bagaimana offset pengikatan digunakan, lihat "Alamat Buffer," nanti di bagian ini.

Mengikat Array

Jika ukuran set baris (nilai atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE) lebih besar dari 1, aplikasi mengikat array buffer alih-alih buffer tunggal. Untuk informasi selengkapnya, lihat Memblokir Kursor.

Aplikasi dapat mengikat array dengan dua cara:

  • Ikat array ke setiap kolom. Ini disebut sebagai pengikatan kolom yang bijaksana karena setiap struktur data (array) berisi data untuk satu kolom.

  • Tentukan struktur untuk menyimpan data untuk seluruh baris dan mengikat array struktur ini. Ini disebut sebagai pengikatan baris-bijaksana karena setiap struktur data berisi data untuk satu baris.

Setiap array buffer harus memiliki setidaknya elemen sebanyak ukuran set baris.

Catatan

Aplikasi harus memverifikasi bahwa perataan valid. Untuk informasi selengkapnya tentang pertimbangan perataan, lihat Perataan.

Pengikatan Bijak Kolom

Dalam pengikatan kolom yang bijaksana, aplikasi mengikat data terpisah dan array panjang/indikator ke setiap kolom.

Untuk menggunakan pengikatan kolom yang bijaksana, aplikasi pertama-tama mengatur atribut pernyataan SQL_ATTR_ROW_BIND_TYPE ke SQL_BIND_BY_COLUMN. (Ini adalah default.) Agar setiap kolom terikat, aplikasi melakukan langkah-langkah berikut:

  1. Mengalokasikan array buffer data.

  2. Mengalokasikan array buffer panjang/indikator.

    Catatan

    Jika aplikasi menulis langsung ke deskriptor saat pengikatan bijaksana kolom digunakan, array terpisah dapat digunakan untuk data panjang dan indikator.

  3. Memanggil SQLBindCol dengan argumen berikut:

    • TargetType adalah jenis elemen tunggal dalam array buffer data.

    • TargetValuePtr adalah alamat array buffer data.

    • BufferLength adalah ukuran elemen tunggal dalam array buffer data. Argumen BufferLength diabaikan saat data adalah data dengan panjang tetap.

    • StrLen_or_IndPtr adalah alamat array panjang/indikator.

Untuk informasi selengkapnya tentang bagaimana informasi ini digunakan, lihat "Alamat Buffer," nanti di bagian ini. Untuk informasi selengkapnya tentang pengikatan kolom yang bijaksana, lihat Pengikatan Kolom-Bijaksana.

Pengikatan Bijak Baris

Dalam pengikatan baris-bijaksana, aplikasi menentukan struktur yang berisi data dan buffer panjang/indikator agar setiap kolom terikat.

Untuk menggunakan pengikatan baris yang bijaksana, aplikasi melakukan langkah-langkah berikut:

  1. Menentukan struktur untuk menyimpan satu baris data (termasuk buffer data dan panjang/indikator) dan mengalokasikan array struktur ini.

    Catatan

    Jika aplikasi menulis langsung ke deskriptor saat pengikatan row-wise digunakan, bidang terpisah dapat digunakan untuk data panjang dan indikator.

  2. Mengatur atribut pernyataan SQL_ATTR_ROW_BIND_TYPE ke ukuran struktur yang berisi satu baris data atau ke ukuran instans buffer tempat kolom hasil akan terikat. Panjangnya harus mencakup ruang untuk semua kolom terikat, dan padding struktur atau buffer apa pun, untuk memastikan bahwa ketika alamat kolom terikat bertahap dengan panjang yang ditentukan, hasilnya akan menunjuk ke awal kolom yang sama di baris berikutnya. Saat menggunakan operator sizeof di ANSI C, perilaku ini dijamin.

  3. Memanggil SQLBindCol dengan argumen berikut agar setiap kolom terikat:

    • TargetType adalah jenis anggota buffer data yang akan terikat ke kolom.

    • TargetValuePtr adalah alamat anggota buffer data dalam elemen array pertama.

    • BufferLength adalah ukuran anggota buffer data.

    • StrLen_or_IndPtr adalah alamat anggota panjang/indikator yang akan diikat.

Untuk informasi selengkapnya tentang bagaimana informasi ini digunakan, lihat "Alamat Buffer," nanti di bagian ini. Untuk informasi selengkapnya tentang pengikatan kolom bijaksana, lihat Pengikatan Row-Wise.

Alamat Buffer

Alamat buffer adalah alamat aktual dari penyangga data atau panjang/indikator. Driver menghitung alamat buffer tepat sebelum menulis ke buffer (seperti selama waktu pengambilan). Ini dihitung dari rumus berikut, yang menggunakan alamat yang ditentukan dalam argumen TargetValuePtr dan StrLen_or_IndPtr , offset pengikatan, dan nomor baris:

Offset Pengikatan Alamat + Terikat + ((Nomor Baris - 1) x Ukuran Elemen)

di mana variabel rumus didefinisikan seperti yang dijelaskan dalam tabel berikut.

Variabel Deskripsi
Alamat Terikat Untuk buffer data, alamat yang ditentukan dengan argumen TargetValuePtr di SQLBindCol.

Untuk buffer panjang/indikator, alamat yang ditentukan dengan argumen StrLen_or_IndPtr di SQLBindCol. Untuk informasi selengkapnya, lihat "Komentar Tambahan" di bagian "Deskriptor dan SQLBindCol".

Jika alamat terikat adalah 0, tidak ada nilai data yang dikembalikan, bahkan jika alamat seperti yang dihitung oleh rumus sebelumnya bukan nol.
Offset Pengikatan Jika pengikatan baris bijaksana digunakan, nilai yang disimpan di alamat yang ditentukan dengan atribut pernyataan SQL_ATTR_ROW_BIND_OFFSET_PTR.

Jika pengikatan kolom bijaksana digunakan atau jika nilai atribut pernyataan SQL_ATTR_ROW_BIND_OFFSET_PTR adalah penunjuk null, Offset Pengikatan adalah 0.
Nomor Baris Jumlah baris berbasis 1 dalam set baris. Untuk pengambilan baris tunggal, yang merupakan default, ini adalah 1.
Ukuran Elemen Ukuran elemen dalam array terikat.

Jika pengikatan kolom bijaksana digunakan, ini adalah sizeof(SQLINTEGER) untuk buffer panjang/indikator. Untuk buffer data, itu adalah nilai argumen BufferLength di SQLBindCol jika jenis data memiliki panjang variabel, dan ukuran jenis data jika jenis data memiliki panjang tetap.

Jika pengikatan baris bijaksana digunakan, ini adalah nilai atribut pernyataan SQL_ATTR_ROW_BIND_TYPE untuk buffer data dan panjang/indikator.

Deskriptor dan SQLBindCol

Bagian berikut menjelaskan bagaimana SQLBindCol berinteraksi dengan deskriptor.

Perhatian

Memanggil SQLBindCol untuk satu pernyataan dapat memengaruhi pernyataan lain. Ini terjadi ketika ARD yang terkait dengan pernyataan dialokasikan secara eksplisit dan juga terkait dengan pernyataan lain. Karena SQLBindCol memodifikasi deskriptor, modifikasi berlaku untuk semua pernyataan yang terkait dengan deskriptor ini. Jika ini bukan perilaku yang diperlukan, aplikasi harus memisahkan deskriptor ini dari pernyataan lain sebelum memanggil SQLBindCol.

Pemetaan Argumen

Secara konseptual, SQLBindCol melakukan langkah-langkah berikut secara berurutan:

  1. Memanggil SQLGetStmtAttr untuk mendapatkan handel ARD.

  2. Memanggil SQLGetDescField untuk mendapatkan bidang SQL_DESC_COUNT deskriptor ini, dan jika nilai dalam argumen ColumnNumber melebihi nilai SQL_DESC_COUNT, memanggil SQLSetDescField untuk meningkatkan nilai SQL_DESC_COUNT ke ColumnNumber.

  3. Memanggil SQLSetDescField beberapa kali untuk menetapkan nilai ke bidang ARD berikut:

    • Mengatur SQL_DESC_TYPE dan SQL_DESC_CONCISE_TYPE ke nilai TargetType, kecuali bahwa jika TargetType adalah salah satu pengidentifikasi ringkas dari subjenis tanggalwaktu atau interval, ia mengatur SQL_DESC_TYPE ke SQL_DATETIME atau SQL_INTERVAL, masing-masing; mengatur SQL_DESC_CONCISE_TYPE ke pengidentifikasi ringkas; dan mengatur SQL_DESC_DATETIME_INTERVAL_CODE ke subkode tanggal atau interval yang sesuai.

    • Mengatur satu atau beberapa SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE, dan SQL_DESC_DATETIME_INTERVAL_PRECISION, yang sesuai untuk TargetType.

    • Mengatur bidang SQL_DESC_OCTET_LENGTH ke nilai BufferLength.

    • Mengatur bidang SQL_DESC_DATA_PTR ke nilai TargetValuePtr.

    • Mengatur bidang SQL_DESC_INDICATOR_PTR ke nilai StrLen_or_IndPtr. (Lihat paragraf berikut.)

    • Mengatur bidang SQL_DESC_OCTET_LENGTH_PTR ke nilai StrLen_or_IndPtr. (Lihat paragraf berikut.)

Variabel yang dirujuk argumen StrLen_or_IndPtr digunakan untuk informasi indikator dan panjang. Jika pengambilan menemukan nilai null untuk kolom, ia menyimpan SQL_NULL_DATA dalam variabel ini; jika tidak, ia menyimpan panjang data dalam variabel ini. Meneruskan penunjuk null sebagai StrLen_or_IndPtr menjaga operasi pengambilan tidak mengembalikan panjang data tetapi membuat pengambilan gagal jika menemukan nilai null dan tidak memiliki cara untuk mengembalikan SQL_NULL_DATA.

Jika panggilan ke SQLBindCol gagal, konten bidang deskriptor yang akan diatur di ARD tidak ditentukan dan nilai bidang SQL_DESC_COUNT ARD tidak berubah.

Pengaturan Ulang Implisit Bidang COUNT

SQLBindCol mengatur SQL_DESC_COUNT ke nilai argumen ColumnNumber hanya ketika ini akan meningkatkan nilai SQL_DESC_COUNT. Jika nilai dalam argumen TargetValuePtr adalah penunjuk null dan nilai dalam argumen ColumnNumber sama dengan SQL_DESC_COUNT (yaitu, saat membatalkan pengikatan kolom terikat tertinggi), maka SQL_DESC_COUNT diatur ke jumlah kolom terikat tertinggi yang tersisa.

Perhatian Mengenai SQL_DEFAULT

Agar berhasil mengambil data kolom, aplikasi harus menentukan dengan benar panjang dan titik awal data dalam buffer aplikasi. Ketika aplikasi menentukan TargetType eksplisit, kesalahpahaman aplikasi mudah dideteksi. Namun, ketika aplikasi menentukan TargetType SQL_DEFAULT, SQLBindCol dapat diterapkan ke kolom jenis data yang berbeda dari yang dimaksudkan oleh aplikasi, baik dari perubahan ke metadata atau dengan menerapkan kode ke kolom yang berbeda. Dalam hal ini, aplikasi mungkin tidak selalu menentukan awal atau panjang data kolom yang diambil. Ini dapat menyebabkan kesalahan data atau pelanggaran memori yang tidak dilaporkan.

Contoh Kode

Dalam contoh berikut, aplikasi menjalankan pernyataan SELECT pada tabel Pelanggan untuk mengembalikan kumpulan hasil ID, nama, dan nomor telepon pelanggan, yang diurutkan menurut nama. Kemudian memanggil SQLBindCol untuk mengikat kolom data ke buffer lokal. Terakhir, aplikasi mengambil setiap baris data dengan SQLFetch dan mencetak nama, ID, dan nomor telepon setiap pelanggan.

Untuk contoh kode lainnya, lihat Fungsi SQLBulkOperations, Fungsi SQLColumns, Fungsi SQLFetchScroll, dan Fungsi SQLSetPos.

// SQLBindCol_ref.cpp  
// compile with: odbc32.lib  
#include <windows.h>  
#include <stdio.h>  
  
#define UNICODE  
#include <sqlext.h>  
  
#define NAME_LEN 50  
#define PHONE_LEN 60
  
void show_error() {  
   printf("error\n");  
}  
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt = 0;  
   SQLRETURN retcode;  
   SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];  
   SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;  
  
   // Allocate environment handle  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
  
   // Set the ODBC version environment attribute  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
      // Allocate connection handle  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  
  
         // Set login timeout to 5 seconds  
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
            // Connect to data source  
            retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);  
  
            // Allocate statement handle  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {   
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
  
               retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
  
                  // Bind columns 1, 2, and 3  
                  retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);  
                  retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);  
                  retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);   
  
                  // Fetch and print each row of data. On an error, display a message and exit.  
                  for (int i=0 ; ; i++) {  
                     retcode = SQLFetch(hstmt);  
                     if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)  
                        show_error();  
                     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
                     {
                        //replace wprintf with printf
                        //%S with %ls
                        //warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
                        //but variadic argument 2 has type 'SQLWCHAR *'
                        //wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);  
                        printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);  
                    }    
                     else  
                        break;  
                  }  
               }  
  
               // Process data  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLCancel(hstmt);  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}  

Lihat juga, Contoh Program ODBC.

Untuk informasi tentang Lihat
Mengembalikan informasi tentang kolom dalam tataan hasil Fungsi SQLDescribeCol
Mengambil blok data atau menggulir melalui kumpulan hasil Fungsi SQLFetchScroll
Mengambil beberapa baris data Fungsi SQLFetch
Merilis buffer kolom pada pernyataan Fungsi SQLFreeStmt
Mengambil bagian atau semua kolom data Fungsi SQLGetData
Mengembalikan jumlah kolom tataan hasil Fungsi SQLNumResultCols

Lihat Juga

Referensi API ODBC
File Header ODBC