向量資料型態(ODBC)

本文說明了自 18.6.1.1 版本起,Microsoft ODBC 驅動程式實作的 向量 SQL 資料型別。 本文件概述了 Microsoft 驅動程式對 向量的行為,並提供使用指引、API 專用說明及程式碼摘要。 關於向量資料型態的概述,請參見 向量資料型態。

概觀

Microsoft ODBC 驅動程式原生支援 向量 資料型態。 應用程式能有效儲存、檢索及處理固定維度的數值嵌入,這些嵌入常用於機器學習與人工智慧工作負載。 驅動程式透過標準 ODBC API 與 C 資料型態提供向量支援。 應用程式可以與 SQL Server 向量欄位互通,而無需更改現有的 ODBC 工作流程。

適用於:Microsoft ODBC 驅動程式 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 佔據線路上一半的位元組, float16 向量在同一 8,000 位元組有效載荷限制內可容納兩倍的維度。

Important

應用程式緩衝區對兩種基本類型而言,都是一個陣float列(每個元素 4 位元組)。 驅動程式會在線路上的半精度和緩衝區的單精度之間轉換。 每個緩衝區的大小都應為 sizeof(float),且切勿每個元素使用 2 位元組,即使是一 float16 欄也一樣。

由於 float16 的尾數 float32比 少,通過一 float16 欄的往返是有損的。 插入時,數值會四捨五入至最接近的可表示半精度值,讀取的值則是 float32 該四捨五入值的展開。

在伺服器端,float16需要啟用 SQL Server 2025 (17.x) 並啟用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 連接字串 關鍵字選擇連線協商的原生向量支援層級。

價值觀 行為
off (預設值) 向量欄位以包含 JSON 陣列的 varchar(max) 形式出現。
v1 基礎型態的原生 向量 支援 float32 。
v2 原生向量支援,適用於float32float16基型與基型。 需要驅動程式版本 18.7.1.1 或更新版本。

你也可以在分配連線柄後、連接前,利用 SQL_COPT_SS_VECTOR_TYPE_SUPPORT pre-connect connection 屬性設定電平。

  • Microsoft 驅動程式提供驅動程式專屬的 C 綁定SQL_C_SS_VECTOR,並支援SQL_C_BINARY向量輸出。 在實踐中:

    • 當你啟用 vectorTypeSupport=v1 或 v2時,檢索 API(例如 SQLGetData 和 SQLBindCol)可以返回 向量 欄位,無論是 SQL_C_SS_VECTOR 還是 SQL_C_BINARY。 SQL_C_SS_VECTOR 以緊湊且具類型的形式回傳向量。 SQL_C_BINARY 回傳一個 變異型 有效載荷。

    • 對於輸入或參數綁定,驅動程式同時支援 SQL_C_SS_VECTOR 和 SQL_C_BINARY。 SQL_C_SS_VECTOR 提供型別化且緊湊的輸入綁定。 SQL_C_BINARY 等同且便攜。 當你想讓驅動程式把有效載荷視為原生SQL_C_SS_VECTOR類型時,請使用。

    • 當 vectorTypeSupport=off時,向量欄位會以 varchar(max) 形式出現,包含 JSON 陣列。

v2 是 的 v1超集,因此在 處 v2 協商的連接對欄位的 float32 處理方式完全相同 v1 。 在協商的v1連線上傳送float16值時,應用程式可能會遇到欄位float16時,使用 Use v2 功能Requested vector base type is not supported for the negotiated vector version.會失敗。

應用程式在使用向量特定類型前,必須將 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 指引

本節說明 ODBC API 如何與 SQL Server 向量資料互動,包括緩衝區配置需求、 NULL 處理方式及支援的資料表示方式。 當 vectorTypeSupport 設定為 v1 或 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) + 浮點 陣列大小(維度 * 4)。

這些尺寸在柱 float16 子中是相同的。 驅動程式會在每個半精度元件充滿緩衝區時展開為 a float ,並回報擴展後的長度。

緩衝區佈局的期望

非連續緩衝區(建議)

  • 應用程式每列分配一個SQL_SS_VECTOR_STRUCT。
  • 應用程式會為 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)
    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());

連續緩衝區

  • 應用程式分配單一緩衝區,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_IndPtr 為 , SQL_NULL_DATA 且不會填入緩衝區。 在存取向量內容物前,務必先檢查指示器。

備註

向向量欄位的讀取與列擷取行為在SQLFetch及SQLFetchScroll中有詳細說明(參見 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) + 浮點陣列大小(維度 * 4)。

不支援分塊檢索。 你必須一次通話中取回整個向量。

範例(原生 向量):

    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_IndPtr 為 , SQL_NULL_DATA 且不會填入緩衝區。 在存取向量內容物前,務必先檢查指示器。

備註

向向量欄位的讀取與列擷取行為在SQLFetch及SQLFetchScroll中有詳細說明(參見 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 以根據指定方向(next、prior、absolute、relative、bookmark)擷取行集。 驅動程式會正確地將向量資料複製到應用程式緩衝區。

  • 典型通話:
    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) +(浮點 陣列大小)
  • DecimalDigits:輸入參數被忽略。 對於輸出參數與執行時資料情境,請指定向量基底類型
  • BufferLength:≥ sizeof(SQL_SS_VECTOR_STRUCT) + (維度 * sizeof(float))
  • *StrLen_or_IndPtr: 必須包含相同的總大小

基型的來源

驅動程式根據參數方向從不同位置讀取基底元素類型。 錯誤是參數 Invalid vector dimensionProvided buffer length too small/largefloat16 錯誤最常見的原因。

參數類型 基礎型來源 維度來源
輸入,以及輸入/輸出 type你經過的SQL_SS_VECTOR_STRUCT田野 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_IndPtr 為 SQL_NULL_DATA,並將 NULL 作為 ParameterValuePtr 전달

  • 提供一個 SQL_SS_VECTOR_STRUCT:

    維度集合類型設為欄位的基底型別 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 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_LENGTH SQL_DESC_OCTET_LENGTH、 、 ,SQL_DESC_PRECISION且都描述客戶端緩衝區,因此它們報告欄位的 +(維度 * sizeof(float)),float16同時也回報sizeof(SQL_SS_VECTOR_STRUCT)一。float32 兩者僅在 SQL Server 儲存與傳輸的位元組數上有所不同。

SQL_DESC_SCALE 是唯一區分基底型的描述子欄位。 讀取它就是應用程式判斷欄位是否為 float32float16或 的方式。

SQLColAttribute 用於向量維度

從版本 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 */

你也可以設定 SQL_CA_SS_VECTOR_DIMENSION 應用程式描述符或向量參數的 IPD。 將它設為任何其他參數時,會回傳無效描述符欄位錯誤。

SQLDescribeCol

當你呼叫 SQLDescribeCol 針對 向量 欄位時:

  • DataType 是 SQL_SS_VECTOR
  • ColumnSize 匹配 SQL_DESC_PRECISION
  • DecimalDigits是基礎元素類型指示器,而非數值刻度:0對 float32 和1float16
  • Nullable 是 SQL_NULLABLE

報告的欄位大小代表本地向量有效載荷大小: sizeof(SQL_SS_VECTOR_STRUCT) +(維度 * sizeof(float))

SQLDescribeParam

當你使用 SQLDescribeParam 作為 向量 參數時:

  • DataType 是 SQL_SS_VECTOR
  • ColumnSize 等於本地向量有效載荷大小
  • DecimalDigits是基礎元素類型指示器,而非數值刻度:0對 float32 和1float16
  • Nullable 是 SQL_NULLABLE

這些資訊讓應用程式能在綁定前正確分配參數緩衝區。

SQLColAttribute

  • 使用 SQLColAttribute(hstmt, ColumnNumber, SQL_DESC_OCTET_LENGTH, ...) 取得向量有效載荷的精確位元組長度。 SQL_DESC_LENGTH 且 SQL_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)或 變數格式 (SQLBINARY),但不支援字元格式。 不支援 向量 型別與字元型別的轉換。

批量複製的支援等級和驅動程式其他部分相同。 一 float16 欄需要在 談判的連接 vectorTypeSupport=v2。 在 BCP 效用中,使用-z0, float32-z1 且 。float16 欲了解更多資訊,請參閱 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 為零,則包含一個指向 SQL_SS_VECTOR_STRUCT 資料的指標,其中有 浮點數 陣列資料(vectorStruct.data.f32 欄位)。 若 cbIndicator 非零,指示器會直接出現在記憶體中的資料前面。 因此 pData ,會指向一個緩衝區,該緩衝區首先是長度 cbIndicator 指示字節,接著是向量結構。
  • cbData:若提供,值必須恰好等於 - sizeof(SQL_SS_VECTOR_STRUCT) + (sizeof(float) * 維度)。 若不行,則發生錯誤。 這兩種基底類型都是一樣的,因為綁定的緩衝區會保持 float32 任何值。
  • eDataType: SQLVECTOR 或 SQLBINARY

將結構的欄位設 type 為該欄位的基底類型。 對於欄位 float16 ,驅動程式在建立線路有效載荷時會將綁定 float32 陣列轉換為半精度,因此以原生格式撰寫的資料檔案每個元素可容納兩個位元組。

當你透過 將資料匯入向量欄位 bcp_bind時,設 eDataType 為 SQLVECTOR 或 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. 結果 BufferLength 不完全符合 sizeof(SQL_SS_VECTOR_STRUCT) +(維度 * sizeof(float)) 檢查緩衝區的大小是否是每個 sizeof(float) 元素兩個位元組,即使是 float16 一欄也一樣。
  • Invalid vector dimension表示維度為零,或超過基型的最大值:1,998 為 float32 ,為 3,996。float16
  • Invalid vector base type 表示該 type 欄位的值非 SQL_VECTOR_TYPE_FLOAT32 或 SQL_VECTOR_TYPE_FLOAT16。 零初始化結構預設為 float32。
  • 如果某 float16 欄被報告為 varchar(max), 包含 JSON 陣列,表示伺服器未 PREVIEW_FEATURES 啟用資料庫範圍設定,或連線協 v2商低於 。