Estrutura SSVARIANT

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure Azure Synapse Analytics Analytics Platform System (PDW)

Baixar o driver do OLE DB

A estrutura SSVARIANT, que é definida em msoledbsql.h, corresponde a um valor DBTYPE_SQLVARIANT no Driver do OLE DB para SQL Server.

SSVARIANT é uma união distinta. Dependendo do valor do membro vt, o consumidor pode determinar qual membro deve ser lido. Os valores vt correspondem aos tipos de dados do SQL Server. Portanto, a estrutura SSVARIANT pode manter qualquer tipo do SQL Server. Para obter mais informações sobre a estrutura de dados para tipos OLE DB padrão, confira Indicadores de tipo.

Comentários

Quando DataTypeCompat==80, vários subtipos SSVARIANT se tornam cadeias de caracteres. Por exemplo, os seguintes valores vt serão exibidos em SSVARIANT como VT_SS_WVARSTRING:

  • VT_SS_DATETIMEOFFSET

  • VT_SS_DATETIME2

  • VT_SS_TIME2

  • VT_SS_DATE

Quando DateTypeCompat == 0, estes tipos aparecerão no seu formulário nativo.

Para obter mais informações sobre SSPROP_INIT_DATATYPECOMPATIBILITY, confira Como usar palavras-chave da cadeia de conexão com o Driver do OLE DB para SQL Server.

O arquivo msoledbsql.h contém macros de acesso a variantes que simplificam a desreferência dos tipos de membro na estrutura SSVARIANT. Um exemplo é V_SS_DATETIMEOFFSET que você pode usar da seguinte maneira:

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

Para obter o conjunto completo de macros de acesso para cada membro da estrutura SSVARIANT, veja o arquivo msoledbsql.h.

A seguinte tabela descreve os membros da estrutura SSVARIANT:

Membro Indicador de tipo OLE DB Tipo de dados OLE DB C valor vt Comentários
vt SSVARTYPE Especifica o tipo de valor contido no struct SSVARIANT.
bTinyIntVal DBTYPE_UI1 BYTE VT_SS_UI1 Dá suporte ao tipo de dados tinyintSQL Server.
sShortIntVal DBTYPE_I2 SHORT VT_SS_I2 Dá suporte ao tipo de dados smallintSQL Server.
lIntVal DBTYPE_I4 LONG VT_SS_I4 Dá suporte ao tipo de dados intSQL Server.
llBigIntVal DBTYPE_I8 LARGE_INTEGER VT_SS_I8 Dá suporte ao tipo de dados bigintSQL Server.
fltRealVal DBTYPE_R4 float VT_SS_R4 Dá suporte ao tipo de dados realSQL Server.
dblFloatVal DBTYPE_R8 double VT_SS_R8 Dá suporte ao tipo de dados floatSQL Server.
cyMoneyVal DBTYPE_CY LARGE_INTEGER VT_SS_MONEY VT_SS_SMALLMONEY Dá suporte aos tipos de dados money e smallmoneySQL Server.
fBitVal DBTYPE_BOOL VARIANT_BOOL VT_SS_BIT Dá suporte ao tipo de dados bitSQL Server.
rgbGuidVal DBTYPE_GUID GUID VT_SS_GUID Dá suporte ao tipo de dados uniqueidentifierSQL Server.
numNumericVal DBTYPE_NUMERIC DB_NUMERIC VT_SS_NUMERIC Dá suporte ao tipo de dados numericSQL Server.
dDateVal DBTYPE_DATE DBDATE VT_SS_DATE Dá suporte ao tipo de dados dateSQL Server.
tsDateTimeVal DBTYPE_DBTIMESTAMP DBTIMESTAMP VT_SS_SMALLDATETIME VT_SS_DATETIME VT_SS_DATETIME2 Dá suporte aos tipos de dados smalldatetime, datetime e datetime2SQL Server.
Time2Val DBTYPE_DBTIME2 DBTIME2 VT_SS_TIME2 Dá suporte ao tipo de dados timeSQL Server.

Inclui os seguintes membros:

tTime2Val (DBTIME2)

bScale (BYTE) Especifica a escala para o valor tTime2Val.
DateTimeVal DBTYPE_DBTIMESTAMP DBTIMESTAMP VT_SS_DATETIME2 Dá suporte ao tipo de dados datetime2SQL Server.

Inclui os seguintes membros:

tsDataTimeVal (DBTIMESTAMP)

bScale (BYTE) Especifica a escala para o valor tsDataTimeVal.
DateTimeOffsetVal DBTYPE_DBTIMESTAMPOFSET DBTIMESTAMPOFFSET VT_SS_DATETIMEOFFSET Dá suporte ao tipo de dados datetimeoffsetSQL Server.

Inclui os seguintes membros:

tsoDateTimeOffsetVal (DBTIMESTAMPOFFSET)

bScale (BYTE) Especifica a escala para o valor tsoDateTimeOffsetVal.
NCharVal Não existe um indicador de tipo OLE DB correspondente. struct _NCharVal VT_SS_WVARSTRING,

VT_SS_WSTRING
Dá suporte aos tipos de dados nchar e nvarcharSQL Server.

Inclui os seguintes membros:

sActualLength (SHORT) especifica o comprimento real da cadeia de caracteres para a qual pwchNCharVal aponta. Não inclui o zero final.

sMaxLength (SHORT) especifica o comprimento máximo da cadeia de caracteres para a qual pwchNCharVal aponta.

pwchNCharVal (WCHAR *) Ponteiro para a cadeia de caracteres.

rgbReserved (BYTE [5] ) especifica as informações de ordenação.

Membros não usados: dwReserved e pwchReserved.
CharVal Não existe um indicador de tipo OLE DB correspondente. struct _CharVal VT_SS_STRING,

VT_SS_VARSTRING
Dá suporte aos tipos de dados char e varcharSQL Server.

Inclui os seguintes membros:

sActualLength (SHORT) especifica o comprimento real da cadeia de caracteres para a qual pchCharVal aponta. Não inclui o zero final.

sMaxLength (SHORT) especifica o comprimento máximo da cadeia de caracteres para a qual pchCharVal aponta.

pchCharVal (CHAR *) Ponteiro para a cadeia de caracteres.

rgbReserved (BYTE [5] ) especifica as informações de ordenação.

Membros não usados:

dwReserved e pwchReserved.
BinaryVal Não existe um indicador de tipo OLE DB correspondente. struct _BinaryVal VT_SS_VARBINARY,

VT_SS_BINARY
Dá suporte aos tipos de dados binary e varbinarySQL Server.

Inclui os seguintes membros:

sActualLength (SHORT) especifica o comprimento real dos dados para os quais prgbBinaryVal aponta.

sMaxLength (SHORT) especifica o comprimento máximo dos dados para os quais prgbBinaryVal aponta.

prgbBinaryVal (BYTE *) Ponteiro para os dados binários.

Membro não usado: dwReserved.
UnknownType UNUSED UNUSED UNUSED UNUSED
BLOBType UNUSED UNUSED UNUSED UNUSED

Problemas conhecidos

Possibilidade de dados corrompidos na cadeia de caracteres estreita

Antes da versão 18.4 do driver do OLE DB, a inserção em uma coluna sql_variant poderia resultar em dados corrompidos no servidor se todas as seguintes condições fossem verdadeiras:

  • A página de código do computador cliente não correspondia à página de código de ordenação do banco de dados.
  • O buffer do cliente para inserção de caracteres não ASCII contidos de cadeia de caracteres estreita era codificado na página de código do cliente.
  • Qualquer uma das seguintes condições era verdadeira:
    • O campo pwszDataSourceType na estrutura DBPARAMBINDINFO descrevendo o parâmetro correspondente à coluna sql_variant era definido como L"DBTYPE_SQLVARIANT", L"DBTYPE_VARIANT" ou L"sql_variant". Para obter detalhes, confira: ICommandWithParameters::SetParameterInfo.

      or

    • A consulta SQL parametrizada usada para inserção era preparada.

Mais especificamente, o driver do OLE DB não convertia os dados para a página de código de ordenação do banco de dados antes de inseri-los. No entanto, o driver indicava incorretamente para o servidor que os dados haviam sido codificados na página de código de ordenação do banco de dados. Esse comportamento levava a uma incompatibilidade entre os dados e sua página de código correspondente armazenada na coluna sql_variant.

De maneira semelhante, após a recuperação do mesmo valor, o driver do OLE DB não convertia cadeias de caracteres na página de código do cliente. No entanto, como os dados inseridos já estavam na página de código do cliente (consulte o parágrafo acima), o aplicativo cliente podia interpretar os dados corretamente. Mesmo assim, aplicativos que usassem outros drivers recuperariam esses valores em um formato corrompido. A corrupção ocorria porque outros drivers interpretavam a cadeia de caracteres na página de código de ordenação do banco de dados e tentavam convertê-los na página de código do cliente.

Começando com a versão 18.4, o driver do OLE DB converte as cadeias de caracteres estreitas para a página de código de ordenação do banco de dados antes da inserção. Da mesma forma, o driver converte os dados de volta para a página de código do cliente após a recuperação. Como resultado, aplicativos cliente que dependem do bug mencionado acima podem enfrentar problemas ao recuperar dados inseridos usando uma versão anterior do driver do OLE DB. O procedimento de recuperação a seguir destina-se a fornecer diretrizes para resolver esses problemas.

Procedimento de recuperação

Importante

Antes de executar as etapas de recuperação abaixo, faça backup dos dados existentes.

Se o seu aplicativo apresentar problemas ao recuperar dados de uma coluna sql_variant depois de alternar para a versão 18.4 do driver do OLE DB, os dados corrompidos precisarão ser modificados para ter a mesma ordenação que a do banco de dados no qual estão armazenados. O script a seguir pode ser usado para recuperar um só valor de uma coluna sql_variant. O script é um modelo e você precisa ajustá-lo ao seu cenário.

Importante

Como a página de código original dos dados não é armazenada, você precisa informar ao servidor como os dados foram codificados inicialmente. Para fazer isso, execute o script no contexto de um banco de dados que tenha a mesma página de código que a do cliente que inseriu os dados primeiro. Por exemplo, se os dados corrompidos tiverem sido inseridos de um cliente configurado com a página de código 932, o script a seguir precisará ser executado dentro do contexto de um banco de dados com uma ordenação em japonês (por exemplo, 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://video2.skills-academy.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://video2.skills-academy.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 Também

Tipos de dados (OLE DB)