Udostępnij za pośrednictwem


SSVARIANT, struktura

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

pobierz sterownik OLE DB

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 i małychtypów danych programu SQL Server.
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 danychliczbowych programu SQL Server.
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:

sActualLength (SHORT) Określa rzeczywistą długość ciągu, do którego punktów pwchNCharVal. Nie obejmuje zera zakończenia.

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 strukturze DBPARAMBINDINFO opisujące parametr odpowiadający kolumnie sql_variant został ustawiony na L"DBTYPE_SQLVARIANT", L"DBTYPE_VARIANT"lub L"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>

Zobacz też

typy danych (OLE DB)