Tipo de dados de vetor (ODBC)

Este artigo documenta o tipo de dados SQL vetor conforme implementado pelo Microsoft ODBC Driver for SQL Server a partir da versão 18.6.1.1. Este documento descreve o comportamento do driver da Microsoft para o vetor e fornece diretrizes de uso, notas específicas da API e snippets de código. Para obter uma visão geral dos tipos de dados de vetor, consulte o tipo de dados vetor.

Visão geral

O Microsoft ODBC Driver for SQL Server dá suporte nativo ao tipo de dados de vetor . Os aplicativos podem armazenar, recuperar e processar inserções numéricas de dimensão fixa comumente usadas em cargas de trabalho de IA e machine learning. O driver expõe o suporte a vetores por meio de APIs ODBC padrão e tipos de dados C. Os aplicativos podem interoperar com colunas de vetor do SQL Server sem alterar fluxos de trabalho ODBC existentes.

Aplica-se a: Microsoft ODBC Driver for SQL Server 18.6.1.1 e versões posteriores. O suporte ao float16 tipo base requer a versão 18.7.1.1 ou posterior.

O suporte a vetores é desativado por padrão e deve ser explicitamente habilitado.

Tipos de elementos base

Uma coluna vetorial declara um tipo de elemento base. O driver suporta ambos os tipos definidos pelo SQL Server.

Tipo base Indicador de tipo Bytes por elemento no fio Dimensão máxima Versão do driver
float32 SQL_VECTOR_TYPE_FLOAT32 (0) 4 1.998 18.6.1.1
float16 SQL_VECTOR_TYPE_FLOAT16 (1) 2 3,996 18.7.1.1

float32 é o padrão. Para usar armazenamento de meia precisão, declare a coluna ou parâmetro como VECTOR(<dimensions>, float16). Como um float16 elemento ocupa metade dos bytes do fio, um float16 vetor contém o dobro de dimensões dentro do mesmo limite de carga útil de 8.000 bytes.

Importante

O buffer de aplicação é sempre um array de float (4 bytes por elemento) para ambos os tipos base. O driver converte entre meia precisão no fio e precisão simples no seu buffer. Dimensione cada buffer com sizeof(float), nunca com 2 bytes por elemento, mesmo para uma float16 coluna.

Como float16 tem menos bits de mantissa do que float32, uma viagem de ida e volta por uma float16 coluna é com perdas. Os valores são arredondados para o valor de meia-precisão representável mais próximo ao inserir, e o valor lido de volta é a float32 expansão desse valor arredondado.

No servidor, float16 é necessário o SQL Server 2025 (17.x) com a PREVIEW_FEATURES configuração com escopo do banco de dados ativada. Para obter mais informações, consulte Suporte a float de meia precisão no tipo de dados de vetor.

Representação C nativa

Quando o suporte ao vetor está habilitado, as colunas de vetor são trocadas usando uma estrutura C tipada chamada SQL_SS_VECTOR_STRUCT.

    typedef enum
    {
        SQL_VECTOR_TYPE_FLOAT32 = 0,  /* 32-bit floating point */
        SQL_VECTOR_TYPE_FLOAT16 = 1   /* 16-bit floating point */
    } SQLVECTORTYPE;

    typedef struct tagSS_VECTOR_STRUCT {
        SQLSMALLINT   dimension;  /* Number of elements */
        SQLVECTORTYPE type;       /* Element base type indicator */
        union data {
            float* f32;           /* Pointer to float32 data */
            float* f16;           /* Pointer to float16 data */
        } data;
    } SQL_SS_VECTOR_STRUCT;
  • dimension: descreve o número de elementos no vetor
  • type: identifica o tipo de elemento base, SQL_VECTOR_TYPE_FLOAT32 ou SQL_VECTOR_TYPE_FLOAT16
  • data.f32 / data.f16: aponta para o buffer de aplicação contendo valores vetoriais

Ambos os membros da união são declarados como float* e são intercambiáveis, pois o buffer do lado do cliente contém float32 valores para qualquer tipo base. Use o membro que documentar sua intenção.

Habilitar o suporte ao vetor

A vectorTypeSupport palavra-chave cadeia de conexão seleciona o nível de suporte vetorial nativo que a conexão negocia.

Valor Behavior
off (predefinição) Colunas vetoriais aparecem como varchar(max) contendo arrays JSON.
v1 Suporte vetorial nativo para o float32 tipo base.
v2 Suporte vetorial nativo tanto para os float32 tipos quanto float16 para base. Requer a versão 18.7.1.1 ou posterior.

Você também pode definir o nível após alocar a alavanca de conexão e, antes de conectar, com o SQL_COPT_SS_VECTOR_TYPE_SUPPORT atributo pré-conexão de conexão.

  • O driver da Microsoft expõe uma ligação SQL_C_SS_VECTOR C específica para o driver e suporta SQL_C_BINARY saída vetorial. Na prática:

    • Quando você ativa vectorTypeSupport=v1 ou v2, APIs de recuperação (por exemplo, SQLGetData e SQLBindCol) podem retornar colunas vetoriais como ou SQL_C_SS_VECTORSQL_C_BINARY. SQL_C_SS_VECTOR retorna o vetor em um formulário compacto digitado. SQL_C_BINARY retorna uma carga varbinary .

    • Para ligação de entrada ou parâmetros, o driver suporta tanto SQL_C_SS_VECTOR quanto SQL_C_BINARY. SQL_C_SS_VECTOR fornece uma associação de entrada typeada e compacta. SQL_C_BINARY é equivalente e portátil. Use SQL_C_SS_VECTOR quando quiser que o driver trate a carga como um tipo de vetor nativo.

    • Quando vectorTypeSupport=off, as colunas de vetor aparecem como varchar(max) contendo matrizes JSON.

v2 é um superconjunto de v1, então uma conexão negociada em v2 trata float32 colunas exatamente como v1 faz. Enviar um float16 valor em uma conexão negociada em v1 falha com Requested vector base type is not supported for the negotiated vector version. Use v2 sempre que a aplicação possa encontrar uma float16 coluna.

Os aplicativos também devem definir a versão ODBC como ODBC 3.8 antes de usar tipos específicos de vetor:

    SQLSetEnvAttr(
    hEnv,
    SQL_ATTR_ODBC_VERSION,
    (SQLPOINTER)SQL_OV_ODBC3_80,
    0);

Formatos de vinculação com suporte

Ligação de vetor nativo

Tipo C: SQL_C_SS_VECTOR

Esse formato é recomendado para aplicativos críticos ao desempenho.

Associação binária

Tipo C: SQL_C_BINARY

Os vetores são retornados usando o mesmo layout que SQL_C_SS_VECTOR. Os aplicativos podem usar esse formato para cenários de interoperabilidade de baixo nível. O buffer do ponteiro de dados pode ser contíguo ou não contíguo com o endereço de memória da estrutura.

Diretrizes da API ODBC

Esta seção descreve como as APIs ODBC interagem com dados de vetor do SQL Server, incluindo requisitos de layout de buffer, NULL tratamento e representações de dados com suporte. Todos os comportamentos se aplicam quando vectorTypeSupport está configurado para v1 ou v2 e o ambiente está configurado para ODBC 3.8.

Cada fórmula de tamanho de buffer nesta seção usa sizeof(float) por elemento para ambos os tipos base, porque o buffer do lado do cliente sempre mantém float32 valores. Uma float16 coluna altera os bytes no fio, não o layout do seu buffer.

SQLBindCol

Use SQLBindCol para associar colunas de vetor em um conjunto de resultados a buffers de aplicação.

  • Chamada típica:
    SQLRETURN SQLBindCol(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   ColumnNumber,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: use SQL_C_SS_VECTOR ou SQL_C_BINARY.

  • TargetValuePtr: ponteiro para um SQL_SS_VECTOR_STRUCT com uma matriz flutuante quando TargetType estiver SQL_C_SS_VECTOR; caso contrário, ponteiro para um buffer com tamanho como o valor em StrLen_or_IndPtr.

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + o número de bytes alocados para o buffer de coluna (dimensão * 4).

  • StrLen_or_IndPtr: ponteiro que recebe o comprimento de byte do vetor retornado (SQL_DESC_OCTET_LENGTH). Seu valor é sizeof(SQL_SS_VECTOR_STRUCT) + o tamanho da matriz flutuante (dimensão * 4).

Esses tamanhos são os mesmos para uma float16 coluna. O driver expande cada elemento de meia precisão para a float à medida que preenche seu buffer, e reporta o comprimento expandido.

Expectativas do layout de buffer

Buffer não contíguo (recomendado)

  • O aplicativo aloca um SQL_SS_VECTOR_STRUCT por linha.
  • O aplicativo aloca memória para data.f32.
  • O driver preenche metadados de vetor e grava valores de elemento no buffer float fornecido.
    SQLLEN numberOfRow = 1000; // set to SQL_ATTR_ROW_ARRAY_SIZE
    SQLULEN columnSize = x; // use SQLDescribeCol or SQLColAttributeW or sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * 4)
    SQL_SS_VECTOR_STRUCT vecBuffer[numberOfRow]
    std::vector<SQLLEN> indicator(numberOfRow, 0);
    for (int i = 0; i < numberOfRow; i++)
    {
        vecBuffer[i].dimension = static_cast<SQLUSMALLINT>((columnSizes[col - 1] - sizeof(SQL_SS_VECTOR_STRUCT)) / 4);
        vecBuffer[i].type = SQL_VECTOR_TYPE_FLOAT32; // or SQL_VECTOR_TYPE_FLOAT16
        vecBuffer[i].data.f32 = (float*)malloc(vecBuffer[i].dimension * sizeof(float));
        if (!vecBuffer[i].data.f32) {
            std::cerr << "Memory allocation failed for vector data." << std::endl;
            return SQL_ERROR;
        }
    }
    SQLBindCol(hStmt, col, SQL_C_SS_VECTOR, vecBuffer, columnSize, indicators.data());

Buffer contíguo

  • O aplicativo aloca um único buffer e o ODBC o preenche adequadamente.
  • A matriz flutuante deve começar imediatamente após o struct.
  • O driver define data.f32 para apontar para essa região contígua.
    SQLLEN numberOfRow = 1000; // set to SQL_ATTR_ROW_ARRAY_SIZE
    SQLULEN columnSize = x; // use SQLDescribeCol or SQLColAttributeW or sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * 4)
    std::vector<BYTE> vecBuffer;
    std::vector<SQLLEN> indicator(numberOfRow, 0);
    vecBuffer.resize(numberOfRow * columnSize);
    SQLBindCol(hStmt, col, SQL_C_BINARY, vecBuffer.data(), columnSize, indicators.data());

Manipulação de NULL para SQLBindCol

Quando o valor da coluna éNULL, o driver define *StrLen_or_IndPtrSQL_NULL_DATA e não preenche o buffer. Sempre verifique o indicador antes de acessar o conteúdo do vetor.

Observação

O comportamento de leitura e busca de linhas para colunas de vetor é descrito em detalhes em SQLFetch e SQLFetchScroll (consulte essas referências de API para semântica de busca e exemplos de busca de array).

SQLGetData

Use SQLGetData para recuperar dados vetoriais de colunas não vinculadas.

  • Chamada típica:
    SQLRETURN SQLGetData(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   Col_or_Param_Num,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: use SQL_C_SS_VECTOR ou SQL_C_BINARY.

  • TargetValuePtr: ponteiro para um SQL_SS_VECTOR_STRUCT com uma matriz flutuante quando TargetType estiver SQL_C_SS_VECTOR; caso contrário, ponteiro para um buffer com tamanho como o valor em StrLen_or_IndPtr.

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + o número de bytes alocados para o buffer de coluna (dimensão * 4).

  • StrLen_or_IndPtr: ponteiro que recebe o comprimento de byte do vetor retornado (SQL_DESC_OCTET_LENGTH). Seu valor é sizeof(SQL_SS_VECTOR_STRUCT) + o tamanho da matriz flutuante (dimensão * 4).

Não há suporte para recuperação em partes. Você deve recuperar todo o vetor em uma chamada.

Exemplo ( vetor nativo):

    SQLLEN dataLen = 0;
    SQL_SS_VECTOR_STRUCT vec = {};
    vec.data.f32 = (float*)malloc(x * sizeof(float)); // x is the dimension
    if (!vec.data.f32) {
        std::cerr << "Memory allocation failed for vector data." << std::endl;
        return SQL_ERROR;
    }
    SQLGetData(hStmt, col, SQL_C_SS_VECTOR, &vec, sizeof(vec) + sizeof(float) * vec.dimension, &dataLen);

Tratamento de NULL para SQLGetData

Quando o valor da coluna éNULL, o driver define *StrLen_or_IndPtrSQL_NULL_DATA e não preenche o buffer. Sempre verifique o indicador antes de acessar o conteúdo do vetor.

Observação

O comportamento de leitura e busca de linhas para colunas de vetor é descrito em detalhes em SQLFetch e SQLFetchScroll (consulte essas referências de API para semântica de busca e exemplos de busca de array).

SQLFetch

Use SQLFetch para buscar a próxima linha e materializar corretamente as colunas vinculadas SqlVector.

  • Chamada típica:
    SQLRETURN SQLFetch(
     SQLHSTMT     StatementHandle);

Chame SQLFetch no loop padrão com SqlVector colunas já associadas através de SQLBindCol. Ou use SQLGetData para recuperar dados para o buffer do aplicativo.

Exemplo ( vetor nativo):

    while ((ret = SQLFetch(hStmt)) == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
        // if SQLBindCol was used directly jump to read buffer
        // else use SQLGetData and than read buffer.
        std::cout << "  data: [";
        if (dataLen != SQL_NULL_DATA)
        {
            for (SQLUSMALLINT d = 0; d < vec.dimension; ++d) {
                std::cout << vec.data.f32[d];
                if (d + 1 < vec.dimension) std::cout << ", ";
            }
        }
        std::cout << "]" << std::endl;
    }

SQLFetchScroll

Use SQLFetchScroll para buscar conjuntos de linhas de acordo com uma orientação especificada (próximo, anterior, absoluto, relativo, marcador). O driver copia corretamente os dados do vetor para os buffers da aplicação.

  • Chamada típica:
    SQLRETURN SQLFetchScroll(
      SQLHSTMT      StatementHandle,
      SQLSMALLINT   FetchOrientation,
      SQLLEN        FetchOffset);

Exemplo ( vetor nativo):

    // Fetch rows in batches
    while ((ret = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0)) != SQL_NO_DATA) {
        for (SQLULEN i = 0; i < numRowsFetched; i++) {
            // In case of Contiguous Buffer
                SQL_SS_VECTOR_STRUCT* vecptr = reinterpret_cast<SQL_SS_VECTOR_STRUCT*>(
                vecBuffer.data() + (i * columnSizes[col - 1]));
                float* floats = reinterpret_cast<float*>(
                reinterpret_cast<char*>(vecptr) + sizeof(SQL_SS_VECTOR_STRUCT)
            );
            // in Case of non-contiguous Buffer
            SQL_SS_VECTOR_STRUCT* vecptr = &vecBuffer[i];
            float* floats = vecptr->data.f32;

            if (indicators[i] != SQL_NULL_DATA)
            {
                for (SQLUSMALLINT d = 0; d < vecptr->dimension; ++d) {
                    std::cout << floats[d];
                    if (d + 1 < vecptr->dimension) std::cout << ", ";
                }
            }
            std::cout << "]" << std::endl;
        }
    }

SQLBindParameter

Use SQLBindParameter para enviar valores de vetor para o SQL Server.

  • Chamada típica:
    SQLRETURN SQLBindParameter(
        SQLHSTMT        StatementHandle,
        SQLUSMALLINT    ParameterNumber,
        SQLSMALLINT     InputOutputType,
        SQLSMALLINT     ValueType,
        SQLSMALLINT     ParameterType,
        SQLULEN         ColumnSize,
        SQLSMALLINT     DecimalDigits,
        SQLPOINTER      ParameterValuePtr,
        SQLLEN          BufferLength,
        SQLLEN *        StrLen_or_IndPtr);
  • ParameterValuePtr: aponta para um povoado SQL_SS_VECTOR_STRUCT
  • ColumnSize: ignorado para parâmetros de entrada. Para parâmetros de saída e cenários de dados em execução, especifique o tamanho total do vetor: sizeof(SQL_SS_VECTOR_STRUCT) + (tamanho da matriz flutuante )
  • DecimalDigits: ignorado para parâmetros de entrada. Para parâmetros de saída e cenários de dados em execução, especifique o tipo base de vetor
  • BufferLength: ≥ sizeof(SQL_SS_VECTOR_STRUCT) + (dimensão * sizeof(float))
  • *StrLen_or_IndPtr: deve conter o mesmo tamanho total

De onde vem o tipo base

O driver lê o tipo de elemento base de um lugar diferente, dependendo da direção do parâmetro. Errar isso é a causa mais comum ou Invalid vector dimensionProvided buffer length too small/large erros em um float16 parâmetro.

Tipo de parâmetro Fonte do tipo base Fonte dimensional
Entrada e entrada/saída O type campo do SQL_SS_VECTOR_STRUCT você passa O dimension campo da mesma estrutura
Saída pura DecimalDigits Derivado de ColumnSize como (ColumnSize - sizeof(SQL_SS_VECTOR_STRUCT)) / sizeof(float)
Dados na execução DecimalDigits Derivado de ColumnSize, e cruzado com o comprimento passado para SQL_LEN_DATA_AT_EXEC

Para um parâmetro de entrada, BufferLength deve ser exatamente sizeof(SQL_SS_VECTOR_STRUCT) igual a + (dimensão * sizeof(float)). Um valor maior ou menor falha em vez de ser tolerado.

Exemplo ( vetor nativo, float32):

    float values[3] = {1.0f, 2.0f, 3.0f};
    SQL_SS_VECTOR_STRUCT vec;
    SQLLEN cb;

    vec.dimension = 3;
    vec.type = SQL_VECTOR_TYPE_FLOAT32;
    vec.data.f32 = values;

    cb = sizeof(vec) + sizeof(values);

    SQLBindParameter(
        hStmt, 1, SQL_PARAM_INPUT, SQL_C_SS_VECTOR, SQL_SS_VECTOR, 0, 0, &vec, cb, &cb);

Exemplo ( vetor nativo, float16):

Só o type campo muda. O array de valores permanece como float um array e cb é calculado da mesma forma.

    float values[3] = {1.0f, 2.0f, 3.0f};
    SQL_SS_VECTOR_STRUCT vec;
    SQLLEN cb;

    vec.dimension = 3;
    vec.type = SQL_VECTOR_TYPE_FLOAT16;
    vec.data.f16 = values; /* still a float32 array */

    cb = sizeof(vec) + sizeof(values);

    SQLBindParameter(
        hStmt, 1, SQL_PARAM_INPUT, SQL_C_SS_VECTOR, SQL_SS_VECTOR, 0, 0, &vec, cb, &cb);

Exemplo (float16 parâmetro de saída):

Um parâmetro de saída puro não carrega estrutura de entrada, então o tipo base é passado e DecimalDigits a dimensão é derivada de ColumnSize.

    SQL_SS_VECTOR_STRUCT vec = {};
    float values[3] = {};
    vec.data.f16 = values;

    SQLULEN columnSize = sizeof(SQL_SS_VECTOR_STRUCT) + 3 * sizeof(float);
    SQLLEN cb = (SQLLEN)columnSize;

    SQLBindParameter(
        hStmt, 1, SQL_PARAM_OUTPUT, SQL_C_SS_VECTOR, SQL_SS_VECTOR,
        columnSize, SQL_VECTOR_TYPE_FLOAT16, &vec, cb, &cb);

Gerenciamento de NULL para SQLBindParameter

Os aplicativos podem indicar um NULL vetor usando uma das abordagens compatíveis.

  • Definir *StrLen_or_IndPtr como SQL_NULL_DATA e passar NULL como ParameterValuePtr

  • Forneça um SQL_SS_VECTOR_STRUCT com:

    Tipo de conjunto de dimensões definido para o tipo base da coluna data.f32 = NULL

SQLPutData

O driver dá suporte a parâmetros SQLPutData de vetor com estas restrições:

  • Você deve fornecer todo o vetor na primeira chamada.

  • O driver não dá suporte à transmissão de vetor em partes ou incremental.

  • NULL O tratamento segue as mesmas regras que SQLBindParameter.

  • Chamada típica:

    SQLRETURN SQLPutData(
        SQLHSTMT     StatementHandle,
        SQLPOINTER   DataPtr,
        SQLLEN       StrLen_or_Ind);
  • DataPtr: aponta para um povoado SQL_SS_VECTOR_STRUCT
  • StrLen_or_Ind: sizeof(SQL_SS_VECTOR_STRUCT) + (dimensão * sizeof(float))

Exemplo ( vetor nativo):

    std::vector<float> floatArray = { 1.0f, 2.0f, 3.0f };

    SQL_SS_VECTOR_STRUCT vectorValue = {0};
    vectorValue.type = SQL_VECTOR_TYPE_FLOAT32; // or SQL_VECTOR_TYPE_FLOAT16
    vectorValue.dimension = (SQLUSMALLINT)floatArray.size();
    vectorValue.data.f32 = floatArray.data();

    // Tell ODBC this parameter will be supplied at execution time
    SQLLEN cbVectorLen = SQL_LEN_DATA_AT_EXEC(
        (SQLLEN)(sizeof(SQL_SS_VECTOR_STRUCT) + floatArray.size() * sizeof(float))
    );

    // Optional token to identify which parameter needs data
    SQLPOINTER token = (SQLPOINTER)1;

    // Bind as DATA_AT_EXEC: BufferLength is 0, value pointer can be a token
    SQLRETURN rc = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_SS_VECTOR, SQL_SS_VECTOR, 0, 0, token, 0, &cbVectorLen);

    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
        // handle error
    }

    rc = SQLExecute(hStmt);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NEED_DATA) {
        // handle error
    }

    SQLPOINTER pParamToken = NULL;
    rc = SQLParamData(hStmt, &pParamToken);

    if (rc == SQL_NEED_DATA) {
        // Provide entire vector in first SQLPutData call (no chunking)
        rc = SQLPutData(
            hStmt,
            (SQLPOINTER)&vectorValue,
            (SQLLEN)(sizeof(SQL_SS_VECTOR_STRUCT) + floatArray.size() * sizeof(float))
        );

        if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
            // handle error
        }

        // Finalize parameter transfer
        rc = SQLParamData(hStmt, &pParamToken);
    }

Metadados do descritor

Quando você habilita o suporte ao vetor, o Microsoft ODBC Driver for SQL Server expõe metadados de vetor por meio de APIs de descritor ODBC padrão. Os aplicativos podem usar informações de descritor para descobrir detalhes do esquema vetor, dimensionar tamanhos de buffer de computação e configurar corretamente associações para parâmetros e conjuntos de resultados.

Valores de campo de descritor para vetor

A tabela a seguir resume os valores de campo do descritor para colunas e parâmetros de vetor do SQL Server.

Campo descritor Valor Description
SQL_DESC_TYPE SQL_SS_VECTOR (-156) Identificador de tipo de dados SQL base
SQL_DESC_CONCISE_TYPE SQL_SS_VECTOR Tipo de dados SQL conciso
SQL_DESC_TYPE_NAME vector Nome do tipo SQL
SQL_DESC_LOCAL_TYPE_NAME vector Nome do tipo local do driver
SQL_DESC_LENGTH sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float)) Tamanho lógico do valor do vetor
SQL_DESC_OCTET_LENGTH O mesmo que SQL_DESC_LENGTH Tamanho físico em bytes
SQL_DESC_PRECISION O mesmo que SQL_DESC_LENGTH Usado para relatar o tamanho do vetor
SQL_DESC_SCALE SQL_VECTOR_TYPE_FLOAT32 ou SQL_VECTOR_TYPE_FLOAT16 Tipo de elemento base de vetor
SQL_CA_SS_VECTOR_DIMENSION dimension Número de elementos no vetor
SQL_DESC_DISPLAY_SIZE dimension * VECTOR_FLOAT32_TO_CHAR_JSON_MAX_SIZE Comprimento máximo de exibição JSON
SQL_DESC_FIXED_PREC_SCALE SQL_FALSE O vetor não tem precisão/escala fixa
SQL_DESC_NULLABLE SQL_NULLABLE Colunas de vetor permitem valores NULL
SQL_DESC_NUM_PREC_RADIX 0 Tipo não numérico
SQL_DESC_SEARCHABLE SQL_PRED_NONE Não utilizável em predicados
SQL_DESC_UNSIGNED SQL_TRUE O tipo de elemento não está assinado
SQL_DESC_AUTO_UNIQUE_VALUE SQL_FALSE Não é autounique (termo técnico)
SQL_DESC_CASE_SENSITIVE SQL_FALSE Não diferencia maiúsculas de minúsculas
SQL_DESC_UPDATABLE SQL_ATTR_READWRITE_UNKNOWN Atualização desconhecida

SQL_DESC_LENGTH, SQL_DESC_OCTET_LENGTH, e SQL_DESC_PRECISION todos descrevem o buffer do lado do cliente, então eles reportam sizeof(SQL_SS_VECTOR_STRUCT) + (dimensão * sizeof(float)) para uma float16 coluna além de um float32 um. Os dois diferem apenas no número de bytes que o SQL Server armazena e transmite.

SQL_DESC_SCALE é o único corpo descritor que distingue os tipos base. Lê-lo é como uma aplicação descobre se uma coluna é float32 ou float16.

SQLColAttribute para dimensão vetorial

A partir da versão 18.7.1.1, SQL_CA_SS_VECTOR_DIMENSION retorna diretamente a contagem de elementos da coluna vetorial, de modo que uma aplicação não precisa mais derivá-la a partir de um campo de comprimento:

    SQLLEN dimension = 0;
    SQLColAttribute(hStmt, col, SQL_CA_SS_VECTOR_DIMENSION, NULL, 0, NULL, &dimension);

    SQLLEN baseType = 0;
    SQLColAttribute(hStmt, col, SQL_DESC_SCALE, NULL, 0, NULL, &baseType);
    /* baseType is SQL_VECTOR_TYPE_FLOAT32 or SQL_VECTOR_TYPE_FLOAT16 */

Você também pode definir SQL_CA_SS_VECTOR_DIMENSION um descritor de aplicação ou no IPD para um parâmetro vetorial. Defini-lo em qualquer outro tipo de parâmetro retorna um erro de campo descritor inválido.

SQLDescribeCol

Quando você chama SQLDescribeCol uma coluna de vetor :

  • DataType é SQL_SS_VECTOR
  • ColumnSize corresponde a SQL_DESC_PRECISION
  • DecimalDigits é o indicador de tipo de elemento base, não uma escala numérica: 0 para float32 e 1 para float16
  • Nullable é SQL_NULLABLE

O tamanho da coluna relatada representa o tamanho da carga do vetor nativo: sizeof(SQL_SS_VECTOR_STRUCT) + (dimensão * sizeof(float))

SQLDescribeParam

Quando você usa SQLDescribeParam para um parâmetro vetor :

  • DataType é SQL_SS_VECTOR
  • ColumnSize é igual ao tamanho da carga do vetor nativo
  • DecimalDigits é o indicador de tipo de elemento base, não uma escala numérica: 0 para float32 e 1 para float16
  • Nullable é SQL_NULLABLE

Essas informações permitem que os aplicativos aloquem buffers de parâmetro corretamente antes da associação.

SQLColAttribute

  • Use SQLColAttribute(hstmt, ColumnNumber, SQL_DESC_OCTET_LENGTH, ...) para obter o comprimento exato em bytes da carga do vetor. SQL_DESC_LENGTH e SQL_DESC_PRECISION podem conter valores específicos do driver. Para contagem de bytes, prefira SQL_DESC_OCTET_LENGTH.

    • NULL tratamento: quando uma coluna é NULL, SQLColAttribute (ou o StrLen_or_IndPtr usado com SQLBindCol) retorna SQL_NULL_DATA. Verifique SQL_NULL_DATA antes de usar os tamanhos ou buffers retornados.

Cópia em massa (BCP)

Você pode importar e exportar colunas de vetor em massa por meio de arquivos BCP e da bcp_bind API, assim como outros tipos de dados. Atualmente, a importação e exportação de vetor dá suporte apenas ao formato nativo (SQLVECTOR) ou varbinary (SQLBINARY), mas não ao formato de caractere. Não há suporte para conversão entre o tipo de vetor e o tipo de caractere.

A cópia em massa respeita o mesmo nível de suporte que o restante do motorista. Uma float16 coluna requer uma conexão negociada em vectorTypeSupport=v2. Na utilidade bcp , use -z0 para float32 e -z1 para float16. Para obter mais informações, consulte o utilitário bcp.

Para obter mais informações sobre o token de tipo, o comprimento do prefixo padrão e o comprimento do campo padrão para o vetor, consulte Tipo de Armazenamento de Arquivos, Comprimento do Prefixo e Comprimento do Campo.

bcp_gettypename

Quando você usa bcp_gettypename para obter o nome do tipo SQL do vetor, ele retorna o token de tipo BCP (SQLVECTOR) e "vector".

bcp_bind

Use bcp_bind para inserir variáveis de programa em massa em uma coluna de vetor .

Chamada típica:

RETCODE bcp_bind (
        HDBC hdbc,
        LPCBYTE pData,
        INT cbIndicator,
        DBINT cbData,
        LPCBYTE pTerm,
        INT cbTerm,
        INT eDataType,
        INT idxServerCol);
  • pData: se cbIndicator for zero, contém um ponteiro para dados de SQL_SS_VECTOR_STRUCT, com uma matriz do tipo float dentro (vectorStruct.data.f32 campo). Se cbIndicator não for zero, o indicador aparecerá na memória diretamente antes dos dados. Portanto, pData aponta para um buffer que primeiro tem cbIndicator bytes de indicador de comprimento, seguido pela estrutura de vetor.
  • cbData: se fornecido, deve ter um valor exatamente igual a - sizeof(SQL_SS_VECTOR_STRUCT) + (sizeof(float) * dimensão). Caso contrário, ocorrerá um erro. Isso é igual para ambos os tipos de base, porque o buffer limitado mantém float32 valores de qualquer forma.
  • eDataType: SQLVECTOR ou SQLBINARY

Defina o type campo da estrutura para o tipo base da coluna. Para uma float16 coluna, o driver converte o array limitado float32 para meia precisão enquanto constrói a carga útil do fio, então um arquivo de dados escrito em formato nativo contém dois bytes por elemento.

Quando você importa dados para uma coluna de vetor por meio de bcp_bind, defina eDataType como SQLVECTOR ou SQLBINARY. Em ambos os casos, você deve fornecer dados na forma de SQL_SS_VECTOR_STRUCT.

Solução de problemas e dicas

  • Se SQLGetTypeInfo não listar VECTOR, volte a armazenar vetores como varchar.
  • Requested vector base type is not supported for the negotiated vector version. significa que um float16 valor foi usado em uma conexão negociada em vectorTypeSupport=v1. Reconecte-se com v2.
  • Provided buffer length too small/large. Significa BufferLength que não correspondia sizeof(SQL_SS_VECTOR_STRUCT) exatamente a + (dimensão * sizeof(float)). Verifique se o buffer tem tamanho com sizeof(float) e não dois bytes por elemento, mesmo para uma float16 coluna.
  • Invalid vector dimension significa que a dimensão é zero, ou excede o máximo para o tipo base: 1.998 para float32 e 3.996 para float16.
  • Invalid vector base type significa que o type campo tinha um valor diferente de SQL_VECTOR_TYPE_FLOAT32 ou SQL_VECTOR_TYPE_FLOAT16. Uma estrutura inicializada a zero tem por padrão .float32
  • Se uma float16 coluna for reportada como varchar(max) contendo um array JSON, o servidor não tem a PREVIEW_FEATURES configuração com escopo do banco de dados ativada, nem a conexão negociada um nível inferior a v2.