SSVARIANT, struktura
Dotyczy:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Struktura SSVARIANT zdefiniowana w pliku msoledbsql.h odpowiada wartości DBTYPE_SQLVARIANT w sterowniku OLE DB dla programu SQL Server.
SSVARIANT jest dyskryminującą związkiem. W zależności od wartości elementu członkowskiego vt użytkownik może określić, który element członkowski ma być odczytywany. Wartości vt odpowiadają typom danych programu SQL Server. W związku z tym struktura SSVARIANT może przechowywać dowolny typ programu SQL Server. Aby uzyskać więcej informacji na temat struktury danych dla standardowych typów OLE DB, zobacz wskaźniki typów .
Uwagi
Gdy dataTypeCompat==80 kilka SSVARIANT stają się ciągami. Na przykład następujące wartości vt będą wyświetlane w SSVARIANT jako VT_SS_WVARSTRING:
VT_SS_DATETIMEOFFSET
VT_SS_DATETIME2
VT_SS_TIME2
VT_SS_DATE
Gdy typ DateTypeCompat == 0, te typy będą wyświetlane w ich natywnej formie.
Aby uzyskać więcej informacji na temat SSPROP_INIT_DATATYPECOMPATIBILITY, zobacz Using Connection String Keywords with OLE DB Driver for SQL Server.
Plik msoledbsql.h zawiera makra dostępu wariantów, które upraszczają wyłuszczanie typów składowych w strukturze SSVARI ANT. Przykładem jest V_SS_DATETIMEOFFSET, którego można użyć w następujący sposób:
memcpy(&V_SS_DATETIMEOFFSET(pssVar).tsoDateTimeOffsetVal, pDTO, cbNative);
V_SS_DATETIMEOFFSET(pssVar).bScale = bScale;
Pełny zestaw makr dostępu dla każdego elementu członkowskiego struktury SSVARIANT można znaleźć w pliku msoledbsql.h.
W poniższej tabeli opisano elementy członkowskie struktury SSVARIANT:
Członek | Wskaźnik typu OLE DB | Typ danych OLE DB C | wartość vt | Komentarze |
---|---|---|---|---|
Vt | SSVARTYPE | Określa typ wartości zawartej w SSVARIANT struktury. | ||
bTinyIntVal | DBTYPE_UI1 | BYTE | VT_SS_UI1 | Obsługuje tinyinttyp danych programu SQL Server. |
sShortIntVal | DBTYPE_I2 | SHORT | VT_SS_I2 | Obsługuje smallinttyp danych programu SQL Server. |
lIntVal | DBTYPE_I4 | DŁUGIE | VT_SS_I4 | Obsługuje inttypu danych programu SQL Server. |
llBigIntVal | DBTYPE_I8 | LARGE_INTEGER | VT_SS_I8 | Obsługuje typ danych bigintSQL Server. |
fltRealVal | DBTYPE_R4 | zmiennoprzecinkowe | VT_SS_R4 | Obsługuje rzeczywisty typ danych programu SQL Server. |
dblFloatVal | DBTYPE_R8 | podwójne | VT_SS_R8 | Obsługuje typ danych zmiennoprzecinkowychprogramu SQL Server. |
cyMoneyVal | DBTYPE_CY | LARGE_INTEGER | VT_SS_MONEY VT_SS_SMALLMONEY | Obsługuje |
fBitVal | DBTYPE_BOOL | VARIANT_BOOL | VT_SS_BIT | Obsługuje bitowy typ danych programu SQL Server. |
rgbGuidVal | DBTYPE_GUID | identyfikator GUID |
VT_SS_GUID | Obsługuje typ danych uniqueidentifierSQL Server. |
numNumericVal | DBTYPE_NUMERIC | DB_NUMERIC | VT_SS_NUMERIC | Obsługuje typ danych |
dDateVal | DBTYPE_DATE | DBDATE | VT_SS_DATE | Obsługuje datę typ danych programu SQL Server. |
tsDateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_SMALLDATETIME VT_SS_DATETIME VT_SS_DATETIME2 | Obsługuje smalldatetime, data/godzinai data/godzina2typów danych programu SQL Server. |
Czas 2wal | DBTYPE_DBTIME2 | DBTIME2 | VT_SS_TIME2 | Obsługuje czastypu danych programu SQL Server. Obejmuje następujące elementy członkowskie: tTime2Val (DBTIME2) bScale (BYTE) określa skalę dla wartości tTime2Val. |
Data/godzina | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_DATETIME2 | Obsługuje typ danych data/godzina2programu SQL Server. Obejmuje następujące elementy członkowskie: tsDateTimeVal (DBTIMESTAMP) bScale (BYTE) określa skalę dla wartości tsDateTimeVal. |
DateTimeOffsetVal | DBTYPE_DBTIMESTAMPOFFSET | DBTIMESTAMPOFFSET |
VT_SS_DATETIMEOFFSET | Obsługuje typ danych datetimeoffsetSQL Server. Obejmuje następujące elementy członkowskie: tsoDateTimeOffsetVal (DBTIMESTAMPOFFSET) bScale (BYTE) Określa skalę dla wartości tsoDateTimeOffsetVal. |
NCharVal | Brak odpowiedniego wskaźnika typu OLE DB. | , struktura _NCharVal |
VT_SS_WVARSTRING, VT_SS_WSTRING |
Obsługuje typy danych nchar i nvarcharSQL Server. Obejmuje następujące elementy członkowskie: sMaxLength (SHORT) Określa maksymalną długość ciągu, do którego punktów pwchNCharVal. pwchNCharVal (WCHAR *) wskaźnik do ciągu. rgbReserved (BYTE[5]) Określa informacje dotyczące sortowania. Nieużywane elementy członkowskie: dwReservedi pwchReserved. |
CharVal | Brak odpowiedniego wskaźnika typu OLE DB. | , struktura _CharVal |
VT_SS_STRING, VT_SS_VARSTRING |
Obsługuje typy danych char i varcharSQL Server. Obejmuje następujące elementy członkowskie: sActualLength (SHORT) Określa rzeczywistą długość ciągu, do którego punktów pchCharVal. Nie obejmuje zera zakończenia. sMaxLength (SHORT) Określa maksymalną długość ciągu, do którego punktów pchCharVal. pchCharVal (CHAR *) wskaźnik do ciągu. rgbReserved (BYTE[5]) Określa informacje dotyczące sortowania. Nieużywane elementy członkowskie: dwReservedi pwchReserved. |
BinaryVal | Brak odpowiedniego wskaźnika typu OLE DB. | , struktura _BinaryVal |
VT_SS_VARBINARY, VT_SS_BINARY |
Obsługuje binarne i typów danych programu SQL Server. Obejmuje następujące elementy członkowskie: sActualLength (SHORT) Określa rzeczywistą długość danych, do których punktów prgbBinaryVal. sMaxLength (SHORT) określa maksymalną długość danych, do których punktów prgbBinaryVal. prgbBinaryVal (BYTE *) Wskaźnik do danych binarnych. Nieużywany element członkowski: dwReserved. |
Nieznany typ | NIEUŻYWANE | NIEUŻYWANE | NIEUŻYWANE | NIEUŻYWANE |
BlOBType | NIEUŻYWANE | NIEUŻYWANE | NIEUŻYWANE | NIEUŻYWANE |
Znane problemy
Możliwe wąskie uszkodzenie danych ciągów
Przed wersją 18.4 sterownika OLE DB wstawienie do kolumny sql_variant
może spowodować uszkodzenie danych na serwerze, jeśli spełnione są wszystkie następujące warunki:
- Strona kodu maszyny klienckiej nie jest zgodna ze stroną kodu sortowania bazy danych.
- Bufor klienta do wstawiania zawiera znaki nie-ASCII wąskie ciągi zakodowane na stronie kodu klienta.
- Spełniony został jeden z następujących warunków:
Pole
pwszDataSourceType
w strukturzeDBPARAMBINDINFO
opisujące parametr odpowiadający kolumniesql_variant
został ustawiony naL"DBTYPE_SQLVARIANT"
,L"DBTYPE_VARIANT"
lubL"sql_variant"
. Aby uzyskać szczegółowe informacje, zobacz: ICommandWithParameters::SetParameterInfo.lub
Przygotowano sparametryzowane zapytanie SQL używane do wstawiania.
Mówiąc dokładniej, sterownik OLE DB nie przetłumaczył danych na stronę kodu sortowania bazy danych przed wstawieniem. Jednak sterownik błędnie wskazał serwerowi, że dane zostały zakodowane na stronie kodu sortowania bazy danych. To zachowanie spowodowało niezgodność między danymi a odpowiednią stroną kodową przechowywaną w kolumnie sql_variant
.
Podobnie po pobraniu tej samej wartości sterownik OLE DB nie przetłumaczył ciągów na stronę kodową klienta. Jednak ponieważ wstawione dane były już na stronie kodu klienta (patrz akapit powyżej), aplikacja kliencka może poprawnie interpretować dane. Mimo to aplikacje korzystające z innych sterowników pobierałyby te wartości w uszkodzonym formacie. Uszkodzenie występuje, ponieważ inne sterowniki interpretowały ciąg na stronie kodu sortowania bazy danych i próbowały przetłumaczyć go na stronę kodową klienta.
Począwszy od wersji 18.4, sterownik OLE DB tłumaczy wąskie ciągi na stronę kodu sortowania bazy danych przed wstawieniem. Podobnie sterownik tłumaczy dane z powrotem na stronę kodu klienta po pobraniu. W związku z tym aplikacje klienckie, które opierają się na usterce wymienionej powyżej, mogą napotkać problemy podczas pobierania danych wstawionych przy użyciu starszej wersji sterownika OLE DB. Poniższa procedura odzyskiwania ma na celu przedstawienie wskazówek dotyczących rozwiązywania tych problemów.
Procedura odzyskiwania
Ważny
Przed wykonaniem poniższych kroków odzyskiwania upewnij się, że wykonasz kopię zapasową istniejących danych.
Jeśli aplikacja napotyka problemy z pobieraniem danych z kolumny sql_variant
po przełączeniu do wersji 18.4 sterownika OLE DB, uszkodzone dane muszą zostać zmodyfikowane, aby miały takie same sortowanie jak baza danych, w której są przechowywane dane. Poniższy skrypt może służyć do odzyskania pojedynczej wartości z kolumny sql_variant
. Skrypt jest szablonem i musisz dostosować go do swojego scenariusza.
Ważny
Ponieważ oryginalna strona kodowa danych nie jest przechowywana, musisz poinformować serwer, jak dane zostały początkowo zakodowane. W tym celu wykonaj skrypt w kontekście bazy danych, która ma tę samą stronę kodową co strona kodowa klienta, który początkowo wstawił dane. Jeśli na przykład uszkodzone dane zostały wstawione z klienta skonfigurowanego przy użyciu strony kodowej 932
, należy wykonać następujący skrypt w kontekście bazy danych z sortowaniem japońskim (np. 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>