14 Oracle Databaseでのベクトル・サポート

この章では、OCCIでのOracle Databaseベクトル・サポートについて説明します。

Oracle Databaseリリース23ai以降では、データ型としてのベクトルが、AIおよび機械学習セマンティクスの半構造化データおよび非構造化データを表すために導入されています。ベクトルは、指定された長さと数値型である一連の数値として表されます。

ベクトル要素は、次のデータ型で表すことができます:

  • INT8_t: これは、C++でのint8 (8ビット符号付き整数)データ型に対応しています
  • FLOAT32 : これは、C++でのfloatに対応しています
  • FLOAT64: これは、C++でのdouble型に対応しています
  • BINARY :C++ではbinaryデータ型はサポートされていませんが、uin8_tが、バイナリ・データをサポートするために使用されています。各uint8_t値には、8ビット(バイナリ値)が含まれます。BINARYベクトルには、8の倍数である次元が必要です。

14.1 OCCIでのOracle Databaseベクトル・サポート

この項では、OCCIでのOracle Databaseベクトル・サポート関数について説明します。

14.1.1 文ハンドルへのベクトルのバインド

この項では、ベクトル・データを文ハンドルにバインドするために導入された関数について説明します。

14.1.1.1 setInt8Vector()

int8_t型のC++ベクトル値からOracle Databaseベクトル・データ型の値をint8(ub1)形式で設定します。

構文

void setInt8Vector(unsigned int paramIndex,vector<int8_t> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するベクトルを指定します。
14.1.1.2 setFloatVector()

float型のC++ベクトル値からOracle Databaseベクトル・データ型の値をIEEE FLOAT32形式で設定します。

構文

void setFloatVector(unsigned int paramIndex,vector<float> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するベクトルを指定します。
14.1.1.3 setDoubleVector()

double型のC++ベクトルからOracle Databaseベクトル・データ型の値をIEEE FLOAT64形式で設定します。

構文

void setDoubleVector(unsigned int paramIndex,vector<double> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するベクトルを指定します。
14.1.1.4 setBinaryVector()

uint8_t型のC++ベクトルからOracle Databaseベクトル・データ型の値をバイナリ形式で設定します。

構文

ノート:

次元が8の倍数であるバイナリ・ベクトルのみ挿入できます。
void setBinaryVector(unsigned int paramIndex,vector<uint8_t> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するベクトルを指定します。

次のサンプル・コード・スニペットは、ベクトルmyDataFLOAT32として、stmt内の位置1にバインドしています。この文をさらに実行すると、それがデータベース表に挿入されます。

Statement *stmt;
stmt = conn->createStatement ("INSERT INTO test_vecflt values(:1,:2)");
vector<float> myData({1.4,1.2,3.5});
stmt->setInt(1,10);
stmt->setFloatVector(2,myData);
stmt->executeUpdate();

14.1.2 ベクトルの場合のPL/SQLアウトバインド

この項では、文ハンドルへのアウトバインドを介してPL/SQLプロシージャまたはファンクションからの出力を取得するために使用する関数について説明します。

14.1.2.1 getInt8Vector()

int8_t型形式のC++ベクトル値からOracle Databaseベクトル・データ型の値をint8(ub1)形式で取得します。

構文

void getInt8Vector(unsigned int paramIndex,vector<int8_t> &vec);
パラメータ 説明
paramIndex
パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。
14.1.2.2 getFloatVector()

float型のC++ベクトル値からOracle Databaseベクトルの値をIEEE FLOAT32形式で取得します。

構文

void getFloatVector(unsigned int paramIndex,vector<float> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。
14.1.2.3 getDoubleVector()

double型のC++ベクトル値からOracle Databaseベクトル・データ型の値をIEEE FLOAT64形式で取得します。

構文

void getDoubleVector(unsigned int paramIndex,vector<double> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。
14.1.2.4 getBinaryVector()

uint8_t型のC++ベクトル内の、Oracle Databaseベクトル・データ型の値をバイナリ形式で取得します。

構文

void getBinaryVector(unsigned int paramIndex,vector<uint8_t>&vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。

ノート:

現在、バイナリ・ベクトルの次元は8の倍数です。つまり、8*vec.size()の場合、vecstl vector<uint8_t>です。

次のコード・スニペットをアウト・バインドに使用してベクトルを取得できます:

Statement *stmt;
stmt = conn->createStatement ("BEGIN occivec_demo(:1) END;");
//Disclaimer: Binary literals introduced in C++14 and above, used here for descriptive purposes.
vector<uint8_t> myInBind({0b00100011,0b01000011,0b10101011,0b01001001});
stmt->setBinaryVector(1,myInOutBind);
stmt->stmtExecute();
stmt->getBinaryVector(1,myInOutBind);

これは、myInOutBind内の位置1でINOUTバインドからフェッチされたデータを取得しています。

柔軟性のある次元の場合は、ベクトルのサイズがDatabaseベクトルの次元と同じでない場合があります。このような場合、stmt->getBinaryVector()には必ず、OUTベクトルの次元を示す戻り値があります。

int dimension = stmt->getBinaryVector(1,myInOutBind);
//printing the bits
for(int i=0;i<dimension;i++)
    cout<<((v[i/8]>>(8-(i%8)))&1;
次のコード・スニペットをアウト・バインドに使用してベクトルを取得できます:
Statement *stmt;
stmt = conn->createStatement ("BEGIN occivec_demo(:1,:2,:3) END;");
vector<double> myInBind({1.4,1.2,3.5});
vector<double> myInOutBind;
vector<double> myOutBind;
stmt->setInt(1,myInBind);
stmt->setDoubleVector(2,myInOutBind);
stmt->registerOutParam(3,OCCI_SQLT_VEC);
stmt->stmtExecute();
stmt->getDoubleVector(2,myInOutBind);
stmt->getDoubleVector(3,myOutBind);

14.1.3 問合せのResultSetからのベクトルの定義

この項では、C++のstlベクトル・コンテナにベクトル型の列値を取得するためにResultSetクラスに導入された関数について説明します。

14.1.3.1 getInt8Vector()

int8_t型のC++ベクトル値として、Oracle Databaseベクトル・データ型の列値をint8(ub1)形式で取得します。

構文

void getInt8Vector(unsigned int paramIndex,vector<int8_t> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。
14.1.3.2 getFloatVector()

float型のC++ベクトル値からOracle Databaseベクトル・データ型の列値をIEEE FLOAT32形式で取得します。

構文

void getFloatVector(unsigned int paramIndex,vector<float> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。
14.1.3.3 getDoubleVector()

double型のC++ベクトル値からOracle Databaseベクトル・データ型の列値をIEEE FLOAT64形式で取得します。

構文

void getDoubleVector(unsigned int paramIndex,vector<double> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。
14.1.3.4 getBinaryVector()

uint8_t型のC++ベクトルからOracle Databaseベクトル・データ型の列値をバイナリ形式で取得します。

構文

void getBinaryVector(unsigned int paramIndex,vector<uint8_t> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるベクトル(OUTパラメータ)への参照。

次のコード・スニペットを使用してResultSet内でベクトルを取得できます:

Statement stmt;
stmt = conn->createStatement ("SELECT * FROM TEST_VECFLT");
ResultSet *rs = stmt->getResultSet();
vector<float> myResult;
stmt->stmtExecute();
rs->getFloatVector(2,myResult);

結果でのベクトル・データの型は、コールされた関数によって異なります。たとえば、getFloatVectorFLOAT32形式に対応しています。

14.1.3.5 getString()

C++の文字列として、任意の形式のOracle Databaseベクトルの列値を取得します。

構文

string getString(unsigned int paramIndex);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
次のサンプル・コード・スニペットを使用してResultSet内でベクトルを取得できます:
Statement stmt;
stmt = conn->createStatement ("SELECT id,embedding FROM TEST_SPARSEVECFLT");
ResultSet *rs = stmt->getResultSet();
stmt->stmtExecute();
int id = rs->getInt(1);
string vec = rs->getString(2);

14.1.4 ベクトルのMetaData

説明機能でMetaDataをサポートするために、新しいデータ型OCCI_SQLT_VECが導入されました。

ベクトル列固有の次の列属性がMetaDataに追加されました:
  • ATTR_VECTOR_DIMENSION : ベクトルの次元の情報
  • ATTR_VECTOR_DATA_FORMAT: ベクトル列に格納されるデータ形式の型
  • ATTR_VECTOR_PROPERTY: データ・フラグの情報
次のコード・スニペットは、ベクトルの列メタデータを取得するために使用されます:
vector<MetaData> v1;
MetaData metaData = conn->getMetaData("TEST_VECDBL");
v1 = metaData.getVector(MetaData::ATTR_LIST_COLUMNS);
for(int i=0; i < v1.size(); i++)
{
    MetaData md = v1[i];
    cout << " Column Name :" << md.getString(MetaData::ATTR_NAME)           << endl;
    cout << " Data Type :"   << md.getInt(MetaData::ATTR_DATA_TYPE)         << endl;
    cout << " Dimension :"   << md.getUInt(MetaData::ATTR_VECTOR_DIMENSION) << endl;
}
14.1.4.1
#include <sys/types.h>
#include <fstream>
#include <iostream>
#include <occi.h>
#include <cstdlib>
#include <string.h>
 
using namespace oracle::occi;
using namespace std;
 
static  char *username=strdup("scott");
static  char *password=strdup("tiger");
static  char *dbname=strdup("inst1");
 
class occivec
{
  private:
 
  Environment *env;
  Connection *conn;
  Statement *stmt;
  ResultSet *rs;
  public:
 
  occivec ()
  {
    env = Environment::createEnvironment (Environment::DEFAULT);
    conn = env->createConnection (username, password, dbname);
  }
 
  ~occivec ()
  {
    env->terminateConnection (conn);
    Environment::terminateEnvironment (env);
  }
 
  void displayAllRows (string tableName)
  {
    cout<<"--- Displaying rows of "<<tableName<<"---"<<endl;
    string sqlStmt = "select * from "+tableName;
    stmt = conn->createStatement (sqlStmt);
    ResultSet *rset = stmt->executeQuery ();
    try{
    while (rset->next ())
    {
      cout << "ID: " << rset->getInt (1) << endl;
      vector<double> ans;
      rset->getDoubleVector(2,ans);
      cout << "Embedding: ";
      for(auto i:ans)cout<<i<<" ";cout<<endl;
    }
    }catch(SQLException ex)
    {
     cout<<"Exception thrown for displayAllRows"<<endl;
     cout<<"Error number: "<<  ex.getErrorCode() << endl;
     cout<<ex.getMessage() << endl;
    }
 
    stmt->closeResultSet (rset);
    conn->terminateStatement (stmt);
    cout<<endl;
  }
 
  void testproc ()
  {
    cout << "--- Testing Procedure Binds ---" << endl;
    vector<double> myInBind = {10.1,20.2,30.3,40.4};
    vector<double> myInOutBind = {50.5,60.6,70.7,80.8};
    vector<double> myOutBind;
    try{
      cout << "callproc - invoking a PL/SQL procedure having IN, OUT and IN/OUT ";
      stmt = conn->createStatement("BEGIN occivec_demo(:1,:2,:3); END;");
      stmt->setDoubleVector(1,myInBind);
      stmt->setDoubleVector (2,myInOutBind);
      stmt->registerOutParam (3, OCCI_SQLT_VEC);
      stmt->executeUpdate ();
      stmt->getDoubleVector(2,myInOutBind);
      stmt->getDoubleVector(3,myOutBind);
      cout << "Printing the INOUT & OUT parameters:" << endl;
      cout<< "IN/OUT vector:"<<endl;
      for(auto i:myInOutBind)cout<<i<<" ";cout<<endl;
      cout<< "OUT vector:"<<endl;
      for(auto i:myOutBind)cout<<i<<" ";cout<<endl;
      conn->terminateStatement (stmt);
      cout << endl;
    }catch(SQLException ex)
    {
      cout<<"Exception thrown for testproc"<<endl;
      cout<<"Error number: "<<  ex.getErrorCode() << endl;
      cout<<ex.getMessage() << endl;
    }
  }
 
  void insertElement ()
  {
    cout << "--- Inserting in a vector table ---" << endl;
    int num = 1;
    vector<double> myData = {10,20.30,30,40.50};
    vector<double> myResult;
    try{
        stmt = conn->createStatement ("INSERT INTO test_vecint values(:1,:2)");
        stmt->setInt(1,num);
        stmt->setDoubleVector(2,myData);
        stmt->executeUpdate();
        conn->terminateStatement (stmt);
        cout << endl;
    }catch(SQLException ex)
    {
        cout<<"Exception thrown for insertElement"<<endl;
        cout<<"Error number: "<<  ex.getErrorCode() << endl;
        cout<<ex.getMessage() << endl;
    }
  }
 
  void describe_table ()
  {
    cout << "--- Describing the table - TEST_VECDBL ---" << endl;
    vector<MetaData> v1;
    MetaData metaData = conn->getMetaData("TEST_VECDBL");
    v1 =  metaData.getVector(MetaData::ATTR_LIST_COLUMNS);
    for(int i=0;i<v1.size();i++)
    {
        MetaData md = v1[i];
        cout << " Column Name :" << (md.getString(MetaData::ATTR_NAME)) << endl;
        cout << " Data Type :" << (printType (md.getInt(MetaData::ATTR_DATA_TYPE))) << endl;
        cout << " Dimension :"<< md.getUInt(MetaData::ATTR_VECTOR_DIMENSION) << endl;
        cout << endl;
    }
    cout << endl;
  }
 
  string printType (int type)
  {
    switch (type)
    {
      case OCCI_SQLT_NUM : return "NUMBER";
                           break;
      case OCCI_SQLT_VEC:  return "VECTOR";
                           break;
      default: return to_string(type);
    }
  } // End of printType (int)
 
};
 
int main (void)
{
  try{
    cout << "Demo Program for OCCI Vector" << endl;
    occivec *demo = new occivec ();
    demo->insertElement();
    demo->describe_table();
    demo->testproc();
    demo->displayAllRows("TEST_VECDBL");
    delete (demo);
  }
  catch (SQLException ex){
    cout << ex.getMessage() << endl;
  }
  cout << "done" << endl;
}

14.2 スパース・ベクトル

この項では、SparseVectorを操作する関数について説明します。スパース・ベクトルは、それらによってメモリーのコストが減少するため推奨されています。

現在、C++には暗黙的なスパースベクトル・サポートがないため、SparseVectorクラスがデータ構造として導入されています。

ノート:

スパース・ベクトルは、現在のベクトル実装に準拠した0ベースの索引付けに従います。

14.2.1 SparseVectorのコンストラクタ

この項では、SparseVectorのコンストラクタについて説明します。

14.2.1.1 SparseVector()

SparseVector関数では、必要な型のSparseVector (それで使用されている値の型を修正する)が初期化されます。

これがデフォルト・コンストラクタです:
SparseVector<T> mySparseVector();
この関数をライブラリ内で使用すると、次のようにスパース・ベクトルを作成できます:
SparseVector<float> mySparseVector;
14.2.1.2 SparseVector(uint32_t size,vector<uint32_t> indices,vector<T> values)

この関数では、必要なサイズのSparseVectorと、ゼロ以外の値が、それぞれの索引とともに初期化されます。

構文

これらのベクトルをSparseVectorクラスのベクトル・メンバーにコピーします。

ノート:

このサイズは、厳密に索引と値のベクトルの長さ以上である必要があります。また、索引と値の長さが同じであることを確認してください。
SparseVector<T> mySparseVector(uint32_t size, vector<uint32_t> indices, vector<A>
    values);
パラメータ 説明
size スパース・ベクトルの合計サイズを指定します。
indices スパース・ベクトルのゼロ以外の値の索引を指定します。
values スパース・ベクトル内のゼロ以外の索引の値を指定します。

この関数をライブラリ内で使用すると、次のようにスパース・ベクトルを作成できます:

SparseVector<float> mySparseVector(45,{1,5,40},{1.3,2.5,4554}};
14.2.1.3 SparseVec(uint32_t size,pair<vector<uint32_t>,vector<T>> &vecp)参照コンストラクタ

この関数は、より効率的かより高速なコンストラクタです。

構文

独自のクラスのベクトル・メンバー内のベクトルをコピーする必要はありません。かわりに、このコンストラクタでは、引数として指定されたペア内のベクトルへの参照を利用できます。つまり、ユーザーのベクトルに加えられたすべての変更内容がSparseVectorに反映され、その逆も同様です。

SparseVector<T> myCopySparseVector(uint32_t size, pair<vector<uint32_t>,vector<T>>
    &vecp);
パラメータ 説明
size スパース・ベクトルの合計サイズを指定します。
vecp 索引を含むベクトルのペアと、それらのベクトルの値をそれぞれ指定します。
   

次のコード・スニペットは、この関数を使用して既存のスパース・ベクトルからスパース・ベクトルを作成する方法を示しています:

pair<vector<uint32_t>,vector<float>> vecp({1,3,5},{2,4,6});
SparseVector<float> mySparseVector(100,vecp); // now we initialize this does no copies of the vectors inside our pair
 
string sqlStmt = "SELECT * FROM DEMO_TAB"; //Table has one row with two columns (id:2,SparseVector:10,{0,2,4},{3,5,7})
stmt = conn->createStatement (sqlStmt);
rset = stmt->executeQuery ();
while(rset->next())
{
    cout << "ID: " << rset->getInt (1) << endl;
    rset->getSparseVector(2, mySparseVector);
    //each time we do getSparseVector our vecp directly gets modified to the sparse-vector we recieved.
    //We can check this by printing each vectors of vecp.
    for(auto i:vecp.first)
        cout<<i<<" ";
    cout<<endl;
    // this will print 0,2,4 as our indices in SparseVector of our table
    for(auto i:vecp.second)
        cout<<i<<" ";
    cout<<endl;
    // this will print 3,5,7 as our indices in SparseVector of our table
}

ノート:

初期化に使用したペア、つまり、vecpは、データベース操作にmySparseVectorを使用している場合はスコープ外にしないでください。そうでないと、SparseVectorも無効になります。

14.2.2 文ハンドルへのスパース・ベクトルのバインド

この項で説明する関数は、SparseVectorデータを文ハンドルにバインドするために導入されています。

ノート:

スパース・ベクトルと密ベクトルのバインド/定義関数の機能:

密またはスパース・ベクトル列がある表に関係なく、SparseVector/std::vectorを使用して挿入できます。ただし、スパース・ベクトル列からのみSparseVectorをフェッチでき、密ベクトル列からのみ密ベクトル(std::vector)をフェッチできます。

14.2.2.1 setInt8Vector()

int8_t型のOCCI SparseVectorからINT8形式のスパース・ベクトルに値をバインドします。

構文

void setInt8Vector(unsigned int paramIndex, SparseVector<int8_t> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するSparseVectorを指定します。
14.2.2.2 setFloatVector()

float型のOCCI SparseVectorからスパース・ベクトルのIEEE FLOAT32形式に値をバインドします。

構文

void setFloatVector(unsigned int paramIndex, SparseVector<float> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するSparseVectorを指定します。
14.2.2.3 setDoubleVector()

double型のOCCI SparseVectorからIEEE FLOAT64形式のスパース・ベクトルに値をバインドします。

構文

void setDoubleVector(unsigned int paramIndex, SparseVector<double> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するSparseVectorを指定します。
14.2.2.4 setBinaryVector()

uint8_t型のC++ベクトルからOracle Databaseベクトル・データ型の値をバイナリ形式で設定します

構文

ノート:

次元が8の倍数であるベクトルのみ挿入できます。
void setBinaryVector(unsigned int paramIndex, SparseVector<uint8_t> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 設定するSparseVectorを指定します。

次のコード・スニペットは、FLOAT32形式のSparseVector mySparseVectorstmt内の位置1にバインドしています。この文をさらに実行して、それをデータベース表に挿入します:

Statement *stmt;
stmt = conn->createStatement ("INSERT INTO test_sparsevecflt values(:1,:2)");
vector<uint32_t> inds = {0, 5, 9};
vector<float> vals = {1.5, 2.3, 4.6};
SparseVector<float> mySparseVector(10, inds, vals);
stmt->setInt(1,10);
stmt->setFloatVector(2, mySparseVector);
stmt->executeUpdate();

14.2.3 スパース・ベクトルの場合のPL/SQLアウトバインド

この項で説明する関数を使用すると、文ハンドルへのアウトバインドを介してPLSQLプロシージャまたはファンクションからの出力を取得できます。

14.2.3.1 getInt8Vector()

int8_t型のOCCI SparseVectorとして、Oracle Databaseスパース・ベクトル・データ型の値をint8(ub1)形式で取得します。

構文

void getInt8Vector(unsigned int paramIndex, SparseVector<int8_t> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるSparseVector (OUTパラメータ)への参照。
14.2.3.2 getFloatVector()

float型のOCCI SparseVectorとして、Oracle Databaseスパース・ベクトル・データ型の値をIEEE FLOAT32形式で取得します。

構文

void getFloatVector(unsigned int paramIndex, SparseVector<float> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるSparseVector (OUTパラメータ)への参照。
14.2.3.3 getDoubleVector()

double型のOCCI SparseVectorとして、Oracle Databaseスパース・ベクトル・データ型の値をIEEE FLOAT64形式で取得します。

構文

void getDoubleVector(unsigned int paramIndex, SparseVector<double> &vec);
パラメータ 説明
paramIndex パラメータの索引を、第1パラメータは1、第2パラメータは2のように指定します。
vec 値を挿入する必要があるSparseVector (OUTパラメータ)を参照します。

次のサンプル・コード・スニペットでは、アウト・バインドにこの関数を使用して、ベクトルを取得しています:

Statement *stmt;
stmt = conn->createStatement ("BEGIN occivec_demo(:1,:2,:3) END;");
pair<vector<uint32_t>, vector<double>> myInPair = {{3, 7, 8}, {2.6, 7.6, 1001.1}};
pair<vector<uint32_t>, vector<double>> myInOutPair = {{0, 4, 9}, {3, 5.7, 2001}};
pair<vector<uint32_t>, vector<double>> myOutPair;
SparseVector<uint32_t> myInBind(9, myInPair);
SparseVector<uint32_t> myInOutBind(10, myInOutPair);
SparseVector<uint32_t> myOutBind(0, myOutPair);
stmt->setDoubleVector(1, myInBind);
stmt->setDoubleVector(2, myInOutBind);
stmt->registerOutParam(3, OCCI_SQLT_VEC);
stmt->stmtExecute();
stmt->getDoubleVector(2, myInOutBind);
stmt->getDoubleVector(3, myOutBind);

前述のコード・スニペットは、位置2でINOUTバインドから取得したデータをmyInOutBind SparseVectorに取得し、また、位置3でOUTバインドから取得したデータをmyOutBindに取得しています。

14.2.4 問合せのResultSetからのスパース・ベクトルの定義

この項では、C++のstlベクトル・コンテナにSparseVector型の列値を取得するためにResultSetクラスに導入された関数について説明します。

14.2.4.1 getInt8Vector()

int8_t型のOCCI SparseVectorとして、Oracle Databaseスパース・ベクトル・データ型の列値をint8(ub1)形式で取得します。

構文

void getInt8Vector(unsigned int paramIndex, SparseVector<int8_t> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるSparseVector (OUTパラメータ)への参照。
14.2.4.2 getFloatVector()

float型のOCCI SparseVectorとして、Oracle Databaseスパース・ベクトル・データ型の列値をIEEE FLOAT32形式で取得します。

構文

void getFloatVector(unsigned int paramIndex, SparseVector<float> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるSparseVector (OUTパラメータ)への参照。
14.2.4.3 getDoubleVector()

double型のOCCI SparseVectorとして、Oracle Databaseベクトル・データ型の列値をIEEE FLOAT64形式で取得します。

構文

void getDoubleVector(unsigned int paramIndex, SparseVector<double> &vec);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。
vec 値を挿入する必要があるSparseVector (OUTパラメータ)への参照。

次のコード・スニペットは、この関数をResultSet内で使用してスパース・ベクトルを取得する方法を示しています:

Statement stmt;
stmt = conn->createStatement ("SELECT * FROM TEST_SPARSEVECFLT");
ResultSet *rs = stmt->getResultSet();
pair<vector<uint32_t>,vector<float>> myResult;
SparseVector mySparseVector(0, myResult);
stmt->stmtExecute();
rs->getFloatVector(2, myResult);

結果でのSparseVectorデータの型は、指定されたベクトル型に応じて決まります。つまり、SparseVector<float>FLOAT32形式に対応しています。

14.2.4.4 getString()

C++の文字列として、任意の形式のOracle Databaseスパース・ベクトル・データ型の列値を取得します。

構文

string getString(unsigned int paramIndex);
パラメータ 説明
colIndex 列の索引を、第1列は1、第2列は2のように指定します。

次のコード・スニペットは、ResultSet内でこの関数を使用してベクトルを取得する方法を示しています:

Statement stmt;
stmt = conn->createStatement ("SELECT id,embedding FROM TEST_SPARSEVECFLT");
ResultSet *rs = stmt->getResultSet();
stmt->stmtExecute();
int id = rs->getInt(1);
string vec = rs->getString(2);

14.3 SparseVectorのユーティリティ関数

この項では、SparseVectorクラスのメンバー関数について説明し、SparseVectorによって格納されているベクトルの密形式を返します。

14.3.1 toDenseVec()

<T>型のOCCI SparseVectorの密ベクトル形式を返します。

構文

vector<T> toDense();

ノート:

ここでは、Tはベクトル値の目的の型です。

次のコード・スニペットは、SparseVector内でこの関数を使用して密ベクトルを取得する方法を示しています:

SparseVector<float> mySparseVector(10,{0,5,9},{0.5,5.5,9.5});
vector<float> myDenseVector = mySparseVector.toDense();
for(auto i:myDenseVector)
    cout<<i<<" ";
cout<<endl;