Compartir a través de


Estructura SSVARIANT

Se aplica a: SQL Server Azure SQL Database Azure SQL Instancia administrada Azure Synapse Analytics Analytics Platform System (PDW)

Descargar controlador OLE DB

La estructura SSVARIANT, que se define en msoledbsql.h, corresponde a un valor DBTYPE_SQLVARIANT en OLE DB Driver for SQL Server.

SSVARIANT es una unión de discriminación. Según el valor del miembro vt, el consumidor puede determinar qué miembro tiene que leerse. Los valores de vt se corresponden con tipos de datos de SQL Server. Por tanto, la estructura SSVARIANT puede contener cualquier tipo de SQL Server. Para más información sobre la estructura de datos de los tipos de OLE DB estándar, consulte Indicadores de tipo.

Observaciones

Cuando DataTypeCompat==80, varios subtipos SSVARIANT se convierten en cadenas. Por ejemplo, los siguientes valores de vt se mostrarán en SSVARIANT como VT_SS_WVARSTRING:

  • VT_SS_DATETIMEOFFSET

  • VT_SS_DATETIME2

  • VT_SS_TIME2

  • VT_SS_DATE

Cuando DateTypeCompat == 0, estos tipos se mostrarán en su forma nativa.

Para más información sobre SSPROP_INIT_DATATYPECOMPATIBILITY, consulte Uso de palabras clave de cadena de conexión con OLE DB Driver for SQL Server.

El archivo msoledbsql.h contiene macros de acceso a tipos de datos variant que simplifican la eliminación de referencias a los tipos de miembro de la estructura SSVARIANT. Un ejemplo sería V_SS_DATETIMEOFFSET, que puede utilizarse tal y como se indica a continuación:

memcpy(&V_SS_DATETIMEOFFSET(pssVar).tsoDateTimeOffsetVal, pDTO, cbNative);  
V_SS_DATETIMEOFFSET(pssVar).bScale = bScale;  

Para obtener el conjunto completo de macros de acceso para cada miembro de la estructura SSVARIANT, consulte el archivo msoledbsql.h.

En la tabla siguiente, se describen los miembros de la estructura SSVARIANT:

Member Indicador de tipo OLE DB Tipo de datos de OLE DB C Valor de vt Comentarios
vt SSVARTYPE Especifica el tipo de valor incluido en la estructura SSVARIANT.
bTinyIntVal DBTYPE_UI1 BYTE VT_SS_UI1 Admite el tipo de datos tinyintSQL Server.
sShortIntVal DBTYPE_I2 SHORT VT_SS_I2 Admite el tipo de datos smallintSQL Server.
lIntVal DBTYPE_I4 LONG VT_SS_I4 Admite el tipo de datos intSQL Server.
llBigIntVal DBTYPE_I8 LARGE_INTEGER VT_SS_I8 Admite el tipo de datos bigintSQL Server.
fltRealVal DBTYPE_R4 float VT_SS_R4 Admite el tipo de datos realSQL Server.
dblFloatVal DBTYPE_R8 double VT_SS_R8 Admite el tipo de datos floatSQL Server.
cyMoneyVal DBTYPE_CY LARGE_INTEGER VT_SS_MONEY VT_SS_SMALLMONEY Admite los tipos de datos money y smallmoneySQL Server.
fBitVal DBTYPE_BOOL VARIANT_BOOL VT_SS_BIT Admite el tipo de datos bitSQL Server.
rgbGuidVal DBTYPE_GUID GUID VT_SS_GUID Admite el tipo de datos uniqueidentifierSQL Server.
numNumericVal DBTYPE_NUMERIC DB_NUMERIC VT_SS_NUMERIC Admite el tipo de datos numericSQL Server.
dDateVal DBTYPE_DATE DBDATE VT_SS_DATE Admite el tipo de datos dateSQL Server.
tsDateTimeVal DBTYPE_DBTIMESTAMP DBTIMESTAMP VT_SS_SMALLDATETIME VT_SS_DATETIME VT_SS_DATETIME2 Admite los tipos de datos smalldatetime, datetime y datetime2SQL Server.
Time2Val DBTYPE_DBTIME2 DBTIME2 VT_SS_TIME2 Admite el tipo de datos timeSQL Server.

Incluye los miembros siguientes:

tTime2Val (DBTIME2)

bScale (BYTE) Especifica la escala del valor tTime2Val.
DateTimeVal DBTYPE_DBTIMESTAMP DBTIMESTAMP VT_SS_DATETIME2 Admite el tipo de datos datetime2SQL Server.

Incluye los miembros siguientes:

tsDataTimeVal (DBTIMESTAMP)

bScale (BYTE) Especifica la escala del valor tsDataTimeVal.
DateTimeOffsetVal DBTYPE_DBTIMESTAMPOFSET DBTIMESTAMPOFFSET VT_SS_DATETIMEOFFSET Admite el tipo de datos datetimeoffsetSQL Server.

Incluye los miembros siguientes:

tsoDateTimeOffsetVal (DBTIMESTAMPOFFSET)

bScale (BYTE) Especifica la escala del valor tsoDateTimeOffsetVal.
NCharVal No hay indicador de tipo OLE DB correspondiente. struct _NCharVal VT_SS_WVARSTRING,

VT_SS_WSTRING
Admite los tipos de datos nchar y nvarcharSQL Server.

Incluye los miembros siguientes:

sActualLength (SHORT) especifica la longitud real de la cadena a la que apunta pwchNCharVal. No incluye cero de terminación.

sMaxLength (SHORT) especifica la longitud máxima de la cadena a la que apunta pwchNCharVal.

pwchNCharVal (WCHAR *) Puntero a la cadena.

rgbReserved (BYTE[5] ) Especifica la información de intercalación.

Miembros sin usar: dwReserved y pwchReserved.
CharVal No hay indicador de tipo OLE DB correspondiente. struct _CharVal VT_SS_STRING,

VT_SS_VARSTRING
Admite los tipos de datos char y varcharSQL Server.

Incluye los miembros siguientes:

sActualLength (SHORT) especifica la longitud real de la cadena a la que apunta pchCharVal. No incluye cero de terminación.

sMaxLength (SHORT) especifica la longitud máxima de la cadena a la que apunta pchCharVal.

pchCharVal (CHAR *) Puntero a la cadena.

rgbReserved (BYTE[5] ) Especifica la información de intercalación.

Miembros no usados:

dwReserved y pwchReserved.
BinaryVal No hay indicador de tipo OLE DB correspondiente. struct _BinaryVal VT_SS_VARBINARY,

VT_SS_BINARY
Admite los tipos de datos binary y varbinarySQL Server.

Incluye los miembros siguientes:

sActualLength (SHORT) especifica la longitud real de los datos a los que apunta prgbBinaryVal.

sMaxLength (SHORT) especifica la longitud máxima de los datos a los que apunta prgbBinaryVal.

prgbBinaryVal (BYTE *) Puntero a los datos binarios.

Miembro no usado: dwReserved.
TipoDesconocido No se usa No se usa No se usa No se usa
BLOBType No se usa No se usa No se usa No se usa

Problemas conocidos

Posibles daños en los datos de cadena de caracteres estrechos

Antes de la versión 18.4 del controlador OLE DB, la inserción en una columna sql_variant podía provocar daños en los datos en el servidor si se cumplían todas las condiciones siguientes:

  • La página de códigos del equipo cliente no coincidía con la página de códigos de intercalación de la base de datos.
  • El búfer cliente que se va a insertar contenía caracteres de cadena estrechos no ASCII codificados en la página de códigos del cliente.
  • Se cumplen cualquiera de las condiciones siguientes:
    • El campo pwszDataSourceType de la estructura DBPARAMBINDINFO que describe el parámetro correspondiente a la columna sql_variant se ha establecido en L"DBTYPE_SQLVARIANT", L"DBTYPE_VARIANT" o L"sql_variant". Para obtener detalles, consulte: ICommandWithParameters::SetParameterInfo.

      or

    • Se ha preparado la consulta SQL con parámetros utilizada para la inserción.

En concreto, el controlador OLE DB no ha traducido los datos en la página de códigos de intercalación de la base de datos antes de insertarlos. Pero el controlador indicaba erróneamente al servidor que los datos estaban codificados en la página de códigos de intercalación de la base de datos. Este comportamiento ha producido una desigualdad entre los datos y su página de códigos correspondiente almacenada en la columna sql_variant.

De forma similar, al recuperar el mismo valor, el controlador OLE DB no ha traducido las cadenas a la página de códigos del cliente. Pero como los datos insertados ya estaban en la página de códigos del cliente (vea el párrafo anterior), la aplicación cliente podría interpretar los datos correctamente. Aun así, las aplicaciones que usan otros controladores recuperarían estos valores en un formato dañado. Los daños se producen porque otros controladores han interpretado la cadena en la página de códigos de intercalación de la base de datos y han intentado traducirla a la página de códigos del cliente.

A partir de la versión 18.4, el controlador OLE DB traduce las cadenas de caracteres estrechos a la página de códigos de intercalación de la base de datos antes de la inserción. Del mismo modo, el controlador vuelve a convertir los datos en la página de códigos del cliente tras la recuperación. Como resultado, es posible que las aplicaciones cliente que se basan en el error mencionado antes experimenten problemas al recuperar los datos que se insertan con una versión anterior del controlador OLE DB. El procedimiento de recuperación siguiente pretende proporcionar instrucciones para resolver estos problemas.

Procedimiento de recuperación

Importante

Antes de realizar los pasos de recuperación siguientes, asegúrese de hacer una copia de seguridad de los datos existentes.

Si la aplicación experimenta problemas al recuperar datos de una columna sql_variant después de cambiar a la versión 18.4 del controlador OLE DB, es necesario modificar los datos dañados para que tengan la misma intercalación que la base de datos en la que se almacenan. Se puede usar el script siguiente para recuperar un valor único de una columna sql_variant. El script es una plantilla y la debe ajustar para adecuarla al escenario.

Importante

Como la página de códigos original de los datos no se almacena, debe indicar al servidor cómo se han codificado inicialmente los datos. Para ello, ejecute el script en el contexto de una base de datos que tenga la misma página de códigos que la del cliente que ha insertado inicialmente los datos. Por ejemplo, si los datos dañados se han insertado desde un cliente configurado con la página de códigos 932, es necesario ejecutar el script siguiente en el contexto de una base de datos con una intercalación japonesa (por ejemplo, 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>

Consulte también

Tipos de datos (OLE DB)