Type de données vectorielles (ODBC)

Cet article documente le type de données SQL vectoriel comme implémenté par Microsoft ODBC Driver pour SQL Server à partir de la version 18.6.1.1. Ce document décrit le comportement du pilote Microsoft pour le vecteur et fournit des conseils d’utilisation, des notes spécifiques à l’API et des extraits de code. Pour obtenir une vue d’ensemble des types de données vectorielles, consultez Le type de données Vector.

Vue d’ensemble

Microsoft ODBC Driver pour SQL Server prend en charge en mode natif le type de données vectorielles . Les applications peuvent stocker, récupérer et traiter efficacement des incorporations numériques de dimension fixe couramment utilisées dans les charges de travail Machine Learning et IA. Le pilote expose la prise en charge des vecteurs par le biais d’API ODBC standard et de types de données C. Les applications peuvent interagir avec des colonnes vectorielles SQL Server sans modifier les flux de travail ODBC existants.

S’applique à : Microsoft ODBC Driver pour SQL Server 18.6.1.1 et versions ultérieures. Le support du float16 type de base nécessite la version 18.7.1.1 ou ultérieure.

Le support vectoriel est désactivé par défaut et doit être explicitement activé.

Types d’éléments de base

Une colonne vectorielle déclare un type d’élément de base. Le pilote prend en charge les deux types définis par SQL Server.

Type de base Indicateur de type Octets par élément sur le fil Dimension maximale Version du pilote
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 est la valeur par défaut. Pour utiliser un stockage à demi-précision, déclarez la colonne ou le paramètre comme VECTOR(<dimensions>, float16). Comme un float16 élément occupe la moitié des octets du fil, un float16 vecteur contient deux fois plus de dimensions dans la même limite de charge utile de 8 000 octets.

Important

Le tampon d’application est toujours un tableau de float (4 octets par élément) pour les deux types de base. Le haut-parleur passe de demi-précision sur le fil à simple précision dans votre tampon. Dimensionnez chaque tampon avec sizeof(float), jamais avec 2 octets par élément, même pour une float16 colonne.

Parce qu’il float16 y a moins de bits de mantissa que float32, un aller-retour à travers une float16 colonne est avec perte. Les valeurs sont arrondies à la valeur de demi-précision représentable la plus proche lors de l’insertion, et la valeur lue en arrière correspond à l’expansion float32 de cette valeur arrondie.

Sur le serveur, float16 il faut SQL Server 2025 (17.x) avec la PREVIEW_FEATURES configuration à portée de la base de données activée. Pour plus d’informations, consultez la prise en charge à demi-précision flottante du type de données vectorielles.

Représentation C native

Lorsque la prise en charge des vecteurs est activée, les colonnes vectorielles sont échangées à l’aide d’une structure C typée nommée 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: décrit le nombre d’éléments dans le vecteur
  • type: identifie le type d’élément de base, SQL_VECTOR_TYPE_FLOAT32 ou SQL_VECTOR_TYPE_FLOAT16
  • data.f32 / data.f16: pointe vers le tampon d’application contenant les valeurs vectorielles

Les deux membres de l’union sont déclarés comme float* et interchangeables, car le tampon côté client contient float32 des valeurs pour l’un ou l’autre type de base. Utilisez le membre qui documente votre intention.

Activer la prise en charge des vecteurs

Le vectorTypeSupport mot-clé chaîne de connexion sélectionne le niveau de support vectoriel natif que la connexion négocie.

Valeur Behavior
off (valeur par défaut) Les colonnes vectorielles apparaissent comme varchar(max) contenant des tableaux JSON.
v1 Prise en charge vectorielle native pour le float32 type de base.
v2 Prise en charge vectorielle native pour les float32 types et float16 types de base. Nécessite la version 18.7.1.1 ou ultérieure.

Vous pouvez aussi définir le niveau après avoir alloué la poignée de connexion, et avant la connexion, avec l’attribut SQL_COPT_SS_VECTOR_TYPE_SUPPORT pré-connexion connexion.

  • Le pilote Microsoft expose une liaison SQL_C_SS_VECTOR C spécifique au pilote et prend en charge SQL_C_BINARY la sortie vectorielle. Pratiquement:

    • Lorsque vous activez vectorTypeSupport=v1 ou v2, les API de récupération (par exemple, SQLGetData et SQLBindCol) peuvent retourner des colonnes vectorielles sous forme de SQL_C_SS_VECTOR .SQL_C_BINARY SQL_C_SS_VECTOR retourne le vecteur dans un formulaire compact et typé. SQL_C_BINARY retourne un payload de type varbinary.

    • Pour la liaison d’entrée ou de paramètres, le pilote prend en charge à la fois SQL_C_SS_VECTOR et SQL_C_BINARY. SQL_C_SS_VECTOR fournit une liaison d’entrée typée et compacte. SQL_C_BINARY est équivalent et portable. Utilisez SQL_C_SS_VECTOR quand vous souhaitez que le pilote traite la charge utile comme un type de vecteur natif.

    • Quand vectorTypeSupport=off, les colonnes vectorielles apparaissent sous forme de varchar(max) contenant des tableaux JSON.

v2 est un surensemble de v1, donc une connexion négociée en v2 gère float32 les colonnes exactement comme v1 le fait. Envoyer une float16 valeur sur une connexion négociée à v1 fait échouer avec Requested vector base type is not supported for the negotiated vector version. Utiliser v2 chaque fois que l’application peut rencontrer une float16 colonne.

Les applications doivent également définir la version ODBC sur ODBC 3.8 avant d’utiliser des types spécifiques au vecteur :

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

Formats de liaisonnement pris en charge

Intégration vectorielle native

Type C : SQL_C_SS_VECTOR

Ce format est recommandé pour les applications critiques en matière de performances.

Liaison binaire

Type C : SQL_C_BINARY

Les vecteurs sont renvoyés en utilisant la même disposition que SQL_C_SS_VECTOR. Les applications peuvent utiliser ce format pour les scénarios d’interopérabilité de bas niveau. La mémoire tampon du pointeur de données peut être contiguë ou non liée à l’adresse mémoire de structure.

Conseils sur l’API ODBC

Cette section décrit comment les API ODBC interagissent avec les données vectorielles SQL Server, notamment les exigences de disposition de mémoire tampon, NULL la gestion et les représentations de données prises en charge. Tous les comportements s’appliquent lorsque vectorTypeSupport l’environnement est défini sur v1 ou v2 et que l’environnement est configuré pour ODBC 3.8.

Chaque formule de taille de tampon dans cette section utilise sizeof(float) chaque élément pour les deux types de base, car le tampon côté client contient float32 toujours des valeurs. Une float16 colonne modifie les octets sur le fil, pas la disposition de votre tampon.

SQLBindCol

Utilisez SQLBindCol pour lier les colonnes vectorielles d'un jeu de résultats aux mémoires tampons d'application.

  • Appel classique :
    SQLRETURN SQLBindCol(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   ColumnNumber,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: utiliser SQL_C_SS_VECTOR ou SQL_C_BINARY.

  • TargetValuePtr: pointeur vers un SQL_SS_VECTOR_STRUCT contenant un tableau de float lorsque TargetType est égal à SQL_C_SS_VECTOR; sinon, pointeur vers une mémoire tampon dont la taille est indiquée par la valeur de StrLen_or_IndPtr.

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + le nombre d’octets alloués pour la mémoire tampon de colonne (dimension * 4).

  • StrLen_or_IndPtr: pointeur qui reçoit la longueur d’octet du vecteur retourné (SQL_DESC_OCTET_LENGTH). Sa valeur est sizeof(SQL_SS_VECTOR_STRUCT) + la taille du tableau float (dimension * 4).

Ces tailles sont les mêmes pour une float16 colonne. Le pilote agrandit chaque élément de demi-précision à un float à mesure qu’il remplit votre tampon, et indique la longueur agrandie.

Attentes de configuration des mémoires tampons

Mémoire tampon noncontigue (recommandé)

  • L’application alloue une SQL_SS_VECTOR_STRUCT par ligne.
  • L’application alloue de la mémoire pour data.f32.
  • Le pilote remplit les métadonnées de vecteur et écrit des valeurs d’élément dans la mémoire tampon float fournie.
    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());

Mémoire tampon contiguë

  • L’application alloue une mémoire tampon unique et ODBC le remplit en conséquence.
  • Le tableau float doit commencer immédiatement après le struct.
  • Le pilote définit data.f32 pour pointer vers cette région contiguë.
    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());

Gestion NULL pour SQLBindCol

Lorsque la valeur de colonne est NULL, le pilote définit *StrLen_or_IndPtr sur SQL_NULL_DATA et ne remplit pas la mémoire tampon. Vérifiez toujours l’indicateur avant d’accéder au contenu vectoriel.

Note

Le comportement de lecture et d’extraction de lignes pour les colonnes vectorielles est décrit en détail sous SQLFetch et SQLFetchScroll (consultez ces références d’API pour la sémantique d’extraction et les exemples de récupération de tableau).

SQLGetData

Permet SQLGetData de récupérer des données vectorielles à partir de colonnes indépendantes.

  • Appel classique :
    SQLRETURN SQLGetData(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   Col_or_Param_Num,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: utiliser SQL_C_SS_VECTOR ou SQL_C_BINARY.

  • TargetValuePtr: pointeur vers un SQL_SS_VECTOR_STRUCT contenant un tableau de float lorsque TargetType est égal à SQL_C_SS_VECTOR; sinon, pointeur vers une mémoire tampon dont la taille est indiquée par la valeur de StrLen_or_IndPtr.

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + le nombre d’octets alloués pour la mémoire tampon de colonne (dimension * 4).

  • StrLen_or_IndPtr: pointeur qui reçoit la longueur d’octet du vecteur retourné (SQL_DESC_OCTET_LENGTH). Sa valeur est sizeof(SQL_SS_VECTOR_STRUCT) + la taille du tableau float (dimension * 4).

La récupération par segments n'est pas prise en charge. Vous devez récupérer l’intégralité du vecteur dans un appel.

Exemple ( vecteur natif) :

    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);

Gestion NULL pour SQLGetData

Lorsque la valeur de colonne est NULL, le pilote définit *StrLen_or_IndPtr sur SQL_NULL_DATA et ne remplit pas la mémoire tampon. Vérifiez toujours l’indicateur avant d’accéder au contenu vectoriel.

Note

Le comportement de lecture et d’extraction de lignes pour les colonnes vectorielles est décrit en détail sous SQLFetch et SQLFetchScroll (consultez ces références d’API pour la sémantique d’extraction et les exemples de récupération de tableau).

SQLFetch

Utilisez SQLFetch pour extraire la ligne suivante et matérialiser correctement les colonnes liées SqlVector.

  • Appel classique :
    SQLRETURN SQLFetch(
     SQLHSTMT     StatementHandle);

Appelez SQLFetch dans la boucle standard avec SqlVector des colonnes déjà liées par SQLBindCol. Vous pouvez également utiliser SQLGetData pour récupérer des données dans la mémoire tampon de l'application.

Exemple ( vecteur natif) :

    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

Utilisez SQLFetchScroll pour récupérer des ensembles de lignes en fonction d’une orientation spécifiée (suivant, précédent, absolu, relatif, signet). Le pilote copie correctement les données vectorielles dans les mémoires tampons d’application.

  • Appel classique :
    SQLRETURN SQLFetchScroll(
      SQLHSTMT      StatementHandle,
      SQLSMALLINT   FetchOrientation,
      SQLLEN        FetchOffset);

Exemple ( vecteur natif) :

    // 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

Permet SQLBindParameter d’envoyer des valeurs vectorielles à SQL Server.

  • Appel classique :
    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: pointe vers un SQL_SS_VECTOR_STRUCT rempli
  • ColumnSize: ignoré pour les paramètres d’entrée. Pour les paramètres de sortie et les scénarios de données à l’exécution, spécifiez la taille totale du vecteur : sizeof(SQL_SS_VECTOR_STRUCT) + (taille du tableau float )
  • DecimalDigits: ignoré pour les paramètres d’entrée. Pour les paramètres de sortie et les scénarios de données à l’exécution, spécifiez le type de base de vecteurs
  • BufferLength: ≥ sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float))
  • *StrLen_or_IndPtr: doit avoir la même taille totale

D’où vient le type de base

Le conducteur lit le type d’élément de base à un endroit différent selon la direction du paramètre. Se tromper est la cause Invalid vector dimension la plus fréquente ou Provided buffer length too small/large les erreurs sur un float16 paramètre.

Type de paramètres Source de type de base Source dimensionnelle
Entrée, et entrée/sortie Le type champ du SQL_SS_VECTOR_STRUCT passage Le dimension corps de la même structure
Sortie pure DecimalDigits Dérivé de ColumnSize comme (ColumnSize - sizeof(SQL_SS_VECTOR_STRUCT)) / sizeof(float)
Data-at-execution DecimalDigits Dérivé de ColumnSize, et vérifié avec la longueur passée à SQL_LEN_DATA_AT_EXEC

Pour un paramètre d’entrée, BufferLength doit être égal sizeof(SQL_SS_VECTOR_STRUCT) exactement à + (dimension * sizeof(float)). Une valeur plus grande ou plus petite échoue plutôt que d’être tolérée.

Exemple ( vecteur natif, 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);

Exemple ( vecteur natif, float16) :

Seul le type champ change. Le tableau de valeurs reste un float tableau et cb est calculé de la même manière.

    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);

Exemple (float16 paramètre de sortie) :

Un paramètre de sortie pur ne porte pas de structure d’entrée, donc le type de base est passé dans DecimalDigits et la dimension est dérivée 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);

Gestion NULL pour SQLBindParameter

Les applications peuvent indiquer un vecteur à l'aide de l'une ou l'autre des approches prises en charge :

  • Définir *StrLen_or_IndPtr sur SQL_NULL_DATA et passer NULL en tant que ParameterValuePtr

  • Fournissez un(e) SQL_SS_VECTOR_STRUCT avec :

    Type d’ensemble de dimension fixé au type de base de la colonne data.f32 = NULL

SQLPutData

Le pilote prend en charge SQLPutData pour les paramètres vectoriels avec ces contraintes :

  • Vous devez fournir l’intégralité du vecteur dans le premier appel.

  • Le pilote ne prend pas en charge la transmission de vecteurs segmentés ou incrémentiels.

  • NULL la gestion suit les mêmes règles que SQLBindParameter.

  • Appel classique :

    SQLRETURN SQLPutData(
        SQLHSTMT     StatementHandle,
        SQLPOINTER   DataPtr,
        SQLLEN       StrLen_or_Ind);
  • DataPtr: pointe vers un SQL_SS_VECTOR_STRUCT rempli
  • StrLen_or_Ind: sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float))

Exemple ( vecteur natif) :

    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);
    }

Métadonnées du descripteur

Lorsque vous activez la prise en charge des vecteurs, Microsoft ODBC Driver pour SQL Server expose les métadonnées vectorielles via des API de descripteur ODBC standard. Les applications peuvent utiliser des informations de descripteur pour découvrir les détails du schéma vectoriel, les tailles de mémoire tampon de calcul et configurer correctement les liaisons pour les paramètres et les jeux de résultats.

Valeurs de champ de descripteur pour vector

Le tableau suivant récapitule les valeurs de champ de descripteur pour les colonnes et paramètres de vecteur SQL Server.

Champ du descripteur Valeur Descriptif
SQL_DESC_TYPE SQL_SS_VECTOR (-156) Identificateur de type de données SQL de base
SQL_DESC_CONCISE_TYPE SQL_SS_VECTOR Type de données SQL concis
SQL_DESC_TYPE_NAME vector Nom du type SQL
SQL_DESC_LOCAL_TYPE_NAME vector Nom du type local du pilote logiciel
SQL_DESC_LENGTH sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float)) Taille logique de la valeur vectorielle
SQL_DESC_OCTET_LENGTH Identique à SQL_DESC_LENGTH Taille physique en octets
SQL_DESC_PRECISION Identique à SQL_DESC_LENGTH Utilisé pour signaler la taille du vecteur
SQL_DESC_SCALE SQL_VECTOR_TYPE_FLOAT32 ou SQL_VECTOR_TYPE_FLOAT16 Type d'élément de vecteur de base
SQL_CA_SS_VECTOR_DIMENSION dimension Nombre d’éléments dans le vecteur
SQL_DESC_DISPLAY_SIZE dimension * VECTOR_FLOAT32_TO_CHAR_JSON_MAX_SIZE Longueur d’affichage JSON maximale
SQL_DESC_FIXED_PREC_SCALE SQL_FALSE Vector n’a pas de précision/d’échelle fixe
SQL_DESC_NULLABLE SQL_NULLABLE Les colonnes vectorielles autorisent les NULL valeurs
SQL_DESC_NUM_PREC_RADIX 0 Type non numérique
SQL_DESC_SEARCHABLE SQL_PRED_NONE Non utilisable dans les prédicats
SQL_DESC_UNSIGNED SQL_TRUE Le type d’élément est non signé
SQL_DESC_AUTO_UNIQUE_VALUE SQL_FALSE Pas unique automatiquement
SQL_DESC_CASE_SENSITIVE SQL_FALSE Non sensible à la casse
SQL_DESC_UPDATABLE SQL_ATTR_READWRITE_UNKNOWN Possibilité de mise à jour inconnue

SQL_DESC_LENGTH, SQL_DESC_OCTET_LENGTH, et SQL_DESC_PRECISION tous décrivent le tampon côté client, donc ils rapportent sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float)) pour une float16 colonne ainsi qu’un float32 un. Les deux ne diffèrent que par le nombre d’octets que SQL Server stocke et transmet.

SQL_DESC_SCALE est le seul corps descripteur qui distingue les types de base. La lecture permet à une application de découvrir si une colonne est float32 ou float16.

SQLColAttribute pour la dimension vectorielle

À partir de la version 18.7.1.1, SQL_CA_SS_VECTOR_DIMENSION elle retourne directement le nombre d’éléments d’une colonne vectoriel, de sorte qu’une application n’a plus besoin de le dériver à partir d’un champ de longueur :

    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 */

Vous pouvez aussi définir SQL_CA_SS_VECTOR_DIMENSION un descripteur d’application ou un paramètre vectoriel sur l’IPD. Le placer sur un autre type de paramètre renvoie une erreur de descripteur invalide.

SQLDescribeCol

Lorsque vous appelez SQLDescribeCol pour une colonne vectorielle :

  • DataType est SQL_SS_VECTOR
  • ColumnSize correspond à SQL_DESC_PRECISION
  • DecimalDigits est l’indicateur de type d’élément de base, et non une échelle numérique : 0 pour float32 et 1 pour float16
  • Nullable est SQL_NULLABLE

La taille de colonne signalée représente la taille de charge utile vectorielle native : sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float))

SQLDescribeParam

Lorsque vous utilisez SQLDescribeParam pour un paramètre vectoriel :

  • DataType est SQL_SS_VECTOR
  • ColumnSize est égale à la taille de charge utile vectorielle native
  • DecimalDigits est l’indicateur de type d’élément de base, et non une échelle numérique : 0 pour float32 et 1 pour float16
  • Nullable est SQL_NULLABLE

Ces informations permettent aux applications d’allouer correctement des mémoires tampons de paramètres avant la liaison.

SQLColAttribute

  • Utilisez SQLColAttribute(hstmt, ColumnNumber, SQL_DESC_OCTET_LENGTH, ...) pour obtenir la longueur précise en octets de la charge utile du vecteur. SQL_DESC_LENGTH et SQL_DESC_PRECISION peut contenir des valeurs spécifiques au pilote. Pour le nombre d’octets, préférez SQL_DESC_OCTET_LENGTH.

    • NULLgestion : lorsqu’une colonne est NULL, SQLColAttribute (ou la méthode utilisée avec StrLen_or_IndPtr) retourne SQLBindColSQL_NULL_DATA. Vérifiez la présence de SQL_NULL_DATA avant d’utiliser les longueurs ou les tampons retournés.

Copie en bloc (BCP)

Vous pouvez importer et exporter des colonnes vectorielles en bloc via des fichiers BCP et l’API bcp_bind , comme d’autres types de données. Actuellement, l’importation et l’exportation vectorielles prennent uniquement en charge le format natif (SQLVECTOR) ou varbinary (SQLBINARY), mais pas le format caractère. La conversion entre le type de vecteur et le type de caractère n’est pas prise en charge.

La copie en bloc honore le même niveau de support que le reste du conducteur. Une float16 colonne nécessite une connexion négociée en vectorTypeSupport=v2. Dans l’utilitaire bcp , utilisez -z0 pour float32 et -z1 pour float16. Pour plus d’informations, consultez l’utilitaire bcp.

Pour plus d’informations sur le jeton de type, la longueur de préfixe par défaut et la longueur de champ par défaut pour le vecteur, consultez Type de stockage de fichiers, Longueur de préfixe et Longueur du champ.

bcp_gettypename

Lorsque vous utilisez bcp_gettypename pour obtenir le nom de type SQL du vecteur, il retourne le jeton de type BCP (SQLVECTOR) et "vector".

bcp_bind

Permet bcp_bind d’insérer en bloc des variables de programme dans une colonne vectorielle .

Appel classique :

RETCODE bcp_bind (
        HDBC hdbc,
        LPCBYTE pData,
        INT cbIndicator,
        DBINT cbData,
        LPCBYTE pTerm,
        INT cbTerm,
        INT eDataType,
        INT idxServerCol);
  • pData: si cbIndicator est zéro, contient un pointeur vers les données SQL_SS_VECTOR_STRUCT, avec un tableau de flottants à l’intérieur de celui-ci (vectorStruct.data.f32 champ). S’il cbIndicator n’est pas différent de zéro, l’indicateur apparaît en mémoire directement avant les données. Donc, pData pointe vers une mémoire tampon qui a d'abord cbIndicator octets d'indicateur de longueur, suivis de la struct.
  • cbData: si elle est fournie, doit avoir une valeur exactement égale à - sizeof(SQL_SS_VECTOR_STRUCT) + (sizeof(float) * dimension). Si ce n’est pas le cas, une erreur se produit. C’est la même chose pour les deux types de base, car le tampon lié conserve float32 des valeurs dans les deux sens.
  • eDataType: SQLVECTOR ou SQLBINARY

Fixez le type champ de la structure au type de base de la colonne. Pour une float16 colonne, le pilote convertit le tableau borné float32 en demi-précision au fur et à mesure qu’il construit la charge utile du fil, de sorte qu’un fichier de données écrit au format natif contient deux octets par élément.

Lorsque vous importez des données dans une colonne vectorielle, bcp_binddéfinissez eDataType sur SQLVECTOR ou SQLBINARY. Dans les deux cas, vous devez fournir des données sous la forme .SQL_SS_VECTOR_STRUCT

Résolution des problèmes et conseils

  • Si SQLGetTypeInfo ne liste pas VECTOR, passez au stockage des vecteurs en tant que varchar.
  • Requested vector base type is not supported for the negotiated vector version. signifie qu’une float16 valeur a été utilisée sur une connexion négociée à vectorTypeSupport=v1. Reconnectez-vous avec v2.
  • Provided buffer length too small/large. signifie BufferLength que ce n’est pas correspondant sizeof(SQL_SS_VECTOR_STRUCT) exactement à + (dimension * sizeof(float)). Vérifiez que le tampon est dimensionné avec sizeof(float) plutôt que deux octets par élément, même pour une float16 colonne.
  • Invalid vector dimension signifie que la dimension est nulle, ou dépasse le maximum pour le type de base : 1 998 pour float32 et 3 996 pour float16.
  • Invalid vector base type signifie que le type corps avait une valeur autre que SQL_VECTOR_TYPE_FLOAT32 ou SQL_VECTOR_TYPE_FLOAT16. Une structure initialisée à zéro est par défaut .float32
  • Si une float16 colonne est rapportée comme varchar(max) contenant un tableau JSON, le serveur n’a pas activé la PREVIEW_FEATURES configuration avec portée de base de données, ou la connexion négociée n’est pas un niveau inférieur à v2.