Struttura SSVARIANT
Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics Piattaforma di strumenti analitici (PDW)
La struttura SSVARIANT definita in msoledbsql.h corrisponde a un valore DBTYPE_SQLVARIANT in OLE DB Driver per SQL Server.
SSVARIANT è un'unione discriminante. A seconda del valore del membro vt, il consumer può determinare il membro da leggere. I valori vt corrispondono ai tipi di dati di SQL Server. Pertanto, la struttura SSVARIANT può contenere qualsiasi tipo SQL Server. Per altre informazioni sulla struttura dei dati per i tipi di OLE DB standard, vedere Indicatori di tipo.
Osservazioni:
Quando DataTypeCompat==80, diversi sottotipi di SSVARIANT diventano stringhe. I valori vt seguenti verranno ad esempio visualizzati in SSVARIANT come VT_SS_WVARSTRING:
VT_SS_DATETIMEOFFSET
VT_SS_DATETIME2
VT_SS_TIME2
VT_SS_DATE
Quando DateTypeCompat == 0, questi tipi vengono visualizzati nel formato nativo.
Per altre informazioni su SSPROP_INIT_DATATYPECOMPATIBILITY, vedere Uso delle parole chiave delle stringhe di connessione con OLE DB Driver per SQL Server.
Il file msoledbsql.h contiene macro di accesso di tipo Variant che semplificano la risoluzione dei riferimenti ai tipi di membri nella struttura SSVARIANT. Un esempio è rappresentato da V_SS_DATETIMEOFFSET, che è possibile utilizzare come indicato di seguito:
memcpy(&V_SS_DATETIMEOFFSET(pssVar).tsoDateTimeOffsetVal, pDTO, cbNative);
V_SS_DATETIMEOFFSET(pssVar).bScale = bScale;
Per il set completo di macro di accesso per ogni membro della struttura SSVARIANT, fare riferimento al file msoledbsql.h.
Nella tabella seguente vengono descritti i membri della struttura SSVARIANT:
Membro | Indicatore del tipo OLE DB | Tipo di dati C di OLE DB | valore vt | Commenti |
---|---|---|---|---|
vt | SSVARTYPE | Specifica il tipo di valore contenuto nella struttura SSVARIANT. | ||
bTinyIntVal | DBTYPE_UI1 | BYTE | VT_SS_UI1 | Supporta il tipo di dati tinyint di SQL Server. |
sShortIntVal | DBTYPE_I2 | SHORT | VT_SS_I2 | Supporta il tipo di dati smallint di SQL Server. |
lIntVal | DBTYPE_I4 | LONG | VT_SS_I4 | Supporta il tipo di dati int di SQL Server. |
llBigIntVal | DBTYPE_I8 | LARGE_INTEGER | VT_SS_I8 | Supporta il tipo di dati bigint di SQL Server. |
fltRealVal | DBTYPE_R4 | float | VT_SS_R4 | Supporta il tipo di dati real di SQL Server. |
dblFloatVal | DBTYPE_R8 | double | VT_SS_R8 | Supporta il tipo di dati float di SQL Server. |
cyMoneyVal | DBTYPE_CY | LARGE_INTEGER | VT_SS_MONEY VT_SS_SMALLMONEY | Supporta i tipi di dati money e smallmoney di SQL Server. |
fBitVal | DBTYPE_BOOL | VARIANT_BOOL | VT_SS_BIT | Supporta il tipo di dati bit di SQL Server. |
rgbGuidVal | DBTYPE_GUID | GUID | VT_SS_GUID | Supporta il tipo di dati uniqueidentifier di SQL Server. |
numNumericVal | DBTYPE_NUMERIC | DB_NUMERIC | VT_SS_NUMERIC | Supporta il tipo di dati numeric di SQL Server. |
dDateVal | DBTYPE_DATE | DBDATE | VT_SS_DATE | Supporta il tipo di dati date di SQL Server. |
tsDateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_SMALLDATETIME VT_SS_DATETIME VT_SS_DATETIME2 | Supporta i tipi di dati smalldatetime, datetime e datetime2SQL di SQL Server. |
Time2Val | DBTYPE_DBTIME2 | DBTIME2 | VT_SS_TIME2 | Supporta il tipo di dati time di SQL Server. Include i membri indicati di seguito: tTime2Val (DBTIME2) bScale (BYTE) Specifica la scala per il valore tTime2Val. |
DateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_DATETIME2 | Supporta il tipo di dati datetime2 di SQL Server. Include i membri indicati di seguito: tsDataTimeVal (DBTIMESTAMP) bScale (BYTE) Specifica la scala per il valore tsDataTimeVal. |
DateTimeOffsetVal | DBTYPE_DBTIMESTAMPOFSET | DBTIMESTAMPOFFSET | VT_SS_DATETIMEOFFSET | Supporta il tipo di dati datetimeoffset di SQL Server. Include i membri indicati di seguito: tsoDateTimeOffsetVal (DBTIMESTAMPOFFSET) bScale (BYTE) Specifica la scala per il valore tsoDateTimeOffsetVal. |
NCharVal | Nessun indicatore del tipo OLE DB corrispondente. | struct _NCharVal | VT_SS_WVARSTRING, VT_SS_WSTRING |
Supporta i tipi di dati nchar e nvarchar di SQL Server. Include i membri indicati di seguito: sActualLength (SHORT) Specifica la lunghezza effettiva per la stringa a cui punta pwchNCharVal. Non include lo zero finale. sMaxLength (SHORT) Specifica la lunghezza massima per la stringa a cui punta pwchNCharVal. pwchNCharVal (WCHAR *) Puntatore alla stringa. rgbReserved (BYTE[5]) Specifica le informazioni sulle regole di confronto. Membri non usati: dwReserved e pwchReserved. |
CharVal | Nessun indicatore del tipo OLE DB corrispondente. | struct _CharVal | VT_SS_STRING, VT_SS_VARSTRING |
Supporta i tipi di dati char e varchar di SQL Server. Include i membri indicati di seguito: sActualLength (SHORT) Specifica la lunghezza effettiva per la stringa a cui punta pchCharVal. Non include lo zero finale. sMaxLength (SHORT) Specifica la lunghezza massima per la stringa a cui punta pchCharVal. pchCharVal (CHAR *) Puntatore alla stringa. rgbReserved (BYTE[5]) Specifica le informazioni sulle regole di confronto. Membri non utilizzati: dwReserved e pwchReserved. |
BinaryVal | Nessun indicatore del tipo OLE DB corrispondente. | struct _BinaryVal | VT_SS_VARBINARY, VT_SS_BINARY |
Supporta i tipi di dati binary e varbinary di SQL Server. Include i membri indicati di seguito: sActualLength (SHORT) Specifica la lunghezza effettiva per i dati a cui punta prgbBinaryVal. sMaxLength (SHORT) Specifica la lunghezza massima per i dati a cui punta prgbBinaryVal. prgbBinaryVal (BYTE *) Puntatore ai dati binari. Membro non usato: dwReserved. |
UnknownType | UNUSED | UNUSED | UNUSED | UNUSED |
BLOBType | UNUSED | UNUSED | UNUSED | UNUSED |
Problemi noti
Possibile danneggiamento dei dati della stringa narrow
Prima della versione 18.4 di OLE DB Driver, l'inserimento in una colonna sql_variant
può causare il danneggiamento dei dati nel server se si verificano tutte le condizioni seguenti:
- La tabella codici del computer client non corrisponde alla tabella codici delle regole di confronto del database.
- Il buffer client da inserire contiene caratteri della stringa narrow non ASCII codificati nella tabella codici del client.
- Sono state soddisfatte una delle condizioni seguenti:
Il campo
pwszDataSourceType
nella strutturaDBPARAMBINDINFO
che descrive il parametro corrispondente alla colonnasql_variant
è stato impostato suL"DBTYPE_SQLVARIANT"
,L"DBTYPE_VARIANT"
oL"sql_variant"
. Per informazioni dettagliate, vedere: ICommandWithParameters::SetParameterInfo.or
È stata preparata la query SQL con parametri usata per l'inserimento.
In particolare, OLE DB Driver non ha convertito i dati nella tabella codici delle regole di confronto del database prima di inserirli. Tuttavia, il driver ha indicato erroneamente al server che i dati sono stati codificati nella tabella codici delle regole di confronto del database. Questo comportamento ha causato una mancata corrispondenza tra i dati e la tabella codici corrispondente archiviata nella colonna sql_variant
.
Analogamente, dopo il recupero dello stesso valore, OLE DB Driver non ha convertito le stringhe nella tabella codici del client. Tuttavia, poiché i dati inseriti erano già presenti nella tabella codici del client (vedere il paragrafo precedente), l'applicazione client potrebbe interpretare i dati in modo corretto. Anche in questo caso, le applicazioni che usano altri driver potrebbero recuperare questi valori in un formato danneggiato. Il danneggiamento si verifica perché altri driver hanno interpretato la stringa nella tabella codici delle regole di confronto del database e tentano di convertirla nella tabella codici del client.
A partire dalla versione 18.4, OLE DB Driver converte le stringhe narrow nella tabella codici delle regole di confronto del database prima dell'inserimento. Analogamente, il driver converte di nuovo i dati nella tabella codici del client al momento del recupero. Di conseguenza, le applicazioni client soggette al bug citato in precedenza potrebbero riscontrare problemi durante il recupero dei dati inseriti usando una versione precedente di OLE DB Driver. La procedura di recupero ha lo scopo di fornire indicazioni per la risoluzione di questi problemi.
Procedura di recupero
Importante
Prima di completare la procedura di recupero seguente, assicurarsi di eseguire il backup dei dati esistenti.
Se l'applicazione riscontra problemi durante il recupero dei dati da una colonna sql_variant
dopo il passaggio alla versione 18.4 di OLE DB Driver, è necessario modificare i dati danneggiati in modo da avere le stesse regole di confronto del database in cui sono archiviati i dati. Lo script seguente può essere usato per recuperare un singolo valore da una colonna sql_variant
. Lo script è un modello ed è necessario modificarlo per adattarlo allo scenario.
Importante
Poiché la tabella codici originale dei dati non viene archiviata, è necessario indicare al server il modo in cui sono stati inizialmente codificati i dati. A questo scopo, eseguire lo script nel contesto di un database che include la stessa tabella codici della tabella codici del client che ha inserito inizialmente i dati. Ad esempio, se i dati danneggiati sono stati inseriti da un client configurato con la tabella codici 932
, è necessario eseguire lo script seguente nel contesto di un database con regole di confronto giapponesi, ad esempio 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://zcusa.951200.xyz/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://zcusa.951200.xyz/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>