ベクター データ型 (ODBC)

この記事では、バージョン 18.6.1.1 以降の Microsoft ODBC Driver for SQL Server によって実装された ベクター SQL データ型について説明します。 このドキュメントでは、 ベクトルに対する Microsoft ドライバーの動作の概要を説明し、使用ガイダンス、API 固有の注意事項、およびコード スニペットについて説明します。 ベクター データ型の概要については、ベクター データ に関するページを参照してください。

概要

Microsoft ODBC Driver for SQL Server では、 ベクター データ型がネイティブにサポートされています。 アプリケーションは、機械学習と AI ワークロードでよく使用される固定次元の数値埋め込みを効率的に格納、取得、および処理できます。 ドライバーは、標準の ODBC API と C データ型を通じてベクターサポートを公開します。 アプリケーションは、既存の ODBC ワークフローを変更することなく、SQL Server ベクター列と相互運用できます。

適用対象: Microsoft ODBC Driver for SQL Server 18.6.1.1 以降のバージョン。 float16ベースタイプのサポートにはバージョン18.7.1.1以降が必要です。

ベクターサポートはデフォルトで無効化されており、明示的に有効化する必要があります。

基底要素の種類

ベクトル列はベース要素タイプを宣言します。 このドライバはSQL Serverが定義する両方のタイプをサポートしています。

基本型 型を表すインジケーター ワイヤー上の各要素あたりのバイト数 最大寸法 ドライバーのバージョン
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 はデフォルト値です。 半精度ストレージを使用するには、列またはパラメータを VECTOR(<dimensions>, float16)と宣言します。 float16要素が配線のバイトの半分を占めるため、同じ8,000バイトのペイロード制限内でfloat16ベクトルは2倍の次元を保持できます。

Important

アプリケーションバッファは、両方のベース型に対して常にfloatの配列(各要素あたり4バイト)です。 ドライバーはバッファ内でワイヤーの半精度と単精度の変換を行います。 すべてのバッファは1要素あたり2バイトで sizeof(float)サイズを付け、 float16 列でも2バイトではいけません。

float16float32よりも尾数ビットが少ないため、float16列を通る往復は損失があります。 値は挿入時に最も近い表現可能な半精度値に丸められ、読み戻される値はその丸め値の float32 展開となります。

サーバー側では、float16 2025(17.x)SQL Server、PREVIEW_FEATURESデータベーススコープ設定を有効にする必要があります。 詳細については、 ベクター データ型での半精度浮動小数点数のサポートを参照してください

ネイティブ C 表現

ベクターのサポートが有効になっている場合、 ベクター 列は、 SQL_SS_VECTOR_STRUCTという名前の型指定された C 構造体を使用して交換されます。

    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: ベクトル内の要素の数を表します。
  • type: は基本要素型、 SQL_VECTOR_TYPE_FLOAT32 または SQL_VECTOR_TYPE_FLOAT16
  • data.f32 / data.f16: はベクトル値を含むアプリケーションバッファを指しています

両方のユニオンメンバーは float* として宣言され、クライアント側のバッファがどちらのベースタイプに対して float32 値を保持しているため、互換性があります。 あなたの意思を文書化した会員を使いましょう。

ベクトルのサポートを有効にする

vectorTypeSupport 接続文字列キーワードは、接続が交渉するネイティブベクトルのサポートレベルを選択します。

価値 Behavior
off (既定値) ベクター列はJSON配列を含む varchar(max) として表示されます。
v1 float32ベース型のネイティブベクターサポート。
v2 float32ベース型とfloat16ベース型の両方でネイティブベクターサポート。 ドライバーバージョン18.7.1.1以降が必要です。

また、接続ハンドルを割り当てた後、接続前に SQL_COPT_SS_VECTOR_TYPE_SUPPORT pre-connect接続属性でレベルを設定することもできます。

  • Microsoftドライバはドライバー固有のCバインディングSQL_C_SS_VECTORを公開し、ベクター出力用のSQL_C_BINARYをサポートしています。 実際に:

    • vectorTypeSupport=v1v2を有効にすると、取得API(例:SQLGetDataSQLBindCol)はベクター列をSQL_C_SS_VECTORまたはSQL_C_BINARYのいずれかで返すことができます。 SQL_C_SS_VECTOR は、型指定されたコンパクトな形式でベクターを返します。 SQL_C_BINARYvarbinary ペイロードを返します。

    • 入力やパラメータのバインディングについては、ドライバは SQL_C_SS_VECTORSQL_C_BINARYの両方をサポートしています。 SQL_C_SS_VECTOR は、型指定されたコンパクトな入力バインドを提供します。 SQL_C_BINARY は同等であり、移植可能です。 ドライバーでペイロードをネイティブ SQL_C_SS_VECTOR型として扱う場合は、を使用します。

    • vectorTypeSupport=offすると、ベクター列は JSON 配列を含む varchar(max) として表示されます。

v2v1のスーパーセットであるため、接続はv2で交渉され、v1と同様にfloat32列を処理します。 v1で交渉された接続に対してfloat16値を送ると、アプリケーションがfloat16列に遭遇するたびにRequested vector base type is not supported for the negotiated vector version. Use v2で失敗します。

アプリケーションでは、ベクター固有の型を使用する前に、ODBC バージョンを ODBC 3.8 に設定する必要もあります。

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

サポートされているバインド形式

ネイティブ ベクター バインド

C 型: SQL_C_SS_VECTOR

この形式は、パフォーマンスが重要なアプリケーションに推奨されます。

バイナリ結合

C 型: SQL_C_BINARY

ベクターは、 SQL_C_SS_VECTORと同じレイアウトを使用して返されます。 アプリケーションでは、低レベルの相互運用性のシナリオでこの形式を使用できます。 データ ポインター バッファーは、連続している場合と、構造体のメモリ アドレスで連続していない場合があります。

ODBC API ガイダンス

このセクションでは、バッファー レイアウトの要件、 NULL 処理、サポートされるデータ表現など、ODBC API が SQL Server ベクター データと対話する方法について説明します。 すべての動作は、 vectorTypeSupportv1 または v2 に設定され、環境がODBC 3.8に設定されている場合に適用されます。

この節のすべてのバッファサイズの式は、両方のベースタイプに対して各要素あたり sizeof(float) を使用します。なぜならクライアント側のバッファが常に float32 値を保持しているからです。 float16列は配線上のバイトを変えるもので、バッファのレイアウトを変えるわけではありません。

SQLBindCol

SQLBindColを使用して、結果セット内のベクター列をアプリケーション バッファーにバインドします。

  • 一般的な呼び出し:
    SQLRETURN SQLBindCol(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   ColumnNumber,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: SQL_C_SS_VECTOR または SQL_C_BINARYを使用します。

  • TargetValuePtr: SQL_SS_VECTOR_STRUCTされている場合は TargetType 配列を持つSQL_C_SS_VECTORへのポインター。それ以外の場合は、StrLen_or_IndPtrの値としてサイズを持つバッファーへのポインター。

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + 列バッファーに割り当てられたバイト数 (ディメンション * 4)。

  • StrLen_or_IndPtr: 返されたベクター (SQL_DESC_OCTET_LENGTH) のバイト長を受け取るポインター。 値は sizeof(SQL_SS_VECTOR_STRUCT) + float 配列サイズ (次元 * 4) です。

これらのサイズは float16 列でも同じです。 ドライバーは各半精度要素をバッファを満たすごとに float に展開し、拡張された長さを報告します。

バッファー レイアウトの期待値

非連続バッファー (推奨)

  • アプリケーションは、行ごとに 1 つの SQL_SS_VECTOR_STRUCT を割り当てます。
  • アプリケーションは、 data.f32にメモリを割り当てます。
  • ドライバーは、ベクター メタデータを設定し、指定された float バッファーに要素の値を書き込みます。
    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());

連続するバッファー

  • アプリケーションは 1 つのバッファーを割り当て、それに応じて ODBC がバッファーを埋めます。
  • float 配列は、構造体の直後に開始する必要があります。
  • ドライバーは、この連続した領域を指す data.f32 を設定します。
    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());

SQLBindCol の NULL 処理

列の値がNULLのときに、ドライバーは*StrLen_or_IndPtrSQL_NULL_DATAに設定し、バッファーを使用しません。 ベクトルの内容にアクセスする前に、必ずインジケーターを確認してください。

ベクター列の読み取りと行フェッチの動作については、SQLFetchSQLFetchScrollで詳しく説明します (フェッチ セマンティクスと配列フェッチの例については、これらの API リファレンスを参照してください)。

SQLGetData

バインドされていない列からベクター データを取得するには、 SQLGetData を使用します。

  • 一般的な呼び出し:
    SQLRETURN SQLGetData(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   Col_or_Param_Num,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: SQL_C_SS_VECTOR または SQL_C_BINARYを使用します。

  • TargetValuePtr: SQL_SS_VECTOR_STRUCTされている場合は TargetType 配列を持つSQL_C_SS_VECTORへのポインター。それ以外の場合は、StrLen_or_IndPtrの値としてサイズを持つバッファーへのポインター。

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + 列バッファーに割り当てられたバイト数 (ディメンション * 4)。

  • StrLen_or_IndPtr: 返されたベクター (SQL_DESC_OCTET_LENGTH) のバイト長を受け取るポインター。 値は sizeof(SQL_SS_VECTOR_STRUCT) + float 配列サイズ (次元 * 4) です。

チャンク取得はサポートされていません。 ベクター全体を 1 回の呼び出しで取得する必要があります。

例 (ネイティブ ベクター):

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

SQLGetData の NULL 処理

列の値がNULLのときに、ドライバーは*StrLen_or_IndPtrSQL_NULL_DATAに設定し、バッファーを使用しません。 ベクトルの内容にアクセスする前に、必ずインジケーターを確認してください。

ベクター列の読み取りと行フェッチの動作については、SQLFetchSQLFetchScrollで詳しく説明します (フェッチ セマンティクスと配列フェッチの例については、これらの API リファレンスを参照してください)。

SQLFetch

SQLFetchを使用して次の行を取得し、バインドされたSqlVector列を適切に実装します。

  • 一般的な呼び出し:
    SQLRETURN SQLFetch(
     SQLHSTMT     StatementHandle);

SQLFetchを介して既にバインドされているSqlVector列を使用して、標準ループ内のSQLBindColを呼び出します。 または、 SQLGetData を使用してアプリケーション バッファーにデータを取得します。

例 (ネイティブ ベクター):

    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

SQLFetchScrollを使用して、指定した向き (次、前、絶対、相対、ブックマーク) に従って行セットをフェッチします。 ドライバーは、ベクター データをアプリケーション バッファーに正しくコピーします。

  • 一般的な呼び出し:
    SQLRETURN SQLFetchScroll(
      SQLHSTMT      StatementHandle,
      SQLSMALLINT   FetchOrientation,
      SQLLEN        FetchOffset);

例 (ネイティブ ベクター):

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

SQLBindParameterを使用して、ベクター値を SQL Server に送信します。

  • 一般的な呼び出し:
    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: 設定された値を指します。 SQL_SS_VECTOR_STRUCT
  • ColumnSize: 入力パラメーターでは無視されます。 出力パラメーターと実行時データのシナリオでは、ベクトルの合計サイズを指定します: sizeof(SQL_SS_VECTOR_STRUCT) + (float 配列サイズ)
  • DecimalDigits: 入力パラメーターでは無視されます。 出力パラメーターと実行時データのシナリオでは、ベクターの基本型を指定します
  • BufferLength: ≥ sizeof(SQL_SS_VECTOR_STRUCT) + (ディメンション * sizeof(float))
  • *StrLen_or_IndPtr: 同じ合計サイズを保持する必要があります

基底型の出所

ドライバーはパラメータの方向に応じて異なる場所からベース要素タイプを読み取ります。 これを誤ることが、float16パラメータでInvalid vector dimensionまたはProvided buffer length too small/largeエラーが発生する最も一般的な原因です。

パラメータの種類 ベースタイプソース 次元源
入力と入力/出力 通り過ぎるSQL_SS_VECTOR_STRUCTのそのtypeフィールド 同じ構造の dimension
純粋な出力 DecimalDigits ColumnSizeから導出(ColumnSize - sizeof(SQL_SS_VECTOR_STRUCT)) / sizeof(float)
実行時のデータ DecimalDigits ColumnSizeから導き、渡された長さと照合したSQL_LEN_DATA_AT_EXEC

入力パラメータの場合、 BufferLength は正確に sizeof(SQL_SS_VECTOR_STRUCT) + (次元 * sizeof(float))に等しくなければなりません。 大きいまたは小さい価値は許容されるのではなく失敗します。

例(ネイティブ ベクトル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);

例(ネイティブ ベクトルfloat16):

変わるのは type 場だけです。 値配列は float 配列のままで、 cb も同じ方法で計算されます。

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

例(float16 出力パラメータ):

純粋な出力パラメータは入力構造を持たないため、ベース型は DecimalDigits で渡され、次元は 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);

SQLBindParameter の NULL 処理

アプリケーションは、サポートされているいずれかの方法を使用して、 NULL ベクターを示すことができます。

  • *StrLen_or_IndPtrSQL_NULL_DATAに設定し、次のようにNULL渡しますParameterValuePtr

  • SQL_SS_VECTOR_STRUCT に次のものを指定してください。

    dimension set type は列の基本型に設定されています data.f32 = NULL

SQLPutData

ドライバーは、次の制約を持つベクター パラメーターの SQLPutData をサポートしています。

  • 最初の呼び出しでベクター全体を指定する必要があります。

  • ドライバーは、チャンクまたは増分ベクター転送をサポートしていません。

  • NULL 処理は、 SQLBindParameterと同じ規則に従います。

  • 一般的な呼び出し:

    SQLRETURN SQLPutData(
        SQLHSTMT     StatementHandle,
        SQLPOINTER   DataPtr,
        SQLLEN       StrLen_or_Ind);
  • DataPtr: 設定された値を指します。 SQL_SS_VECTOR_STRUCT
  • StrLen_or_Ind: sizeof(SQL_SS_VECTOR_STRUCT) + (ディメンション * sizeof(float))

例 (ネイティブ ベクター):

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

記述子メタデータ

ベクターのサポートを有効にすると、Microsoft ODBC Driver for SQL Server は標準の ODBC 記述子 API を介してベクター メタデータを公開します。 アプリケーションでは、記述子情報を使用して、ベクター スキーマの詳細、コンピューティング バッファー サイズを検出し、パラメーターと結果セットのバインドを正しく構成できます。

ベクターの記述子フィールド値

次の表は、SQL Server ベクター 列とパラメーターの記述子フィールド値をまとめたものです。

記述子フィールド 価値 Description
SQL_DESC_TYPE SQL_SS_VECTOR (-156) SQL ベースデータ型識別子
SQL_DESC_CONCISE_TYPE SQL_SS_VECTOR 簡潔な SQL データ型
SQL_DESC_TYPE_NAME vector SQL 型名
SQL_DESC_LOCAL_TYPE_NAME vector ドライバー・ローカルタイプ名
SQL_DESC_LENGTH sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float)) ベクター値の論理サイズ
SQL_DESC_OCTET_LENGTH SQL_DESC_LENGTH と同じ 物理サイズ (バイト単位)
SQL_DESC_PRECISION SQL_DESC_LENGTH と同じ ベクター サイズを報告するために使用されます
SQL_DESC_SCALE SQL_VECTOR_TYPE_FLOAT32 または SQL_VECTOR_TYPE_FLOAT16 ベクター基本要素の型
SQL_CA_SS_VECTOR_DIMENSION dimension ベクトル内の要素数
SQL_DESC_DISPLAY_SIZE dimension * VECTOR_FLOAT32_TO_CHAR_JSON_MAX_SIZE 最大 JSON 表示長
SQL_DESC_FIXED_PREC_SCALE SQL_FALSE ベクターに固定の精度/スケールがない
SQL_DESC_NULLABLE SQL_NULLABLE ベクター列を使用すると、 NULL 値を使用できます
SQL_DESC_NUM_PREC_RADIX 0 数値以外の型
SQL_DESC_SEARCHABLE SQL_PRED_NONE 述語では使用できません
SQL_DESC_UNSIGNED SQL_TRUE 要素の型が符号なしである
SQL_DESC_AUTO_UNIQUE_VALUE SQL_FALSE 自動の一意性ではありません
SQL_DESC_CASE_SENSITIVE SQL_FALSE 大文字と小文字を区別しない
SQL_DESC_UPDATABLE SQL_ATTR_READWRITE_UNKNOWN 更新可能性が不明

SQL_DESC_LENGTHSQL_DESC_OCTET_LENGTHSQL_DESC_PRECISION はすべてクライアント側バッファを記述するため、float16列とfloat32列の両方でsizeof(SQL_SS_VECTOR_STRUCT)+(次元 * sizeof(float))を報告します。 両者はSQL Serverが格納・送信するバイト数にのみ異なります。

SQL_DESC_SCALE は基本型を区別する唯一の記述子フィールドです。 これを読むことで、アプリケーションは列が float32float16かを判断します。

SQLColAttribute for vector dimension

バージョン18.7.1.1以降、 SQL_CA_SS_VECTOR_DIMENSION はベクトル列の要素数を直接返すため、アプリケーションはもはや長さフィールドからそれを導出する必要がなくなりました。

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

また、アプリケーションのディスクリプタやベクターパラメータのIPDで SQL_CA_SS_VECTOR_DIMENSION を設定することもできます。 他のパラメータに設定すると無効なディスクリプタフィールドエラーが返されます。

SQLDescribeCol

SQLDescribeCol列のを呼び出すとき:

  • DataTypeSQL_SS_VECTOR です
  • ColumnSizeSQL_DESC_PRECISION に一致します
  • DecimalDigitsは基本要素タイプの指標であり、数値スケールではありません。float3201float16
  • NullableSQL_NULLABLE です

報告される列のサイズは、ネイティブ ベクター ペイロード サイズ ( sizeof(SQL_SS_VECTOR_STRUCT) + (ディメンション * sizeof(float)) を表します。

SQLDescribeParam

SQLDescribeParam パラメーターにを使用する場合:

  • DataTypeSQL_SS_VECTOR です
  • ColumnSize はネイティブ ベクター ペイロード サイズと等しい
  • DecimalDigitsは基本要素タイプの指標であり、数値スケールではありません。float3201float16
  • NullableSQL_NULLABLE です

この情報により、アプリケーションはバインド前にパラメーター バッファーを正しく割り当てることができます。

SQLColAttribute

  • SQLColAttribute(hstmt, ColumnNumber, SQL_DESC_OCTET_LENGTH, ...)を使用して、ベクター ペイロードの正確なバイト長を取得します。 SQL_DESC_LENGTHSQL_DESC_PRECISION にはドライバー固有の値が含まれます。 バイト数の場合は、 SQL_DESC_OCTET_LENGTHを優先します。

    • NULL処理: 列がNULLされると、SQLColAttribute (またはStrLen_or_IndPtrで使用されるSQLBindCol) はSQL_NULL_DATAを返します。 返される長さまたはバッファーを使用する前に、 SQL_NULL_DATA を確認してください。

一括コピー (BCP)

他のデータ型と同様に、BCP ファイルと bcp_bind API を使用してベクター列を一括インポートおよびエクスポートできます。 現在、ベクターのインポートとエクスポートではネイティブ形式 (SQLVECTOR) または varbinary (SQLBINARY) のみがサポートされていますが、文字形式はサポートされていません。 ベクター型と文字型の間の変換はサポートされていません。

バルクコピーはドライバーの他の部分と同じサポートレベルを尊重します。 float16列はvectorTypeSupport=v2で交渉された接続が必要です。 BCPユーティリティでは、float32-z0float16-z1を使いましょう。 詳細については、「 bcp ユーティリティ」を参照してください。

トークン、既定のプレフィックス長、およびベクターの既定のフィールド長の詳細については、「ファイル ストレージの種類プレフィックスの長さおよびフィールドの長さ」を参照してください。

bcp_gettypename

bcp_gettypenameを使用してベクターの SQL 型名を取得すると、BCP 型トークン (SQLVECTOR) と"vector"が返されます。

bcp_bind

bcp_bindを使用して、プログラム変数をベクター列に一括挿入します。

一般的な呼び出し:

RETCODE bcp_bind (
        HDBC hdbc,
        LPCBYTE pData,
        INT cbIndicator,
        DBINT cbData,
        LPCBYTE pTerm,
        INT cbTerm,
        INT eDataType,
        INT idxServerCol);
  • pData: cbIndicator が 0 の場合は、データへのポインター SQL_SS_VECTOR_STRUCT 含み、その中に float 配列データが含まれます (フィールドvectorStruct.data.f32 )。 cbIndicatorが 0 以外の場合、インジケーターはメモリ内のデータの直前に表示されます。 したがって、 pData は、最初に cbIndicator バイトの長さのインジケーターを持ち、その後にベクター構造体が続くバッファーを指します。
  • cbData: 指定する場合は、 sizeof(SQL_SS_VECTOR_STRUCT) + (sizeof(float) * ディメンション) と正確に等しい値を指定する必要があります。 そうでない場合は、エラーが発生します。 これは両方のベースタイプで同様で、バウンドバッファはどちらの方向にも float32 値を保持します。
  • eDataType: SQLVECTOR または SQLBINARY

構造体の type フィールドを列の基本型に設定します。 float16列の場合、ドライバーは配列float32配列を半精度に変換しながら配線ペイロードを構築するため、ネイティブ形式で書かれたデータファイルは各要素あたり2バイトを保持します。

bcp_bindを使用してデータをベクター列にインポートする場合は、eDataTypeSQLVECTORまたはSQLBINARYに設定します。 どちらの場合も、 SQL_SS_VECTOR_STRUCTの形式でデータを提供する必要があります。

トラブルシューティングとヒント

  • SQLGetTypeInfo VECTORが一覧表示されない場合は、ベクターを varchar として格納することにフォールバックします。
  • Requested vector base type is not supported for the negotiated vector version. vectorTypeSupport=v1で交渉された接続にfloat16価値が使われたことを意味します。 v2と再びつながってください。
  • Provided buffer length too small/large. つまり BufferLengthsizeof(SQL_SS_VECTOR_STRUCT) +(次元 * sizeof(float))と正確に一致しなかったということです。 バッファのサイズが1要素あたり2バイトではなく sizeof(float) で設定されているか確認してください。 float16 列でも同じです。
  • Invalid vector dimension 次元がゼロ、または基本型の最大値( float32 では1,998、 float16では3,996)を超えることを意味します。
  • Invalid vector base type typeフィールドがSQL_VECTOR_TYPE_FLOAT32またはSQL_VECTOR_TYPE_FLOAT16以外の値を持っていたことを意味します。 ゼロ初期化構造はデフォルトで float32となります。
  • もし float16 列がJSON配列を含む varchar(max )として報告されている場合、サーバーは PREVIEW_FEATURES データベーススコープ設定が有効になっていないか、接続がレベル v2より低いレベルで交渉されている可能性があります。