Bagikan melalui


Struktur SSVARIANT

Berlaku untuk: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)

Unduh driver OLE DB

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 yang DBPARAMBINDINFO menjelaskan parameter yang sesuai dengan sql_variant kolom diatur ke L"DBTYPE_SQLVARIANT", L"DBTYPE_VARIANT", atau L"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 932kode , 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

Tipe Data (OLE DB)