Typ danych wektorowych (ODBC)

Ten artykuł dokumentuje wektorowy typ danych SQL implementowany przez sterownik Microsoft ODBC dla programu SQL Server, począwszy od wersji 18.6.1.1. W tym dokumencie opisano zachowanie sterownika firmy Microsoft dla wektora i przedstawiono wskazówki dotyczące użycia, uwagi specyficzne dla interfejsu API i fragmenty kodu. Aby zapoznać się z omówieniem typów danych wektorowych, zobacz Vector data type (Typ danych wektorowych).

Przegląd

Sterownik Microsoft ODBC dla programu SQL Server natywnie obsługuje typ danych wektorowych . Aplikacje mogą wydajnie przechowywać, pobierać i przetwarzać osadzanie liczbowe o stałym wymiarze często używane w obciążeniach uczenia maszynowego i sztucznej inteligencji. Sterownik uwidacznia obsługę wektorów za pomocą standardowych interfejsów API ODBC i typów danych języka C. Aplikacje mogą współdziałać z kolumnami wektorów programu SQL Server bez zmieniania istniejących przepływów pracy ODBC.

Dotyczy: Sterownik MICROSOFT ODBC dla programu SQL Server 18.6.1.1 i nowszych wersji. Wsparcie dla float16 tego typu podstawowego wymaga wersji 18.7.1.1 lub nowzej.

Obsługa wektorów jest domyślnie wyłączona i musi być wyraźnie włączona.

Typy elementów bazowych

Kolumna wektorowa deklaruje typ elementu bazowego. Sterownik obsługuje oba typy definiowane przez SQL Server.

Typ podstawowy Wskaźnik typu Bajty na element na przewodzie Maksymalny wymiar Wersja sterownika
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

Wartość domyślna to float32. Aby użyć przechowywania o półprecyzji, zadeklaruj kolumnę lub parametr jako .VECTOR(<dimensions>, float16) Ponieważ float16 element zajmuje połowę bajtów przewodu, wektor float16 mieści dwa razy więcej wymiarów w ramach tego samego limitu ładunku 8 000 bajtów.

Important

Bufor aplikacji to zawsze tablica float (4 bajty na element) dla obu typów bazowych. Sterownik przechodzi między półprecyzją na przewodzie a pojedynczą precyzją w twoim buforze. Rozmiaruj każdy bufor przez sizeof(float), nigdy nie używaj 2 bajtów na element, nawet dla kolumny float16 .

Ponieważ float16 ma mniej bitów mantysy niż float32, przejście przez kolumnę float16 w obie strony jest stratne. Wartości są zaokrąglane do najbliższej reprezentowalnej wartości półprecyzji przy wstawieniu, a odczyt to float32 rozwinięcie tej zaokrąglonej wartości.

Na serwerze wymaga float16 to SQL Server 2025 (17.x) z PREVIEW_FEATURES włączoną konfiguracją skalowaną bazą danych. Aby uzyskać więcej informacji, zobacz Obsługa zmiennoprzecinkowa o połowie precyzji w typie danych wektorowych.

Reprezentacja natywnego języka C

Po włączeniu obsługi wektorów kolumny wektorowe są wymieniane przy użyciu typizowanej struktury języka C o nazwie 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: opisuje liczbę elementów w wektorze
  • type: identyfikuje typ elementu bazowego, SQL_VECTOR_TYPE_FLOAT32 lub SQL_VECTOR_TYPE_FLOAT16
  • data.f32 / data.f16: wskazuje na bufor aplikacji zawierający wartości wektorowe

Obaj członkowie unii są deklarowani jako float* i są wymienne, ponieważ bufor po stronie klienta zawiera float32 wartości dla każdego typu bazowego. Użyj tego, który dokument dokumentuje Twoje intencje.

Włączanie obsługi wektorów

Słowo vectorTypeSupport kluczowe parametry połączenia wybiera poziom natywnego wsparcia wektorowego, które negocjuje połączenie.

Wartość Behavior
off (ustawienie domyślne) Kolumny wektorowe pojawiają się jako varchar(max) zawierające tablice JSON.
v1 Natywne wsparcie wektorowe dla float32 typu bazowego.
v2 Natywne wsparcie wektorowe zarówno dla typów bazowych float32 , jak i float16 bazowych. Wymaga sterownika w wersji 18.7.1.1 lub nowzej.

Możesz też ustawić poziom po alokacji uchwytu połączenia, a przed połączeniem, za pomocą atrybutu SQL_COPT_SS_VECTOR_TYPE_SUPPORT połączenia pre-connect.

  • Sterownik Microsoft udostępnia przypisanie C specyficzne SQL_C_SS_VECTOR dla sterownika i obsługuje SQL_C_BINARY wynik wektorowy. W praktyce:

    • Gdy włączysz vectorTypeSupport=v1 lub v2, API pobierania (na przykład SQLGetData i SQLBindCol) mogą zwracać kolumny wektorowe jako albo SQL_C_SS_VECTORSQL_C_BINARY. SQL_C_SS_VECTOR zwraca wektor w postaci kompaktowej, typizowanej. SQL_C_BINARY zwraca ładunek varbinary .

    • Dla wiązania wejścia lub parametrów sterownik obsługuje zarówno , SQL_C_SS_VECTOR jak i SQL_C_BINARY. SQL_C_SS_VECTOR zapewnia typizowane, kompaktowe powiązanie wejściowe. SQL_C_BINARY jest równoważny i przenośny. Użyj SQL_C_SS_VECTOR polecenia , jeśli sterownik ma traktować ładunek jako natywny typ wektora .

    • Gdy vectorTypeSupport=offkolumny wektorowe są wyświetlane jako varchar(max) zawierające tablice JSON.

v2 jest nadzbiorem v1, więc połączenie negocjowane w obsługuje v2float32 kolumny dokładnie tak samo jak v1 . Wysłanie float16 wartości na połączenie negocjowane na kończy v1 się niepowodzeniem z Requested vector base type is not supported for the negotiated vector version. Używaj, v2 gdy aplikacja może napotkać kolumnę float16 .

Aplikacje muszą również ustawić wersję ODBC na ODBC 3.8 przed użyciem typów specyficznych dla wektorów:

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

Obsługiwane formaty powiązań

Natywne powiązanie wektora

Typ C: SQL_C_SS_VECTOR

Ten format jest zalecany w przypadku aplikacji o krytycznym znaczeniu dla wydajności.

Powiązanie binarne

Typ C: SQL_C_BINARY

Wektory są zwracane przy użyciu tego samego układu co SQL_C_SS_VECTOR. Aplikacje mogą używać tego formatu na potrzeby scenariuszy współdziałania niskiego poziomu. Bufor wskaźnika danych może być ciągły lub nieciągły z adresem pamięci struktury.

Wskazówki dotyczące interfejsu API ODBC

W tej sekcji opisano sposób interakcji interfejsów API ODBC z danymi wektorowymi programu SQL Server, w tym wymaganiami dotyczącymi układu buforu, NULL obsługą i obsługiwanymi reprezentacjami danych. Wszystkie zachowania mają zastosowanie, gdy vectorTypeSupport jest ustawione na lub v1v2 i środowisko jest skonfigurowane dla ODBC 3.8.

Każda formuła na rozmiar bufora w tej sekcji używa sizeof(float) elementów dla obu typów bazowych, ponieważ bufor po stronie klienta zawsze zawiera float32 wartości. Kolumna float16 zmienia bajty na przewodzie, a nie układ bufora.

SQLBindCol

Użyj polecenia SQLBindCol , aby powiązać kolumny wektorów w zestawie wyników z buforami aplikacji.

  • Typowe wywołanie:
    SQLRETURN SQLBindCol(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   ColumnNumber,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: użyj SQL_C_SS_VECTOR lub SQL_C_BINARY.

  • TargetValuePtr: wskaźnik do SQL_SS_VECTOR_STRUCT tablicy zmiennoprzecinkowej, gdy TargetType jest SQL_C_SS_VECTOR; w przeciwnym razie wskaźnik do buforu o rozmiarze równym wartości w StrLen_or_IndPtr.

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + liczba bajtów przydzielonych dla buforu kolumny (wymiar * 4).

  • StrLen_or_IndPtr: wskaźnik, który odbiera długość bajtu zwracanego wektora (SQL_DESC_OCTET_LENGTH). Jego wartość to sizeof(SQL_SS_VECTOR_STRUCT) + rozmiar tablicy zmiennoprzecinkowej (wymiar * 4).

Te rozmiary są takie same dla kolumny float16 . Sterownik rozszerza każdy element o półprecyzji do a float , gdy wypełnia bufor, i raportuje rozszerzoną długość.

Oczekiwania dotyczące układu buforu

Bufor nieciągły (zalecane)

  • Aplikacja przydziela jeden SQL_SS_VECTOR_STRUCT na wiersz.
  • Aplikacja przydziela pamięć dla elementu data.f32.
  • Sterownik wypełnia metadane wektora i zapisuje wartości elementów w podanym buforze 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());

Ciągły bufor

  • Aplikacja przydziela jeden bufor i wypełnia go odpowiednio ODBC.
  • Tablica zmiennoprzecinkowa musi się zaczynać natychmiast po strukturze.
  • Sterownik ustawia data.f32 w celu wskazania tego ciągłego regionu.
    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());

Obsługa wartości NULL w SQLBindCol

Gdy wartość kolumny to NULL, sterownik ustawia *StrLen_or_IndPtr na SQL_NULL_DATA i nie inicjuje bufora. Zawsze sprawdzaj wskaźnik przed uzyskaniem dostępu do zawartości wektora.

Uwaga / Notatka

Zachowanie podczas odczytu i pobierania wierszy dla kolumn wektorów jest szczegółowo opisane w SQLFetch i SQLFetchScroll (zobacz te odwołania do interfejsów API, aby uzyskać szczegóły dotyczące semantyki pobierania oraz przykładów pobierania tablic).

SQLGetData

Użyj SQLGetData do pobierania danych wektorowych z niezwiązanych kolumn.

  • Typowe wywołanie:
    SQLRETURN SQLGetData(
      SQLHSTMT       StatementHandle,
      SQLUSMALLINT   Col_or_Param_Num,
      SQLSMALLINT    TargetType,
      SQLPOINTER     TargetValuePtr,
      SQLLEN         BufferLength,
      SQLLEN *       StrLen_or_IndPtr);
  • TargetType: użyj SQL_C_SS_VECTOR lub SQL_C_BINARY.

  • TargetValuePtr: wskaźnik do SQL_SS_VECTOR_STRUCT tablicy zmiennoprzecinkowej, gdy TargetType jest SQL_C_SS_VECTOR; w przeciwnym razie wskaźnik do buforu o rozmiarze równym wartości w StrLen_or_IndPtr.

  • BufferLength: sizeof(SQL_SS_VECTOR_STRUCT) + liczba bajtów przydzielonych dla buforu kolumny (wymiar * 4).

  • StrLen_or_IndPtr: wskaźnik, który odbiera długość bajtu zwracanego wektora (SQL_DESC_OCTET_LENGTH). Jego wartość to sizeof(SQL_SS_VECTOR_STRUCT) + rozmiar tablicy zmiennoprzecinkowej (wymiar * 4).

Dzielenie pobrań na fragmenty nie jest obsługiwane. Należy pobrać cały wektor w jednym wywołaniu.

Przykład ( wektor natywny):

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

Obsługa wartości NULL dla sqlGetData

Gdy wartość kolumny to NULL, sterownik ustawia *StrLen_or_IndPtr na SQL_NULL_DATA i nie inicjuje bufora. Zawsze sprawdzaj wskaźnik przed uzyskaniem dostępu do zawartości wektora.

Uwaga / Notatka

Zachowanie podczas odczytu i pobierania wierszy dla kolumn wektorów jest szczegółowo opisane w SQLFetch i SQLFetchScroll (zobacz te odwołania do interfejsów API, aby uzyskać szczegóły dotyczące semantyki pobierania oraz przykładów pobierania tablic).

SQLFetch

Użyj SQLFetch polecenia , aby pobrać następny wiersz i prawidłowo zmaterializować wszystkie powiązane SqlVector kolumny.

  • Typowe wywołanie:
    SQLRETURN SQLFetch(
     SQLHSTMT     StatementHandle);

Wywołaj SQLFetch w standardowej pętli z kolumnami już powiązanymi przez SqlVector z pomocą SQLBindCol. Możesz też użyć polecenia SQLGetData , aby pobrać dane do buforu aplikacji.

Przykład ( wektor natywny):

    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

Użyj SQLFetchScroll do pobierania zestawów wierszy zgodnie z określoną orientacją (następna, poprzednia, bezwzględna, względna, znacznik). Sterownik poprawnie kopiuje dane wektorowe do buforów aplikacji.

  • Typowe wywołanie:
    SQLRETURN SQLFetchScroll(
      SQLHSTMT      StatementHandle,
      SQLSMALLINT   FetchOrientation,
      SQLLEN        FetchOffset);

Przykład ( wektor natywny):

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

Użyj SQLBindParameter polecenia , aby wysyłać wartości wektorów do programu SQL Server.

  • Typowe wywołanie:
    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: wskazuje wypełnione SQL_SS_VECTOR_STRUCT
  • ColumnSize: ignorowane dla parametrów wejściowych. W przypadku parametrów wyjściowych i scenariuszy wykonywania danych określ całkowity rozmiar wektora: sizeof(SQL_SS_VECTOR_STRUCT) + (rozmiar tablicy zmiennoprzecinkowej )
  • DecimalDigits: ignorowane dla parametrów wejściowych. W przypadku parametrów wyjściowych i scenariuszy wykonywania danych określ typ podstawowy wektora
  • BufferLength: ≥ sizeof(SQL_SS_VECTOR_STRUCT) + (wymiar * sizeof(float))
  • *StrLen_or_IndPtr: musi zawierać ten sam całkowity rozmiar

Skąd pochodzi typ bazowy

Sterownik odczytuje typ elementu bazowego z innego miejsca w zależności od kierunku parametru. Błędne ułożenie tego jest najczęstszą przyczyną Invalid vector dimension lub Provided buffer length too small/large błędami parametrów float16 .

Rodzaj parametrów Źródło typu bazowego Źródło wymiaru
Wejście, wejście/wyjście Pole typeSQL_SS_VECTOR_STRUCT twojego mijania Pole dimension o tej samej strukturze
Wyjście czyste DecimalDigits Wyprowadzone z ColumnSize jako (ColumnSize - sizeof(SQL_SS_VECTOR_STRUCT)) / sizeof(float)
Dane przy wykonaniu DecimalDigits Wyprowadzony z ColumnSize, i porównany z długością przechodzącą do SQL_LEN_DATA_AT_EXEC

Dla parametru wejściowego musi BufferLengthsizeof(SQL_SS_VECTOR_STRUCT) być dokładnie równe + (wymiar * sizeof(float)). Większa lub mniejsza wartość zawodzi, zamiast być tolerowana.

Przykład ( wektor natywny, 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);

Przykład ( wektor natywny, float16):

Zmienia się type tylko pole. Tablica wartości pozostaje tablicą float i cb jest obliczana w ten sam sposób.

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

Przykład (float16 parametr wyjściowy):

Czysty parametr wyjściowy nie posiada struktury wejściowej, więc typ bazowy jest przekazywany do , DecimalDigits a wymiar wyprowadzany jest z 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);

Obsługa wartości NULL dla parametru SQLBindParameter

Aplikacje mogą wskazywać NULL wektor przy użyciu jednej z obsługiwanych metod:

  • Ustaw *StrLen_or_IndPtr na SQL_NULL_DATA oraz przekaż NULL jako ParameterValuePtr

  • Podaj element SQL_SS_VECTOR_STRUCT z:

    Typ zestawu wymiarowego ustawiony na bazę kolumny data.f32 = NULL

SQLPutData

Sterownik obsługuje SQLPutData parametry wektorów z następującymi ograniczeniami:

  • Należy podać cały wektor w pierwszym wywołaniu.

  • Sterownik nie obsługuje fragmentowanej ani przyrostowej transmisji wektorów.

  • NULL obsługa jest zgodna z tymi samymi regułami co SQLBindParameter.

  • Typowe wywołanie:

    SQLRETURN SQLPutData(
        SQLHSTMT     StatementHandle,
        SQLPOINTER   DataPtr,
        SQLLEN       StrLen_or_Ind);
  • DataPtr: wskazuje wypełnione SQL_SS_VECTOR_STRUCT
  • StrLen_or_Ind: sizeof(SQL_SS_VECTOR_STRUCT) + (wymiar * sizeof(float))

Przykład ( wektor natywny):

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

Metadane deskryptorów

Po włączeniu obsługi wektorów sterownik Microsoft ODBC dla programu SQL Server uwidacznia metadane wektorów za pomocą standardowych interfejsów API deskryptora ODBC. Aplikacje mogą używać informacji deskryptora do odnajdywania szczegółów schematu wektora, rozmiarów buforów obliczeniowych i prawidłowego konfigurowania powiązań dla parametrów i zestawów wyników.

Wartości pól deskryptora dla wektora

Poniższa tabela zawiera podsumowanie wartości pól deskryptora dla kolumn i parametrów wektorów programu SQL Server.

Pole deskryptora Wartość Description
SQL_DESC_TYPE SQL_SS_VECTOR (-156) Identyfikator podstawowego typu danych SQL
SQL_DESC_CONCISE_TYPE SQL_SS_VECTOR Zwięzły typ danych SQL
SQL_DESC_TYPE_NAME vector Nazwa typu SQL
SQL_DESC_LOCAL_TYPE_NAME vector Nazwa lokalnego typu sterownika
SQL_DESC_LENGTH sizeof(SQL_SS_VECTOR_STRUCT) + (dimension * sizeof(float)) Rozmiar logiczny wartości wektora
SQL_DESC_OCTET_LENGTH Tak samo jak SQL_DESC_LENGTH Rozmiar fizyczny w bajtach
SQL_DESC_PRECISION Tak samo jak SQL_DESC_LENGTH Służy do raportowania rozmiaru wektora
SQL_DESC_SCALE SQL_VECTOR_TYPE_FLOAT32 lub SQL_VECTOR_TYPE_FLOAT16 Typ elementu podstawowego wektora
SQL_CA_SS_VECTOR_DIMENSION dimension Liczba elementów w wektorze
SQL_DESC_DISPLAY_SIZE dimension * VECTOR_FLOAT32_TO_CHAR_JSON_MAX_SIZE Maksymalna długość wyświetlacza JSON
SQL_DESC_FIXED_PREC_SCALE SQL_FALSE Wektor nie ma stałej dokładności/skali
SQL_DESC_NULLABLE SQL_NULLABLE Kolumny wektorowe zezwalają na NULL wartości
SQL_DESC_NUM_PREC_RADIX 0 Typ nieliczbowy
SQL_DESC_SEARCHABLE SQL_PRED_NONE Nie można używać w predykatach
SQL_DESC_UNSIGNED SQL_TRUE Typ elementu jest niepodpisany
SQL_DESC_AUTO_UNIQUE_VALUE SQL_FALSE Nie automatycznie unikalny
SQL_DESC_CASE_SENSITIVE SQL_FALSE Nie uwzględnia wielkości liter
SQL_DESC_UPDATABLE SQL_ATTR_READWRITE_UNKNOWN Nieznana możliwość aktualizacji

SQL_DESC_LENGTH SQL_DESC_OCTET_LENGTH, , i SQL_DESC_PRECISION wszystkie opisują bufor po stronie klienta, więc raportują sizeof(SQL_SS_VECTOR_STRUCT) + (wymiar * sizeof(float)) zarówno dla kolumnyfloat16, jak i float32 dla jednego. Różnią się jedynie liczbą bajtów, które SQL Server przechowuje i przesyła.

SQL_DESC_SCALE jest jedynym polem deskryptorem, które wyróżnia typy bazowe. Czytanie tego polega na tym, że aplikacja wykrywa, czy kolumna to float32 czy float16.

SQLColAttribute dla wymiaru wektorowego

Począwszy od wersji 18.7.1.1, zwraca SQL_CA_SS_VECTOR_DIMENSION bezpośrednio liczbę elementów kolumny wektorowej, dzięki czemu aplikacja nie musi już wyprowadzać jej z pola długości:

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

Możesz też ustawić SQL_CA_SS_VECTOR_DIMENSION na deskryptorze aplikacji lub na IPD parametr wektorowy. Ustawienie go na dowolnym innym typie parametru zwraca nieprawidłowy błąd pola deskryptoru.

SQLDescribeCol

Podczas wywoływania SQLDescribeCol dla kolumny wektorowej:

  • DataType jest SQL_SS_VECTOR
  • ColumnSize dopasowuje się do SQL_DESC_PRECISION
  • DecimalDigits jest wskaźnikiem typu elementu bazowego, a nie skalą liczbową: 0 dla float32 i 1 dla float16
  • Nullable jest SQL_NULLABLE

Rozmiar zgłaszanej kolumny reprezentuje natywny rozmiar ładunku wektora: sizeof(SQL_SS_VECTOR_STRUCT) + (wymiar * sizeof(float))

SQLDescribeParam

W przypadku użycia SQLDescribeParam parametru wektora :

  • DataType jest SQL_SS_VECTOR
  • ColumnSize odpowiada natywnemu rozmiarowi ładunku wektora
  • DecimalDigits jest wskaźnikiem typu elementu bazowego, a nie skalą liczbową: 0 dla float32 i 1 dla float16
  • Nullable jest SQL_NULLABLE

Te informacje umożliwiają aplikacjom prawidłowe przydzielanie buforów parametrów przed powiązaniem.

SQLColAttribute

  • Użyj polecenia SQLColAttribute(hstmt, ColumnNumber, SQL_DESC_OCTET_LENGTH, ...) , aby uzyskać dokładną długość bajtu ładunku wektora. SQL_DESC_LENGTH i SQL_DESC_PRECISION może przenosić wartości specyficzne dla sterownika. W przypadku liczby bajtów preferuj wartość SQL_DESC_OCTET_LENGTH.

    • NULL Obsługa: Gdy kolumna to NULL, SQLColAttribute (lub StrLen_or_IndPtr używane z SQLBindCol) zwraca SQL_NULL_DATA. Sprawdź, czy istnieje SQL_NULL_DATA, przed użyciem zwróconych długości lub buforów.

Kopiowanie zbiorcze (BCP)

Możesz zbiorczo importować i eksportować kolumny wektorów za pomocą plików BCP i interfejsu bcp_bind API, podobnie jak w przypadku innych typów danych. Obecnie importowanie i eksportowanie wektorów obsługuje tylko format natywny (SQLVECTOR) lub varbinary (SQLBINARY), ale nie format znaków. Konwersja między typem wektora a typem znaku nie jest obsługiwana.

Kopia masowa honoruje ten sam poziom wsparcia co reszta sterownika. Kolumna float16 wymaga połączenia negocjowanego w .vectorTypeSupport=v2 W narzędziu bcp używamy -z0 dla float32 i -z1 dla float16. Aby uzyskać więcej informacji, zobacz narzędzie bcp.

Aby uzyskać więcej informacji na temat tokenu typu, domyślnej długości prefiksu i domyślnej długości pola dla wektora, zobacz Typ magazynu plików, Długość prefiksu i Długość pola.

bcp_gettypename

Gdy używasz bcp_gettypename polecenia, aby uzyskać nazwę typu SQL vector, zwraca token typu BCP (SQLVECTOR) i "vector".

bcp_bind

Służy bcp_bind do zbiorczego wstawiania zmiennych programu do kolumny wektorów .

Typowe wywołanie:

RETCODE bcp_bind (
        HDBC hdbc,
        LPCBYTE pData,
        INT cbIndicator,
        DBINT cbData,
        LPCBYTE pTerm,
        INT cbTerm,
        INT eDataType,
        INT idxServerCol);
  • pData: jeśli cbIndicator ma wartość zero, zawiera wskaźnik do SQL_SS_VECTOR_STRUCT danych z danymi tablicy zmiennoprzecinkowej wewnątrz (vectorStruct.data.f32 pole). Jeśli cbIndicator wartość jest niezerowa, wskaźnik jest wyświetlany w pamięci bezpośrednio przed danymi. Dlatego pData wskazuje na bufor, który najpierw zawiera cbIndicator bajtów wskaźnika długości, po którym następuje struktura wektora.
  • cbData: jeśli podano, musi mieć wartość dokładnie równą - sizeof(SQL_SS_VECTOR_STRUCT) + ( *sizeof(float) wymiar). W przeciwnym razie wystąpi błąd. Jest to takie samo dla obu typów bazowych, ponieważ bufor bound przechowuje float32 wartości w obu kierunkach.
  • eDataType: SQLVECTOR lub SQLBINARY

Ustaw type pole struktury na typ bazy kolumny. Dla kolumny float16 sterownik konwertuje tablicę powiązaną float32 na pół-precyzyjną podczas budowania ładunku przewodowego, więc plik danych napisany w formacie natywnym mieści dwa bajty na element.

Podczas importowania danych do kolumny wektorowej za pomocą bcp_bind, ustaw eDataType na SQLVECTOR lub SQLBINARY. W obu przypadkach należy podać dane w postaci SQL_SS_VECTOR_STRUCT.

Rozwiązywanie problemów i porady

  • Jeśli SQLGetTypeInfo nie ma listy VECTOR, wróć do przechowywania wektorów jako varchar.
  • Requested vector base type is not supported for the negotiated vector version.oznacza, że float16 wartość została użyta na połączeniu wynegocjowanym przy .vectorTypeSupport=v1 Ponownie połącz się z .v2
  • Provided buffer length too small/large. Means BufferLength nie zgadzały się sizeof(SQL_SS_VECTOR_STRUCT) dokładnie z + (wymiar * sizeof(float)). Sprawdź, czy bufor jest objęty wartością sizeof(float) , a nie dwoma bajtami na element, nawet dla kolumny float16 .
  • Invalid vector dimension oznacza, że wymiar wynosi zero lub przekracza maksimum dla typu bazowego: 1 998 dla float32 i 3 996 dla float16.
  • Invalid vector base type oznacza, że pole zawierało type wartość inną niż SQL_VECTOR_TYPE_FLOAT32 lub SQL_VECTOR_TYPE_FLOAT16. Struktura inicjalizowana zerem domyślnie wynosi .float32
  • Jeśli kolumna float16 jest raportowana jako varchar(max) zawierająca tablicę JSON, serwer nie ma PREVIEW_FEATURES włączonej konfiguracji skalowanej bazy danych lub połączenie jest wynegocjowane na poziomie niższym niż v2.