Structure SSVARIANT
S’applique à :SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
La structure SSVARIANT, qui est définie dans msoledbsql.h correspond à une valeur DBTYPE_SQLVARIANT dans OLE DB Driver pour SQL Server.
SSVARIANT est une union de discrimination. En fonction de la valeur du membre vt, le consommateur peut identifier le membre à lire. Les valeurs de vt correspondent aux types de données SQL Server. Ainsi, la structure SSVARIANT peut contenir n’importe quel type SQL Server. Pour plus d’informations sur la structure de données pour les types OLE DB standard, consultez Indicateurs de type.
Notes
Quand DataTypeCompat==80, plusieurs sous-types SSVARIANT deviennent des chaînes. Par exemple, les valeurs de vt suivantes apparaissent dans SSVARIANT en tant que VT_SS_WVARSTRING :
VT_SS_DATETIMEOFFSET
VT_SS_DATETIME2
VT_SS_TIME2
VT_SS_DATE
Lorsque DateTypeCompat == 0, ces types s'affichent sous leur forme native.
Pour plus d’informations sur SSPROP_INIT_DATATYPECOMPATIBILITY, consultez Utilisation de mots clés de chaîne de connexion avec OLE DB Driver for SQL Server.
Le fichier msoledbsql.h contient des macros d’accès de type Variant qui simplifient le déréférencement des types de membres dans la structure SSVARIANT. Un exemple est V_SS_DATETIMEOFFSET, que vous pouvez utiliser comme suit :
memcpy(&V_SS_DATETIMEOFFSET(pssVar).tsoDateTimeOffsetVal, pDTO, cbNative);
V_SS_DATETIMEOFFSET(pssVar).bScale = bScale;
Pour obtenir le jeu complet de macros d'accès pour chaque membre de la structure SSVARIANT, consultez le fichier msoledbsql.
Le tableau suivant décrit les membres de la structure SSVARIANT :
Membre | Indicateur de type OLE DB | Type de données OLE DB C | Valeur vt | Commentaires |
---|---|---|---|---|
vt | SSVARTYPE | Spécifie le type de valeur contenu dans la structure SSVARIANT. | ||
bTinyIntVal | DBTYPE_UI1 | BYTE | VT_SS_UI1 | Prend en charge le type de données tinyintSQL Server. |
sShortIntVal | DBTYPE_I2 | SHORT | VT_SS_I2 | Prend en charge le type de données smallintSQL Server. |
lIntVal | DBTYPE_I4 | LONG | VT_SS_I4 | Prend en charge le type de données intSQL Server. |
llBigIntVal | DBTYPE_I8 | LARGE_INTEGER | VT_SS_I8 | Prend en charge le type de données bigintSQL Server. |
fltRealVal | DBTYPE_R4 | float | VT_SS_R4 | Prend en charge le type de données realSQL Server. |
dblFloatVal | DBTYPE_R8 | double | VT_SS_R8 | Prend en charge le type de données floatSQL Server. |
cyMoneyVal | DBTYPE_CY | LARGE_INTEGER | VT_SS_MONEY VT_SS_SMALLMONEY | Prend en charge les types de données money et smallmoneySQL Server. |
fBitVal | DBTYPE_BOOL | VARIANT_BOOL | VT_SS_BIT | Prend en charge le type de données bitSQL Server. |
rgbGuidVal | DBTYPE_GUID | GUID | VT_SS_GUID | Prend en charge le type de données uniqueidentifierSQL Server. |
numNumericVal | DBTYPE_NUMERIC | DB_NUMERIC | VT_SS_NUMERIC | Prend en charge le type de données numericSQL Server. |
dDateVal | DBTYPE_DATE | DBDATE | VT_SS_DATE | Prend en charge le type de données dateSQL Server. |
tsDateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_SMALLDATETIME VT_SS_DATETIME VT_SS_DATETIME2 | Prend en charge les types de données smalldatetime, datetime et datetime2SQL Server. |
Time2Val | DBTYPE_DBTIME2 | DBTIME2 | VT_SS_TIME2 | Prend en charge le type de données timeSQL Server. Inclut les membres suivants : tTime2Val (DBTIME2) bScale (BYTE) Spécifie l’échelle pour la valeur tTime2Val. |
DateTimeVal | DBTYPE_DBTIMESTAMP | DBTIMESTAMP | VT_SS_DATETIME2 | Prend en charge le type de données datetime2SQL Server. Inclut les membres suivants : tsDateTimeVal (DBTIMESTAMP) bScale (BYTE) Spécifie la mise à l’échelle pour valeur tsDateTimeVal. |
DateTimeOffsetVal | DBTYPE_DBTIMESTAMPOFFSET | DBTIMESTAMPOFFSET | VT_SS_DATETIMEOFFSET | Prend en charge le type de données datetimeoffsetSQL Server. Inclut les membres suivants : tsoDateTimeOffsetVal (DBTIMESTAMPOFFSET) bScale (BYTE) Spécifie l’échelle pour la valeur tsoDateTimeOffsetVal. |
NCharVal | Aucun indicateur de type OLE DB correspondant. | struct _NCharVal |
VT_SS_WVARSTRING, VT_SS_WSTRING |
Prend en charge les types de données nchar et nvarcharSQL Server. Inclut les membres suivants : sActualLength (SHORT) Spécifie la longueur réelle de la chaîne vers laquelle pwchNCharVal pointe. N'inclut pas le zéro de fin. sMaxLength (SHORT) Spécifie la longueur maximale de la chaîne vers laquelle pwchNCharVal pointe. pwchNCharVal (WCHAR *) Pointeur sur la chaîne. rgbReserved (BYTE[5] ) Spécifie les informations de classement. Membres non utilisés : dwReserved et pwchReserved. |
CharVal | Aucun indicateur de type OLE DB correspondant. | struct _CharVal |
VT_SS_STRING, VT_SS_VARSTRING |
Prend en charge les types de données char et varcharSQL Server. Inclut les membres suivants : sActualLength (SHORT) Spécifie la longueur réelle de la chaîne vers laquelle pchCharVal pointe. N'inclut pas le zéro de fin. sMaxLength (SHORT) Spécifie la longueur maximale de la chaîne vers laquelle pchCharVal pointe. pchCharVal (CHAR *) Pointeur sur la chaîne. rgbReserved (BYTE[5] ) Spécifie les informations de classement. Membres non utilisés : dwReserved et pwchReserved. |
BinaryVal | Aucun indicateur de type OLE DB correspondant. | struct _BinaryVal |
VT_SS_VARBINARY, VT_SS_BINARY |
Prend en charge les types de données binary et varbinarySQL Server. Inclut les membres suivants : sActualLength (SHORT) Spécifie la longueur réelle des données vers lesquelles prgbBinaryVal pointe. sMaxLength (SHORT) Spécifie la longueur maximale des données vers lesquelles prgbBinaryVal pointe. prgbBinaryVal (BYTE *) Pointeur sur les données binaires. Membre inutilisé : dwReserved. |
UnknownType | UNUSED | UNUSED | UNUSED | UNUSED |
BLOBType | UNUSED | UNUSED | UNUSED | UNUSED |
Problèmes connus
Risque d’altération des données de chaîne étroite
Avant la version 18.4 du pilote OLE DB, l’insertion dans une colonne sql_variant
pouvait entraîner une altération des données sur le serveur si toutes les conditions suivantes étaient remplies :
- La page de codes de l’ordinateur client ne correspondait pas à la page de codes du classement de la base de données.
- La mémoire tampon du client contenait des caractères de chaîne étroite non ASCII codés dans la page de codes du client.
- L’une des conditions suivantes a été remplie :
Le champ
pwszDataSourceType
dans la structureDBPARAMBINDINFO
décrivant le paramètre correspondant à la colonnesql_variant
était défini surL"DBTYPE_SQLVARIANT"
,L"DBTYPE_VARIANT"
ouL"sql_variant"
. Pour plus d’informations, consultez : ICommandWithParameters::SetParameterInfo.or
La requête SQL paramétrable utilisée pour l’insertion était préparée.
Plus précisément, le pilote OLE DB n’a pas translaté les données vers la page de codes de classement de base de données avant de les insérer. Toutefois, le pilote a mal indiqué au serveur que les données avaient été codées dans la page de codes du classement de la base de données. Ce comportement a entraîné une incohérence entre les données et la page de codes correspondante stockée dans la colonne sql_variant
.
De même, lors de la récupération de la même valeur, le pilote OLE DB n’a pas translaté les chaînes dans la page de codes du client. Cependant, étant donné que les données insérées étaient déjà dans la page de codes du client (voir le paragraphe ci-dessus), l’application cliente a pu interpréter les données correctement. Même dans ce cas, les applications qui utilisent d’autres pilotes récupèrent ces valeurs dans un format endommagé. L’altération se produit parce que d’autres pilotes ont interprété la chaîne dans la page de codes du classement de la base de données et ont tenté de la translater en page de codes du client.
À partir de la version 18.4, OLE DB Driver translate les chaînes étroites en page de codes de classement de base de données avant l’insertion. De même, le pilote retranslate les données en page de codes client lors de la récupération. Par conséquent, les applications clientes qui reposent sur le bogue mentionné plus haut peuvent rencontrer des problèmes lors de la récupération des données insérées à l’aide d’une version antérieure de OLE DB Driver. La procédure de récupération ci-dessous vise à vous aider à résoudre ces problèmes.
Procédure de récupération
Important
Avant de suivre les étapes de récupération ci-dessous, assurez-vous de sauvegarder vos données existantes.
Si votre application rencontre des problèmes lors de la récupération de données à partir d’une colonne sql_variant
après avoir basculé vers la version 18.4 de OLE DB Driver, les données endommagées doivent être modifiées pour avoir le même classement que la base de données dans laquelle les données sont stockées. Le script suivant peut être utilisé pour récupérer une valeur unique à partir d’une colonne sql_variant
. Le script est un modèle et vous devez le modifier pour l’adapter à votre scénario.
Important
Étant donné que la page de codes d’origine des données n’est pas stockée, vous devez indiquer au serveur la manière dont les données ont été initialement codées. Pour ce faire, exécutez le script dans le contexte d’une base de données qui a la même page de codes que la page de codes du client qui a initialement inséré les données. Par exemple, si les données endommagées ont été insérées à partir d’un client configuré avec la page de codes 932
, le script suivant doit être exécuté dans le contexte d’une base de données avec un classement japonais (par exemple, 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>