本文說明了自 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商低於 。