Pengikatan dan Transfer Data Parameter Table-Valued dan Nilai Kolom

Berlaku untuk: SQL Server Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)

Parameter bernilai tabel (TVP), seperti parameter lain, harus terikat sebelum diteruskan ke server. Aplikasi ini mengikat parameter bernilai tabel dengan cara yang sama seperti mengikat parameter lain: menggunakan SQLBindParameter atau panggilan yang setara ke SQLSetDescField atau SQLSetDescRec. Jenis data server untuk parameter bernilai tabel SQL_SS_TABLE. Jenis C dapat ditentukan baik sebagai SQL_C_DEFAULT atau SQL_C_BINARY.

Di SQL Server 2008 (10.0.x) atau yang lebih baru, hanya parameter bernilai tabel input yang didukung. Oleh karena itu, setiap upaya untuk mengatur SQL_DESC_PARAMETER_TYPE ke nilai selain SQL_PARAM_INPUT mengembalikan SQL_ERROR dengan SQLSTATE = HY105 dan pesan "Jenis parameter tidak valid".

Seluruh kolom parameter bernilai tabel dapat ditetapkan nilai default dengan menggunakan atribut SQL_CA_SS_COL_HAS_DEFAULT_VALUE. Namun, nilai kolom parameter bernilai tabel individual tidak dapat ditetapkan nilai default dengan menggunakan SQL_DEFAULT_PARAM di StrLen_or_IndPtr dengan SQLBindParameter. Parameter bernilai tabel secara keseluruhan tidak dapat diatur ke nilai default dengan menggunakan SQL_DEFAULT_PARAM di StrLen_or_IndPtr dengan SQLBindParameter. Jika aturan ini tidak diikuti, SQLExecute atau SQLExecDirect mengembalikan SQL_ERROR. Rekaman diagnostik dihasilkan dengan SQLSTATE=07S01 dan pesan "Penggunaan parameter default tidak valid untuk parameter <p>," di mana <p> adalah ordinal TVP dalam pernyataan kueri.

Catatan

Parameter bernilai tabel tidak memiliki nilai default yang dapat diatur, karena SQL_DEFAULT_PARAM menunjukkan tidak ada baris. Jadi, jika tidak ada baris, tidak ada kolom yang akan diikat.

Setelah mengikat parameter bernilai tabel, aplikasi kemudian harus mengikat setiap kolom parameter bernilai tabel. Untuk melakukan ini, aplikasi pertama-tama memanggil SQLSetStmtAttr untuk mengatur SQL_SOPT_SS_PARAM_FOCUS ke ordinal parameter bernilai tabel. Aplikasi mengikat kolom parameter bernilai tabel dengan panggilan ke rutinitas berikut: SQLBindParameter, SQLSetDescRec, dan SQLSetDescField. Mengatur SQL_SOPT_SS_PARAM_FOCUS ke 0 memulihkan efek SQLBindParameter, SQLSetDescRec, dan SQLSetDescField yang beroperasi pada parameter tingkat atas reguler.

Catatan

Untuk driver ODBC Linux dan Mac dengan unixODBC 2.3.1 ke 2.3.4, saat mengatur nama TVP melalui SQLSetDescField dengan bidang deskriptor SQL_CA_SS_TYPE_NAME, unixODBC tidak secara otomatis mengonversi antara string ANSI dan Unicode tergantung pada fungsi yang tepat yang disebut (SQLSetDescFieldA / SQLSetDescFieldW). Anda harus selalu menggunakan SQLBindParameter atau SQLSetDescFieldW dengan string Unicode (UTF-16) untuk mengatur nama TVP.

Tidak ada data aktual yang dikirim atau diterima untuk parameter bernilai tabel itu sendiri, tetapi data dikirim dan diterima untuk setiap kolom konstituennya. Karena parameter bernilai tabel adalah kolom semu, parameter untuk SQLBindParameter mengacu pada atribut yang berbeda dari jenis data lainnya, sebagai berikut:

Parameter Atribut terkait untuk jenis parameter non-nilai tabel, termasuk kolom Atribut terkait untuk parameter bernilai tabel
InputOutputType SQL_DESC_PARAMETER_TYPE di IPD.

Untuk kolom parameter bernilai tabel, ini harus sama dengan pengaturan untuk parameter bernilai tabel itu sendiri.
SQL_DESC_PARAMETER_TYPE di IPD.

Ini harus SQL_PARAM_INPUT.
ValueType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE di APD. SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE di APD.

Ini harus SQL_C_DEFAULT atau SQL_C_BINARY.
ParameterType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE di IPD. SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE di IPD.

Ini harus SQL_SS_TABLE.
Ukuran Kolom SQL_DESC_LENGTH atau SQL_DESC_PRECISION di IPD.

Ini tergantung pada nilai ParameterType.
SQL_DESC_ARRAY_SIZE

Dapat juga diatur menggunakan SQL_ATTR_PARAM_SET_SIZE saat fokus parameter diatur ke parameter bernilai tabel.

Untuk parameter bernilai tabel, ini adalah jumlah baris dalam buffer kolom parameter bernilai tabel.
DesimalDigits SQL_DESC_PRECISION atau SQL_DESC_SCALE di IPD. Tidak digunakan. Ini harus 0.

Jika parameter ini bukan 0, SQLBindParameter mengembalikan SQL_ERROR, dan rekaman diagnostik dihasilkan dengan SQLSTATE= HY104 dan pesan "Presisi atau skala tidak valid".
ParameterValuePtr SQL_DESC_DATA_PTR di APD. SQL_CA_SS_TYPE_NAME.

Ini opsional untuk panggilan prosedur tersimpan, dan NULL dapat ditentukan jika tidak diperlukan. Ini harus ditentukan untuk pernyataan SQL yang bukan panggilan prosedur.

Parameter ini juga berfungsi sebagai nilai unik yang dapat digunakan aplikasi untuk mengidentifikasi parameter bernilai tabel ini saat pengikatan baris variabel digunakan. Untuk informasi selengkapnya, lihat bagian "Variabel Table-Valued Pengikatan Baris Parameter", nanti dalam topik ini.

Ketika nama jenis parameter bernilai tabel ditentukan pada panggilan ke SQLBindParameter, nama tersebut harus ditentukan sebagai nilai Unicode, bahkan dalam aplikasi yang dibangun sebagai aplikasi ANSI. Nilai yang digunakan untuk parameter StrLen_or_IndPtr harus SQL_NTS atau panjang string nama dikalikan dengan ukuran (WCHAR).
BufferLength SQL_DESC_OCTET_LENGTH di APD. Panjang nama jenis parameter bernilai tabel dalam byte.

Ini dapat SQL_NTS jika nama jenis dihentikan null, atau 0 jika nama jenis parameter bernilai tabel tidak diperlukan.
StrLen_or_IndPtr SQL_DESC_OCTET_LENGTH_PTR di APD. SQL_DESC_OCTET_LENGTH_PTR di APD.

Untuk parameter bernilai tabel, ini adalah jumlah baris daripada panjang data.

Dua mode transfer data didukung untuk parameter bernilai tabel: pengikatan baris tetap dan pengikatan baris variabel.

Memperbaiki Pengikatan Baris Parameter Table-Valued

Untuk pengikatan baris tetap, aplikasi mengalokasikan buffer (atau array buffer) yang cukup besar untuk semua kemungkinan nilai kolom input. Aplikasi melakukan hal berikut:

  1. Mengikat semua parameter dengan menggunakan panggilan SQLBindParameter, SQLSetDescRec, atau SQLSetDescField.

    1. Mengatur SQL_DESC_ARRAY_SIZE ke jumlah maksimum baris yang dapat ditransfer untuk setiap parameter bernilai tabel. Ini dapat dilakukan dalam panggilan SQLBindParameter.
  2. Memanggil SQLSetStmtAttr untuk mengatur SQL_SOPT_SS_PARAM_FOCUS ke ordinal setiap parameter bernilai tabel.

    1. Untuk setiap parameter bernilai tabel, mengikat kolom parameter bernilai tabel dengan menggunakan panggilan SQLBindParameter, SQLSetDescRec, atau SQLSetDescField.

    2. Untuk setiap kolom parameter bernilai tabel yang memiliki nilai default, memanggil SQLSetDescField untuk mengatur SQL_CA_SS_COL_HAS_DEFAULT_VALUE ke 1.

  3. Memanggil SQLSetStmtAttr untuk mengatur SQL_SOPT_SS_PARAM_FOCUS ke 0. Ini harus dilakukan sebelum SQLExecute atau SQLExecDirect dipanggil. Jika tidak, SQL_ERROR dikembalikan, dan rekaman diagnostik dihasilkan dengan SQLSTATE=HY024 dan pesan "Nilai atribut tidak valid, SQL_SOPT_SS_PARAM_FOCUS (harus nol pada waktu eksekusi)."

  4. Mengatur StrLen_or_IndPtr atau SQL_DESC_OCTET_LENGTH_PTR ke SQL_DEFAULT_PARAM untuk parameter bernilai tabel tanpa baris, atau jumlah baris yang akan ditransfer pada panggilan berikutnya dari SQLExecute atau SQLExecDirect jika parameter bernilai tabel memiliki baris. StrLen_or_IndPtr atau SQL_DESC_OCTET_LENGTH_PTR tidak dapat diatur ke SQL_NULL_DATA untuk parameter bernilai tabel karena parameter bernilai tabel tidak dapat diubah ke null (meskipun kolom konstituen parameter bernilai tabel mungkin dapat diubah ke null). Jika ini diatur ke nilai yang tidak valid, SQLExecute atau SQLExecDirect mengembalikan SQL_ERROR, dan rekaman diagnostik dihasilkan dengan SQLSTATE=HY090 dan pesan "String tidak valid atau panjang buffer untuk parameter <p>," di mana p adalah nomor parameter.

  5. Memanggil SQLExecute atau SQLExecDirect.

    Nilai kolom parameter bernilai tabel input dapat diteruskan dalam potongan-potongan jika StrLen_or_IndPtr diatur ke SQL_LEN_DATA_AT_EXEC(panjang) atau SQL_DATA_AT_EXEC untuk kolom. Ini mirip dengan meneruskan nilai dalam potongan-potongan ketika array parameter digunakan. Seperti semua parameter data-at-execution, SQLParamData tidak menunjukkan baris array mana yang dimintai data oleh driver; aplikasi harus mengurus ini. Aplikasi tidak dapat membuat asumsi tentang urutan di mana driver meminta nilai.

Pengikatan Baris Parameter Table-Valued Variabel

Untuk pengikatan baris variabel, baris ditransfer dalam batch pada waktu eksekusi, dan aplikasi meneruskan baris ke driver sesuai permintaan. Ini mirip dengan data yang sedang dieksekusi untuk nilai parameter individual. Untuk pengikatan baris variabel, aplikasi melakukan hal berikut:

  1. Mengikat parameter dan kolom parameter bernilai tabel, seperti yang dijelaskan dalam langkah 1 hingga 3 dari bagian sebelumnya, "Tetap Table-Valued Pengikatan Baris Parameter."

  2. Mengatur StrLen_or_IndPtr atau SQL_DESC_OCTET_LENGTH_PTR untuk parameter bernilai tabel apa pun yang akan diteruskan pada waktu eksekusi ke SQL_DATA_AT_EXEC. Jika tidak diatur, parameter diproses seperti yang dijelaskan di bagian sebelumnya.

  3. Memanggil SQLExecute atau SQLExecDirect. Ini mengembalikan SQL_NEED_DATA jika ada parameter SQL_PARAM_INPUT atau SQL_PARAM_INPUT_OUTPUT yang akan ditangani sebagai parameter data-at-execution. Dalam hal ini, aplikasi melakukan hal berikut:

    • Memanggil SQLParamData. Ini mengembalikan nilai ParameterValuePtr untuk parameter data-at-execution dan kode pengembalian SQL_NEED_DATA. Ketika semua data parameter telah diteruskan ke driver, SQLParamData mengembalikan SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, atau SQL_ERROR. Untuk parameter data saat eksekusi, ParameterValuePtr, yang sama dengan bidang deskriptor SQL_DESC_DATA_PTR, dapat dianggap sebagai token untuk mengidentifikasi parameter yang nilainya diperlukan secara unik. "Token" ini diteruskan dari aplikasi ke driver pada waktu pengikatan, lalu diteruskan kembali ke aplikasi pada waktu eksekusi.
  4. Untuk mengirim data baris parameter bernilai tabel untuk parameter bernilai tabel null, jika parameter bernilai tabel tidak memiliki baris, aplikasi memanggil SQLPutData dengan StrLen_or_Ind diatur ke SQL_DEFAULT_PARAM.

    Untuk TVP non-NULL, aplikasi:

    • Mengatur Str_Len_or_Ind untuk semua kolom parameter bernilai tabel ke nilai yang sesuai, dan mengisi buffer data untuk kolom parameter bernilai tabel yang tidak menjadi parameter data-at-execution. Anda dapat menggunakan data saat dieksekusi untuk kolom parameter bernilai tabel dengan cara yang sama seperti parameter biasa yang dapat diteruskan ke driver dalam potongan-potongan.

    • Memanggil SQLPutData dengan Str_Len_or_Ind diatur ke jumlah baris yang akan dikirim ke server. Nilai apa pun di luar rentang 0 hingga SQL_DESC_ARRAY_SIZE atau SQL_DEFAULT_PARAM adalah kesalahan, dan mengembalikan SQLSTATE HY090, dengan pesan "String tidak valid atau panjang buffer." 0 menunjukkan bahwa semua baris telah dikirim, dan tidak ada lagi data untuk parameter bernilai tabel (seperti yang dicatat dalam item poin kedua dalam daftar ini). SQL_DEFAULT_PARAM hanya dapat digunakan pertama kali driver meminta data untuk parameter bernilai tabel (seperti yang dijelaskan dalam item poin pertama dalam daftar ini).

  5. Ketika semua baris telah dikirim, panggil SQLPutData untuk parameter bernilai tabel dengan nilai Str_Len_or_Ind 0, lalu lanjutkan ke langkah 3a di atas.

  6. Memanggil SQLParamData lagi. Jika ada parameter data-at-execution di antara kolom parameter bernilai tabel, ini diidentifikasi oleh nilai ValuePtrPtr yang dikembalikan oleh SQLParamData. Saat semua nilai kolom tersedia, SQLParamData mengembalikan nilai ParameterValuePtr untuk parameter bernilai tabel, dan aplikasi dimulai lagi.

Langkah berikutnya

Parameter Bernilai Tabel ODBC