Struktur SSVARIANT
Berlaku untuk: SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics Analytics
Platform System (PDW)
Struktur SSVARIANT , yang didefinisikan dalam msoledbsql.h, sesuai dengan nilai DBTYPE_SQLVARIANT di Driver OLE DB untuk SQL Server.
SSVARIANT adalah serikat yang diskriminatif. Tergantung pada nilai anggota vt, konsumen dapat menentukan anggota mana yang akan dibaca. Nilai vt sesuai dengan jenis data SQL Server. Oleh karena itu, struktur SSVARIANT dapat menampung jenis SQL Server apa pun. Untuk informasi selengkapnya tentang struktur data untuk jenis OLE DB standar, lihat Indikator Tipe.
Keterangan
Ketika DataTypeCompat==80, beberapa subjenis SSVARIANT menjadi string. Misalnya, nilai vt berikut akan muncul di SSVARIANT sebagai VT_SS_WVARSTRING:
VT_SS_DATETIMEOFFSET
VT_SS_DATETIME2
VT_SS_TIME2
VT_SS_DATE
Ketika DateTypeCompat == 0, jenis ini akan muncul dalam bentuk aslinya.
Untuk informasi selengkapnya tentang SSPROP_INIT_DATATYPECOMPATIBILITY, lihat Menggunakan Kata Kunci String Koneksi dengan Driver OLE DB untuk SQL Server.
File msoledbsql.h berisi makro akses varian yang menyederhanakan dereferensi jenis anggota dalam struktur SSVARIANT . Contohnya adalah V_SS_DATETIMEOFFSET, yang dapat Anda gunakan sebagai berikut:
memcpy(&V_SS_DATETIMEOFFSET(pssVar).tsoDateTimeOffsetVal, pDTO, cbNative);
V_SS_DATETIMEOFFSET(pssVar).bScale = bScale;
Untuk kumpulan lengkap makro akses untuk setiap anggota struktur SSVARIANT , lihat file msoledbsql.h.
Tabel berikut ini menjelaskan anggota struktur SSVARIANT :
Anggota | Indikator tipe OLE DB | Tipe data OLE DB C | nilai vt | Komentar |
---|---|---|---|---|
Vt | SSVARTYPE | Menentukan jenis nilai yang terkandung dalam struct SSVARIANT . | ||
bTinyIntVal | DBTYPE_UI1 | BYTE | VT_SS_UI1 | Mendukung jenis data SQL Server yang kecil. |
sShortIntVal | DBTYPE_I2 | PENDEK | VT_SS_I2 | Mendukung jenis data SmallintSQL Server. |
lIntVal | DBTYPE_I4 | LONG | VT_SS_I4 | Mendukung jenis data SQL Server int. |
llBigIntVal | DBTYPE_I8 | LARGE_INTEGER | VT_SS_I8 | Mendukung jenis data BigintSQL Server. |
fltRealVal | DBTYPE_R4 | float | VT_SS_R4 | Mendukung jenis data SQL Server nyata. |
dblFloatVal | DBTYPE_R8 | dobel | VT_SS_R8 | Mendukung jenis data FloatSQL Server. |
cyMoneyVal | DBTYPE_CY | LARGE_INTEGER | VT_SS_MONEY VT_SS_SMALLMONEY | Mendukung uang dan jenis data SmallmoneySQL Server. |
fBitVal | DBTYPE_BOOL | VARIANT_BOOL | VT_SS_BIT | Mendukung jenis data SQL Server bit. |
rgbGuidVal | DBTYPE_GUID | GUID | VT_SS_GUID | Mendukung jenis data SQL Server uniqueidentifier. |
numNumericVal | DBTYPE_NUMERIC | DB_NUMERIC | VT_SS_NUMERIC | Mendukung jenis data SQL Server numerik. |
dDateVal | DBTYPE_DATE | DBDATE | VT_SS_DATE | Mendukung jenis data SQL Server tanggal. |
tsDateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_SMALLDATETIME VT_SS_DATETIME VT_SS_DATETIME2 | Mendukung jenis data smalldatetime, datetime, dan datetime2SQL Server. |
Time2Val | DBTYPE_DBTIME2 | DBTIME2 | VT_SS_TIME2 | Mendukung waktujenis data SQL Server. Termasuk anggota berikut: tTime2Val (DBTIME2) bScale (BYTE) Menentukan skala untuk nilai tTime2Val . |
DateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_DATETIME2 | Mendukung jenis data datetime2SQL Server. Termasuk anggota berikut: tsDataTimeVal (DBTIMESTAMP) bScale (BYTE) Menentukan skala untuk nilai tsDataTimeVal . |
DateTimeOffsetVal | DBTYPE_DBTIMESTAMPOFSET | DBTIMESTAMPOFFSET | VT_SS_DATETIMEOFFSET | Mendukung jenis data datetimeoffsetSQL Server. Termasuk anggota berikut: tsoDateTimeOffsetVal (DBTIMESTAMPOFFSET) bScale (BYTE) Menentukan skala untuk nilai tsoDateTimeOffsetVal . |
NCharVal | Tidak ada indikator jenis OLE DB yang sesuai. | _NCharVal struktur | VT_SS_WVARSTRING, VT_SS_WSTRING |
Mendukung jenis data nchar dan nvarcharSQL Server. Termasuk anggota berikut: sActualLength (SHORT) Menentukan panjang aktual untuk string tempat titik pwchNCharVal . Tidak termasuk mengakhiri nol. sMaxLength (SHORT) Menentukan panjang maksimum untuk string tempat titik pwchNCharVal . pwchNCharVal (WCHAR *) Pointer ke string. rgbReserved (BYTE[5]) Menentukan informasi kolab. Anggota yang tidak digunakan: dwReserved, dan pwchReserved. |
CharVal | Tidak ada indikator jenis OLE DB yang sesuai. | _CharVal struktur | VT_SS_STRING, VT_SS_VARSTRING |
Mendukung jenis data char dan varcharSQL Server. Termasuk anggota berikut: sActualLength (SHORT) Menentukan panjang aktual untuk string tempat titik pchCharVal . Tidak termasuk mengakhiri nol. sMaxLength (SHORT) Menentukan panjang maksimum untuk string tempat titik pchCharVal . pchCharVal (CHAR *) Pointer ke string. rgbReserved (BYTE[5]) Menentukan informasi kolab. Anggota yang tidak digunakan: dwReserved, dan pwchReserved. |
BinaryVal | Tidak ada indikator jenis OLE DB yang sesuai. | _BinaryVal struktur | VT_SS_VARBINARY, VT_SS_BINARY |
Mendukung jenis data SQL Server biner dan varbinary. Termasuk anggota berikut: sActualLength (SHORT) Menentukan panjang aktual untuk data yang titik prgbBinaryVal . sMaxLength (SHORT) Menentukan panjang maksimum untuk data yang titik prgbBinaryVal . prgbBinaryVal (BYTE *) Pointer ke data biner. Anggota yang tidak digunakan: dwReserved. |
UnknownType | TIDAK TERPAKAI | TIDAK TERPAKAI | TIDAK TERPAKAI | TIDAK TERPAKAI |
BLOBType | TIDAK TERPAKAI | TIDAK TERPAKAI | TIDAK TERPAKAI | TIDAK TERPAKAI |
Masalah umum
Kemungkinan kerusakan data string sempit
Sebelum driver OLE DB versi 18.4, penyisipan ke dalam sql_variant
kolom dapat mengakibatkan kerusakan data di server jika semua kondisi berikut ini benar:
- Halaman kode komputer klien tidak cocok dengan halaman kode kolab database.
- Buffer klien untuk menyisipkan karakter string sempit non-ASCII yang dikodekan di halaman kode klien.
- Salah satu kondisi berikut benar:
Bidang
pwszDataSourceType
dalam struktur yangDBPARAMBINDINFO
menjelaskan parameter yang sesuai dengansql_variant
kolom diatur keL"DBTYPE_SQLVARIANT"
,L"DBTYPE_VARIANT"
, atauL"sql_variant"
. Untuk detailnya, lihat: ICommandWithParameters::SetParameterInfo.atau
Kueri SQL berparameter yang digunakan untuk penyisipan telah disiapkan.
Lebih khusus lagi, driver OLE DB tidak menerjemahkan data ke halaman kode kolasis database sebelum menyisipkannya. Namun, driver salah menunjukkan ke server bahwa data dikodekan di halaman kode kolase database. Perilaku ini mengakibatkan ketidakcocokan antara data dan halaman kode terkait yang disimpan di sql_variant
kolom.
Demikian pula, setelah pengambilan nilai yang sama, driver OLE DB tidak menerjemahkan string ke halaman kode klien. Namun, karena data yang disisipkan sudah ada di halaman kode klien (lihat paragraf di atas), aplikasi klien dapat menginterpretasikan data dengan benar. Meskipun demikian, aplikasi yang menggunakan driver lain akan mengambil nilai-nilai ini dalam format yang rusak. Kerusakan terjadi karena driver lain menafsirkan string di halaman kode kolase database dan mencoba menerjemahkannya ke halaman kode klien.
Mulai dari versi 18.4, Driver OLE DB menerjemahkan string sempit ke halaman kode kolase database sebelum penyisipan. Demikian pula, driver menerjemahkan data kembali ke halaman kode klien setelah pengambilan. Akibatnya, aplikasi klien yang mengandalkan bug yang disebutkan di atas mungkin mengalami masalah saat mengambil data yang dimasukkan menggunakan versi Driver OLE DB sebelumnya. Prosedur pemulihan di bawah ini bertujuan untuk memberikan panduan untuk menyelesaikan masalah ini.
Prosedur pemulihan
Penting
Sebelum melakukan langkah-langkah pemulihan di bawah ini, pastikan untuk mencadangkan data yang sudah ada.
Jika aplikasi Anda mengalami masalah saat mengambil data dari sql_variant
kolom setelah beralih ke driver OLE DB versi 18.4, data yang rusak perlu dimodifikasi untuk memiliki kolase yang sama dengan database tempat data disimpan. Skrip berikut dapat digunakan untuk memulihkan satu nilai dari sql_variant
kolom. Skrip adalah templat dan Anda perlu menyesuaikannya agar sesuai dengan skenario Anda.
Penting
Karena halaman kode asli data tidak disimpan, Anda perlu memberi tahu server bagaimana data awalnya dikodekan. Untuk melakukannya, jalankan skrip dalam konteks database yang memiliki halaman kode yang sama dengan halaman kode klien yang awalnya menyisipkan data. Misalnya, jika data yang rusak dimasukkan dari klien yang dikonfigurasi dengan halaman 932
kode , skrip berikut perlu dijalankan dalam konteks database dengan kolase Jepang (misalnya Japanese_XJIS_100_CS_AI
).
/*
Description:
Template that can be used to recover the corrupted value inserted into the sql_variant column.
Scenario:
The database is named [YourDatabase] and it contains a table named [YourTable], which contains the corrupted value.
Schema is named [dbo].
The corrupted value is stored in a column of type sql_variant named [YourColumn].
The corrupted value is sql_variant of BaseType char. For details on sql_variant properties, see:
https://learn.microsoft.com/sql/t-sql/functions/sql-variant-property-transact-sql
*/
-- Base type in sql_variant can hold a maximum of 8000 bytes
-- For details see:
-- https://learn.microsoft.com/sql/t-sql/data-types/sql-variant-transact-sql#remarks
DECLARE @bin VARBINARY(8000)
-- In the following lines we convert the sql_variant base type to binary.
-- <FilterExpression>
-- Is a placeholder and must be replaced with an expression that filters a single corrupted value to be recovered.
-- Therefore, the expression must result in a single value being returned only.
SET @bin = (SELECT CAST([YourColumn] AS VARBINARY(8000)) FROM [YourDatabase].[dbo].[YourTable] WHERE <FilterExpression>)
-- In the following lines we store the binary value in char(59) (a fixed-size character data type).
-- IMPORTANT NOTE:
-- This example assumes the corrupted sql_variant's base type is char(59).
-- You MUST adjust the type (that is, char/varchar) and size to match your scenario exactly.
DECLARE @char CHAR(59)
SET @char = CAST((@bin) AS CHAR(59))
DECLARE @sqlvariant sql_variant
-- The following lines recover the corrupted value by translating the value to the collation of the database.
-- <DBCollation>
-- Must be replaced with the collation (for example, Latin1_General_100_CI_AS_SC_UTF8) of the database holding the data.
SET @sqlvariant = @char collate <DBCollation>
-- Finally, we update the corrupted value with the recovered value.
-- "<FilterExpression>"
-- Is a placeholder and must be replaced with an expression that filters a single corrupted value to be recovered.
-- Therefore, the expression must result in a single value being returned only.
UPDATE [YourDatabase].[dbo].[YourTable] SET [YourColumn] = @sqlvariant WHERE <FilterExpression>
Lihat Juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk