Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Kesesuaian
Versi diperkenalkan: Kepatuhan Standar ODBC 1.0: ISO 92
Summary
SQLBindCol mengikat buffer data aplikasi ke kolom dalam set hasil.
Syntax
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Arguments
StatementHandle
[Input] Handel pernyataan.
Nomor Kolom
[Input] Nomor kolom set hasil yang akan diikat. Kolom diberi nomor dengan urutan kolom yang meningkat mulai dari 0, di mana kolom 0 adalah kolom bookmark. Jika bookmark tidak digunakan - yaitu, atribut pernyataan SQL_ATTR_USE_BOOKMARKS diatur ke SQL_UB_OFF - maka nomor kolom dimulai dari 1.
Tipe Sasaran
[Input] Pengidentifikasi tipe data C dari buffer *TargetValuePtr . Ketika mengambil data dari sumber data dengan SQLFetch, SQLFetchScroll, SQLBulkOperations, atau SQLSetPos, driver mengonversi data ke tipe ini; ketika mengirim data ke sumber data dengan SQLBulkOperations atau SQLSetPos, driver mengonversi data dari tipe ini. Untuk daftar tipe data C yang valid dan pengenal tipe, lihat bagian Tipe Data C di Lampiran D: Tipe Data.
Jika argumen TargetType adalah tipe data interval, presisi awal interval default (2) dan presisi interval detik default (6), yang diatur dalam bidang SQL_DESC_DATETIME_INTERVAL_PRECISION dan SQL_DESC_PRECISION ARD, masing-masing, digunakan untuk data tersebut. Jika argumen TargetType SQL_C_NUMERIC, presisi default (didefinisikan driver) dan skala default (0), seperti yang diatur pada bidang SQL_DESC_PRECISION dan SQL_DESC_SCALE ARD, digunakan untuk data. Jika presisi atau skala default tidak sesuai, aplikasi harus secara eksplisit mengatur bidang deskriptor yang sesuai dengan memanggil SQLSetDescField atau SQLSetDescRec.
Anda juga dapat menentukan jenis data C yang diperluas. Untuk informasi selengkapnya, lihat Jenis Data C di ODBC.
TargetValuePtr
[Input/Output Ditunda] Penunjuk ke buffer data untuk diikat ke kolom.
SQLFetch dan SQLFetchScroll mengembalikan data dalam buffer ini.
SQLBulkOperations mengembalikan data dalam buffer ini ketika Operasi SQL_FETCH_BY_BOOKMARK; ia mengambil data dari buffer ini saat Operasi SQL_ADD atau SQL_UPDATE_BY_BOOKMARK.
SQLSetPos mengembalikan data dalam buffer ini saat Operasi SQL_REFRESH; ia mengambil data dari buffer ini saat Operasi SQL_UPDATE.
Jika TargetValuePtr adalah null pointer, driver akan melepaskan ikatan data buffer untuk kolom tersebut. Sebuah aplikasi dapat melepaskan semua kolom dengan memanggil SQLFreeStmt menggunakan opsi SQL_UNBIND. Sebuah aplikasi dapat melepaskan ikatan data buffer untuk sebuah kolom tetapi tetap memiliki batas buffer panjang/indikator untuk kolom tersebut, jika argumen TargetValuePtr dalam pemanggilan SQLBindCol adalah null pointer tetapi argumen StrLen_or_IndPtr adalah nilai yang valid.
BufferLength
[Input] Panjang buffer *TargetValuePtr dalam byte.
Driver menggunakan BufferLength untuk menghindari menulis melewati akhir buffer *TargetValuePtr saat mengembalikan data panjang variabel, seperti data karakter atau biner. Perhatikan bahwa driver menghitung karakter null-termination saat mengembalikan data karakter ke *TargetValuePtr. *Oleh karena itu, TargetValuePtr harus berisi ruang untuk karakter null-terminasi atau driver akan memotong data.
Ketika driver mengembalikan data dengan panjang tetap, seperti bilangan bulat atau struktur tanggal, driver mengabaikan BufferLength dan menganggap buffer cukup besar untuk menampung data. Oleh karena itu, penting bagi aplikasi untuk mengalokasikan buffer yang cukup besar untuk data dengan panjang tetap atau driver akan menulis melewati ujung buffer.
SQLBindCol mengembalikan SQLSTATE HY090 (String atau panjang buffer tidak valid) ketika BufferLength kurang dari 0 tetapi tidak jika BufferLength adalah 0. Namun, jika TargetType menentukan tipe karakter, aplikasi tidak boleh mengatur BufferLength ke 0, karena driver yang sesuai dengan ISO CLI mengembalikan SQLSTATE HY090 (String atau buffer length tidak valid) dalam kasus tersebut.
StrLen_or_IndPtr
[Input/Output Ditunda] Penunjuk ke buffer panjang/indikator untuk diikat ke kolom.
SQLFetch dan SQLFetchScroll mengembalikan nilai dalam buffer ini.
SQLBulkOperations mengambil nilai dari buffer ini ketika Operasi SQL_ADD, SQL_UPDATE_BY_BOOKMARK, atau SQL_DELETE_BY_BOOKMARK.
SQLBulkOperations mengembalikan nilai dalam buffer ini ketika Operation SQL_FETCH_BY_BOOKMARK.
SQLSetPos mengembalikan nilai di buffer ini ketika Operation SQL_REFRESH; ia 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-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 dari 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 lebih lanjut, lihat Fungsi SQLBulkOperations, Fungsi SQLFetch, Fungsi SQLSetPos, dan Menggunakan Nilai Panjang/Indikator.
Jika StrLen_or_IndPtr adalah null pointer, tidak digunakan panjang atau nilai indikator. Ini adalah kesalahan saat mengambil data dan data tersebut NULL.
Lihat Informasi ODBC 64-Bit, jika aplikasi Anda akan berjalan pada sistem operasi 64-bit.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, atau SQL_INVALID_HANDLE.
Diagnostics
Ketika SQLBindCol mengembalikan SQL_ERROR atau SQL_SUCCESS_WITH_INFO, nilai SQLSTATE terkait dapat diperoleh dengan memanggil SQLGetDiagRec dengan HandleType SQL_HANDLE_STMT dan HandleStatementHandle. Tabel berikut mencantumkan nilai SQLSTATE yang biasanya dikembalikan oleh SQLBindCol dan menjelaskan masing-masing dalam konteks fungsi ini; notasi "(DM)" mendahului deskripsi SQLSTATE 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 set 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 bukanlah tipe data yang valid maupun SQL_C_DEFAULT. |
| HY010 | Kesalahan urutan fungsi | (DM) Fungsi eksekusi asinkron dipanggil untuk handel koneksi yang terkait dengan StatementHandle. Fungsi asinkron ini masih berjalan saat 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) Sopirnya adalah ODBC 2. x driver, 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 tipe data SQL spesifik driver dari kolom yang sesuai. Argumen ColumnNumber adalah 0 dan driver tidak mendukung bookmark. 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 tipe data interval C yang tercantum dalam Tipe Data C di Lampiran D: Tipe Data. Driver hanya mendukung versi ODBC sebelum versi 3.50, dan argumen TargetType SQL_C_GUID. |
| HYT01 | Waktu tunggu koneksi habis | 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 set hasil ke data buffer dan buffer panjang/indikator dalam aplikasi. Ketika aplikasi memanggil SQLFetch, SQLFetchScroll, atau SQLSetPos untuk mengambil data, driver mengembalikan data untuk kolom terikat di buffer yang ditentukan; untuk informasi lebih lanjut, lihat Fungsi SQLFetch. Ketika 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 lebih lanjut, lihat Fungsi SQLBulkOperations atau Fungsi SQLSetPos. Untuk informasi lebih lanjut tentang binding, lihat Pengambilan Hasil (Dasar).
Perhatikan bahwa kolom tidak harus terikat untuk mengambil data dari kolom tersebut. Sebuah aplikasi juga dapat memanggil SQLGetData untuk mengambil data dari kolom. Meskipun memungkinkan untuk mengikat beberapa kolom dalam satu baris dan memanggil SQLGetData untuk kolom lain, hal ini tunduk pada beberapa pembatasan. Untuk informasi lebih lanjut, lihat SQLGetData.
Membinding, Membuka Ikatan, dan Mengikat Ulang Kolom
Sebuah kolom dapat diikat, dilepaskan, atau di-rebound kapan saja, bahkan setelah data diambil dari hasil tersebut. Pengikatan baru akan berlaku saat fungsi yang menggunakan pengikatan dipanggil berikutnya. Misalnya, misalkan sebuah aplikasi mengikat kolom-kolom dalam satu set hasil dan memanggil SQLFetch. Driver mengembalikan data dalam buffer yang terikat. Sekarang misalkan aplikasi mengikat kolom-kolom tersebut ke set buffer yang berbeda. Driver tidak memasukkan data untuk baris yang baru diambil ke buffer yang baru diikat. Sebaliknya, data menunggu hingga SQLFetch dipanggil lagi lalu menempatkan data untuk baris berikutnya di buffer yang baru diikat.
Note
Atribut pernyataan SQL_ATTR_USE_BOOKMARKS harus selalu diatur sebelum mengikat kolom ke kolom 0. Ini tidak wajib tetapi sangat direkomendasikan.
Kolom Penghubung
Untuk mengikat kolom, sebuah aplikasi memanggil SQLBindCol dan mengirimkan nomor kolom, tipe, alamat, dan panjang buffer data, serta alamat buffer panjang/indikator. Untuk informasi tentang bagaimana alamat-alamat ini digunakan, lihat "Alamat Buffer," di bagian selanjutnya di bagian ini. Untuk informasi lebih lanjut tentang binding column, lihat Menggunakan SQLBindCol.
Penggunaan buffer ini ditunda; artinya, aplikasi mengikatnya dalam SQLBindCol tetapi driver mengaksesnya dari fungsi lain - yaitu SQLBulkOperations, SQLFetch, SQLFetchScroll, atau SQLSetPos. Merupakan tanggung jawab aplikasi untuk memastikan bahwa pointer yang ditentukan dalam SQLBindCol tetap valid selama binding masih berlaku. Jika aplikasi membiarkan pointer ini menjadi tidak valid - misalnya, membebaskan buffer - dan kemudian memanggil fungsi yang mengharapkan pointer valid, konsekuensinya tidak terdefinisi. Untuk informasi lebih lanjut, lihat Buffer Ditunda.
Pengikatan tetap berlaku sampai digantikan oleh pengikatan baru, kolom tidak terikat, atau pernyataan dibebaskan.
Membuka Ikatan Kolom
Untuk melepaskan ikatan satu kolom, sebuah aplikasi memanggil SQLBindCol dengan ColumnNumber diatur ke nomor kolom tersebut dan TargetValuePtr ke null pointer. Jika ColumnNumber merujuk pada kolom yang tidak terikat, SQLBindCol tetap mengembalikan SQL_SUCCESS.
Untuk melepaskan semua kolom, sebuah aplikasi memanggil SQLFreeStmt dengan fOption diatur ke SQL_UNBIND. Hal ini juga dapat dilakukan dengan mengatur medan SQL_DESC_COUNT ARD ke nol.
Membeut Ulang Kolom
Aplikasi dapat melakukan salah satu dari dua operasi untuk mengubah pengikatan:
Panggil SQLBindCol untuk menentukan binding baru untuk kolom yang sudah terikat. Driver menimpa pengikatan lama dengan yang baru.
Tentukan offset yang akan ditambahkan ke alamat buffer yang ditentukan oleh binding call ke SQLBindCol. Untuk informasi lebih lanjut, lihat bagian berikutnya, "Binding Offsets."
Offset Pengikatan
Binding offset adalah nilai yang ditambahkan ke alamat buffer data dan panjang/indikator (sebagaimana ditentukan dalam argumen TargetValuePtr dan StrLen_or_IndPtr ) sebelum di-dereferensi. Ketika offset digunakan, binding tersebut menjadi "template" tentang bagaimana buffer aplikasi disusun, dan aplikasi dapat memindahkan "template" ini ke area memori yang berbeda dengan mengubah offset. Karena offset yang sama ditambahkan ke setiap alamat dalam setiap binding, offset relatif antara buffer untuk kolom yang berbeda harus sama dalam setiap set buffer. Hal ini selalu berlaku ketika binding baris demi baris digunakan; Aplikasi harus dengan cermat menyusun buffer-nya agar hal ini benar saat pengikatan kolom digunakan.
Menggunakan binding offset pada dasarnya memiliki efek yang sama seperti meng-rebinding kolom dengan memanggil SQLBindCol. Perbedaannya adalah panggilan baru ke SQLBindCol menentukan alamat baru untuk buffer data dan buffer panjang/indikator, sedangkan penggunaan binding offset tidak mengubah alamat tersebut tetapi hanya menambahkan offset ke alamat tersebut. Aplikasi dapat menentukan offset baru kapan saja diinginkan, dan offset ini selalu ditambahkan ke alamat yang awalnya terikat. Secara khusus, jika offset diatur ke 0 atau atribut pernyataan diatur ke null pointer, 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 binding, aplikasi menempatkan offset dalam byte pada buffer ini. Untuk menentukan alamat buffer yang akan digunakan, driver menambahkan offset ke alamat dalam binding. Jumlah alamat dan offset harus merupakan alamat yang valid, tetapi alamat tempat offset ditambahkan tidak harus valid. Untuk informasi lebih lanjut tentang bagaimana offset binding digunakan, lihat "Alamat Buffer," di bagian selanjutnya di bagian ini.
Array Pengikat
Jika ukuran rowset (nilai atribut pernyataan SQL_ATTR_ROW_ARRAY_SIZE) lebih besar dari 1, aplikasi mengikat array buffer daripada buffer tunggal. Untuk informasi lebih lanjut, lihat Blok Kursor.
Aplikasi dapat mengikat array dengan dua cara:
Mengikatkan array ke setiap kolom. Ini disebut sebagai pengikatan kolom karena setiap struktur data (array) berisi data untuk satu kolom.
Tentukan sebuah struktur untuk menyimpan data selama satu baris penuh dan bind array dari struktur tersebut. Ini disebut sebagai pengikatan baris karena setiap struktur data berisi data untuk satu baris saja.
Setiap array buffer harus memiliki setidaknya sebanyak elemen sebesar ukuran rowset.
Note
Sebuah aplikasi harus memverifikasi bahwa penyelarasan valid. Untuk informasi lebih lanjut tentang pertimbangan penyelarasan, lihat Penjajaran.
Pengikatan Column-Wise
Dalam binding per kolom, aplikasi mengikat data dan array panjang/indikator terpisah ke setiap kolom.
Untuk menggunakan binding kolom, 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:
Mengalokasikan array buffer data.
Mengalokasikan array buffer panjang/indikator.
Note
Jika aplikasi menulis langsung ke deskriptor saat pengikatan bijaksana kolom digunakan, array terpisah dapat digunakan untuk data panjang dan indikator.
Memanggil SQLBindCol dengan argumen berikut:
TargetType adalah tipe dari satu elemen dalam array data buffer.
TargetValuePtr adalah alamat dari array buffer data.
BufferLength adalah ukuran satu elemen dalam array data buffer. Argumen BufferLength diabaikan saat data adalah data dengan panjang tetap.
StrLen_or_IndPtr adalah alamat array panjang/indikator.
Untuk informasi lebih lanjut tentang bagaimana informasi ini digunakan, lihat "Alamat Buffer," di bagian selanjutnya di bagian ini. Untuk informasi lebih lanjut tentang binding kolom-demi-kolom, lihat Column-Wise Binding.
Row-Wise Pengikatan
Dalam binding baris demi baris, aplikasi mendefinisikan struktur yang berisi data dan buffer panjang/indikator untuk setiap kolom yang akan diikat.
Untuk menggunakan pengikatan baris yang bijaksana, aplikasi melakukan langkah-langkah berikut:
Mendefinisikan struktur untuk menampung satu baris data (termasuk buffer data dan panjang/indikator) dan mengalokasikan array struktur tersebut.
Note
Jika aplikasi menulis langsung ke deskriptor saat pengikatan row-wise digunakan, bidang terpisah dapat digunakan untuk data panjang dan indikator.
Mengatur atribut pernyataan SQL_ATTR_ROW_BIND_TYPE ke ukuran struktur yang berisi satu baris data atau ke ukuran instance buffer tempat kolom hasil akan diikat. Panjang harus mencakup ruang untuk semua kolom yang terikat, dan setiap padding pada struktur atau buffer, untuk memastikan bahwa ketika alamat kolom terikat ditambah dengan panjang yang ditentukan, hasilnya akan mengarah ke awal kolom yang sama di baris berikutnya. Saat menggunakan operator sizeof di ANSI C, perilaku ini dijamin.
Memanggil SQLBindCol dengan argumen berikut untuk setiap kolom yang akan diikat:
TargetType adalah tipe anggota buffer data yang akan diikat ke kolom.
TargetValuePtr adalah alamat anggota data buffer pada elemen array pertama.
BufferLength adalah ukuran anggota buffer data.
StrLen_or_IndPtr adalah alamat anggota panjang/indikator yang akan diikat.
Untuk informasi lebih lanjut tentang bagaimana informasi ini digunakan, lihat "Alamat Buffer," di bagian selanjutnya di bagian ini. Untuk informasi lebih lanjut tentang binding kolom-demi-kolom, lihat Row-Wise Binding.
Alamat Buffer
Alamat buffer adalah alamat aktual dari buffer data atau panjang/indikator. Driver menghitung alamat buffer tepat sebelum menulis ke buffer (misalnya saat waktu pengambilan data). Ini dihitung dari rumus berikut, yang menggunakan alamat yang ditentukan dalam argumen TargetValuePtr dan StrLen_or_IndPtr , offset pengikatan, dan nomor baris:
alamat terikat + Offset Binding + ((Nomor Baris - 1) x Ukuran Elemen)
di mana variabel formula didefinisikan seperti yang dijelaskan dalam tabel berikut.
| Variable | Deskripsi |
|---|---|
| alamat terikat | Untuk data buffer, alamat yang ditentukan dengan argumen TargetValuePtr di SQLBindCol. Untuk buffer panjang/indikator, alamat yang ditentukan dengan argumen StrLen_or_IndPtr di SQLBindCol. Untuk informasi lebih lanjut, lihat "Komentar Tambahan" di bagian "Deskriptor dan SQLBindCol". Jika alamat terikat adalah 0, tidak ada nilai data yang dikembalikan, meskipun alamat yang dihitung oleh rumus sebelumnya tidak nol. |
| Binding Offset | Jika pengikatan baris digunakan, nilai yang disimpan pada alamat yang ditentukan dengan atribut pernyataan SQL_ATTR_ROW_BIND_OFFSET_PTR. Jika binding per kolom digunakan atau jika nilai atribut pernyataan SQL_ATTR_ROW_BIND_OFFSET_PTR adalah null pointer, Binding Offset adalah 0. |
| Nomor Baris | Nomor baris berbasis 1 dalam rowset. Untuk pengambilan baris tunggal, yang merupakan default, ini adalah 1. |
| Ukuran Elemen | Ukuran elemen dalam array terikat. Jika binding kolom digunakan, ini adalah sizeof(SQLINTEGER) untuk buffer panjang/indikator. Untuk buffer data, ini adalah nilai argumen BufferLength dalam SQLBindCol jika tipe data memiliki panjang variabel, dan ukuran tipe data jika tipe data tersebut memiliki panjang tetap. Jika binding baris 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.
Caution
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 tersebut 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:
Memanggil SQLGetStmtAttr untuk mendapatkan handle ARD.
Memanggil SQLGetDescField untuk mendapatkan field SQL_DESC_COUNT dari deskriptor ini, dan jika nilai dalam argumen ColumnNumber melebihi nilai SQL_DESC_COUNT, memanggil SQLSetDescField untuk meningkatkan nilai SQL_DESC_COUNT ke ColumnNumber.
Memanggil SQLSetDescField beberapa kali untuk menetapkan nilai ke field berikut dari ARD:
Mengatur SQL_DESC_TYPE dan SQL_DESC_CONCISE_TYPE ke nilai TargetType, kecuali jika TargetType adalah salah satu pengenal ringkas dari subtipe datetime atau interval, ia menetapkan SQL_DESC_TYPE menjadi SQL_DATETIME atau SQL_INTERVAL, masing-masing; mengatur SQL_DESC_CONCISE_TYPE ke pengenal ringkas; dan mengatur SQL_DESC_DATETIME_INTERVAL_CODE ke subkode datetime atau interval yang sesuai.
Mengatur satu atau lebih SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE, dan SQL_DESC_DATETIME_INTERVAL_PRECISION, sesuai dengan 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 oleh argumen StrLen_or_IndPtr digunakan untuk informasi indikator dan panjang. Jika sebuah fetch menemukan nilai null untuk kolom tersebut, maka SQL_NULL_DATA disimpan dalam variabel ini; jika tidak, ia menyimpan panjang data dalam variabel ini. Mengirim pointer null sebagai StrLen_or_IndPtr mencegah operasi pengambilan data mengembalikan panjang data tetapi membuat pengambilan gagal jika menemukan nilai null dan tidak memiliki cara untuk mengembalikan SQL_NULL_DATA.
Jika pemanggilan ke SQLBindCol gagal, isi field deskriptor yang seharusnya diatur di ARD tidak terdefinisi dan nilai field SQL_DESC_COUNT ARD tidak berubah.
Reset Implisit Field 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 pointer null dan nilai dalam argumen ColumnNumber sama dengan SQL_DESC_COUNT (yaitu, saat membuka binding pada kolom tertinggi), maka SQL_DESC_COUNT diatur ke nomor kolom terbatas tertinggi yang tersisa.
Peringatan Terkait SQL_DEFAULT
Untuk mengambil data kolom dengan sukses, aplikasi harus menentukan dengan benar panjang dan titik awal data di buffer aplikasi. Ketika aplikasi menentukan TargetType eksplisit, kesalahpahaman aplikasi mudah terdeteksi. Namun, ketika aplikasi menentukan TargetType dari SQL_DEFAULT, SQLBindCol dapat diterapkan pada kolom dengan tipe data berbeda dari yang diinginkan aplikasi, baik dari perubahan metadata atau dengan menerapkan kode ke kolom lain. Dalam kasus ini, aplikasi mungkin tidak selalu menentukan awal atau panjang data kolom yang diambil. Hal ini dapat menyebabkan kesalahan data yang tidak dilaporkan atau pelanggaran memori.
Contoh Kode
Dalam contoh berikut, sebuah aplikasi menjalankan pernyataan SELECT pada tabel Customers untuk mengembalikan set hasil ID pelanggan, nama, dan nomor telepon, yang diurutkan berdasarkan nama. Kemudian memanggil SQLBindCol untuk mengikat kolom data ke buffer lokal. Terakhir, aplikasi mengambil setiap baris data dengan SQLFetch dan mencetak nama, ID, serta nomor telepon setiap pelanggan.
Untuk contoh kode lainnya, lihat SQLBulkOperations Function, SQLColumns Function, SQLFetchScroll Function, dan SQLSetPos Function.
// 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, Program ODBC Contoh.
Fungsi Terkait
| Untuk informasi mengenai | 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 |
| Melepaskan buffer kolom pada pernyataan | Fungsi SQLFreeStmt |
| Mengambil bagian atau semua kolom data | Fungsi SQLGetData |
| Mengembalikan jumlah kolom set hasil | Fungsi SQLNumResultCols |