39 OCIでのベクトル・データ型のサポート
この項では、ベクトル列値をフェッチおよび変更するためのOCI (Oracle Call Interface) APIの拡張機能について説明します。ベクトル列のバインドまたは定義に使用できる様々なCデータ型をリストします。また、ベクトル・メタデータにアクセスするための詳細も提供します。
トピック:
39.1 OCIVector記述子
この項では、OCIVector記述子を使用してOCI (Oracle Call Interface)でVECTORを表す方法について説明します。
OCIVector記述子は、記述子タイプOCI_DTYPE_VECTORによって識別されます。OCIVector記述子は、OCIDescriptorAlloc()およびOCIDescriptorFree()関数を使用してそれぞれ割当ておよび解放できます。OCIVector記述子のインスタンスは、サーバーとの間でVECTORコンテンツの読取り(OCIDefine*())および書込み(OCIBind*())に使用できます。OCIVectorFromTextまたはOCIVectorFromArray関数を使用して、ベクトル記述子を移入することもできます。OCIVector記述子に存在するベクトル・データは、OCIVectorToTextまたはOCIVectorToArray関数を使用してフェッチできます。
記述子の配列を割り当てる必要がある場合は、OCIArrayDescriptorAlloc関数とOCIArrayDescriptorFree関数を使用します。
| OCI記述子 | 説明 | OCI記述子型定数 |
|---|---|---|
OCIVector * |
VECTOR記述子 | OCI_DTYPE_VECTOR |
関連項目:
OCIVectorのバインドと定義 *39.2 OCIVector記述子の属性
この項では、OCIVector記述子の属性について説明します。
OCI_ATTR_VECTOR_DATA_FORMAT
OCI_ATTR_VECTOR_PROPERTY
39.3 外部VECTORデータ型とOCI
この項では、SQLデータ型VECTORのOracle Call Interface(OCI)データ型定数について説明します。VECTORは、Oracle Databaseで認識されるデータ型です。
VECTORデータ型は定数SQLT_VECを使用して表されます。つまり、クライアントは、データ型定数としてSQLT_VECを使用して、VECTOR記述子をwrite (OCI定義)およびread (OCIバインド)できます。
| 外部データ型 | プログラム変数 | SQL型定数 |
|---|---|---|
VECTOR |
OCIVector* |
SQLT_VEC |
ノート:
VECTORデータ型には、32MBというサイズ制限があります。関連項目:
外部データ型39.4 VECTOR SQLデータ型のサポートのバインドまたは定義
VECTORデータ型のバインドまたは定義をサポートするために、OCIでは、外部データ型定数SQLT_VEC (OCIVector*)を有効にして、バインドの目的にOCIVectorFromArrayを使用してdouble、floatまたはintegerの配列のネイティブ表現を設定できるようにします。OCIVector記述子には、定義時の正規表現があります。ユーザーは、OCIVectorToArray関数を使用してネイティブ表現の配列を取得できます。
関連項目:
ベクトル用のコード・スニペットの例Oracleデータベースでは、char、nchar、varchar2、nvarchar2、CLOBおよびNCLOBからVECTORデータ型への暗黙的な変換が可能であり、その逆も可能です。したがって、ユーザーはこれらの外部データ型を使用できます。Oracle Databaseはバインドのために暗黙的な変換を処理し、クライアントは定義のために暗黙的な変換を処理します。VECTORをバインド型または定義型として指定できない古いクライアントの場合、サポートされる唯一のバインド型または定義型は、char、char varchar2、nvarchar2、CLOBおよびNCLOBに対応する文字列型バインドまたは定義のみです。
ベクトル列型を持つ表の記述情報は、OCIDescribeAny()を介して公開されます。
PL/SQL OUTバインド用に新しい外部データ型SQLT_VECが導入されました。この外部データ型は、VECTORデータ型の列に対してバインドまたは定義を行うためにオーバーロードされます。
39.5 OCIベクトル・サポート関数
OCIベクトル・サポート関数は、ネイティブなC配列とOCIVector記述子との間の変換のために提供されています。また、char、nchar、varchar2、nvarchar2、CLOBおよびNCLOB外部データ型をベクトル列のバインドまたは定義に使用できます。
表39-1 OCIベクトル・サポート関数
| 関数 | 用途 |
|---|---|
OCIVectorFromText |
ベクトルのテキスト表現をベクトル形式に変換します。 |
OCIVectorFromArray |
ベクトルの配列表現をベクトル形式に変換します。 |
OCIVectorToText |
ベクトルをテキスト形式に変換します。 |
OCIVectorToArray |
ベクトルを配列形式に変換します。 |
39.5.1 OCIVectorFromText
ベクトルのテキスト表現をベクトル形式に変換します。
用途
ベクトルのテキスト表現をベクトル形式に変換します。入力テキストを記述子に格納されるベクトルに変換するには、OCIVectorDescriptor、エラー・ハンドル、ベクトル形式、ベクトル・テキスト、テキスト長および様々なベクトル・フラグを使用します。
構文
sword OCIVectorFromText(OCIVector *vectord, OCIError *errhp, ub1 vformat, ub4 vdim
const OraText *vtext, ub4 vtextlen, ub4 mode);
パラメータ
| パラメータ | 用途 |
|---|---|
OCIVector *vectord (IN/OUT) |
ベクトルに関連付けられたOCIVector記述子を指定します。入力テキストのベクトル表現を格納します。
|
OCIError *errhp |
変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。 |
ub1 vformat |
テキストに存在する要素の形式(OCI_ATTR_VECTOR_FORMAT_*値)を指定します。
|
ub4 vdim |
ベクトル・テキスト内の次元数を指定します。 |
const OraText * vtext
|
ベクトルに変換する入力テキストを指定します。 |
ub4 vtextlen |
入力テキストの長さを指定します。 |
ub4 mode
|
将来役立つ可能性のあるフラグを指定します。
現在のデフォルト・フラグは |
戻り値
OCI_SUCCESS (正常に実行された場合)。
OCI_ERROR (エラーが返された場合)。
39.5.2 OCIVectorFromArray
ベクトルの配列表現をベクトル形式に変換します。
用途
OCIVectorFromArray関数は、入力配列を記述子に格納されるベクトルに変換するために、OCIVectorDescriptor、エラー・ハンドル、ベクトル形式、ベクトル次元、ベクトル配列およびその他の様々なベクトル・フラグを使用します。
構文
sword OCIVectorFromArray(OCIVector *vectord, OCIError *errhp, ub1 vformat,
ub4 vdim, void *vecarray, ub4 mode);
表39-2 パラメータ
| パラメータ | 用途 |
|---|---|
OCIVector *vectord (IN/OUT) |
入力テキストのベクトル表現を格納するOCIVector記述子を指定します。
|
OCIError *errhp
|
変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。 |
ub1 vformat |
配列に存在する要素の形式(OCI_ATTR_VECTOR_FORMAT_*値)を指定します。次のように値を使用します:
|
ub4 vdim |
配列内の要素の数を指定します。 |
void *vecarray |
ベクトルに変換する配列を指定します。 |
ub4 mode
|
将来役立つ可能性のあるフラグを指定します。
現在のデフォルト・フラグは |
OCI_SUCCESS (正常に実行された場合)。
OCI_ERROR (エラーが返された場合)。
39.5.3 OCIVectorToText
ベクトルをテキスト形式に変換します。
用途
OCIVectorToText関数は、記述子に格納されるベクトルをテキスト形式に変換するために、OCIVectorDescriptor、エラー・ハンドル、テキスト・ポインタ、テキスト長ポインタ、その他様々なベクトル・フラグを使用します。
構文
sword OCIVectorToText(OCIVector *vectord, OCIError *errhp, text *vtext,
ub4 *vtextlen, ub4 mode);
表39-3 パラメータ
| パラメータ | 用途 |
|---|---|
OCIVector *vectord |
データのベクトル表現を格納するOCIVector記述子を指定します。
|
OCIError *errhp |
変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。 |
OraText *vtext |
ベクトルのテキスト表現に使用されるバッファへのポインタを指定します。この関数のコール元がこのメモリーを割り当てる必要があります。 |
ub4 *vtextlen |
関数に渡されるテキスト・バッファの長さへのポインタを指定します
ノート: バッファ・サイズが小さい場合、エラー51810が返され、データが切り捨てられます。ノート: エラー51810、「VECTORからCHARまたはVARCHARへの変換を行うにはバッファ・サイズが不十分です。」
バッファ・サイズが不十分であり、VECTOR列を指定された CHARまたはVARCHARバッファ・サイズが、変換されたVECTOR列値を格納するのに十分であることを確認します。関数LENGTH(FROM_VECTOR(<vector>))は、適切なバッファ・サイズを決定するために使用されます。
|
ub4 mode |
将来役立つ可能性のあるフラグを指定します。
現在のデフォルト・フラグは |
戻り値
OCI_SUCCESS(正常に実行された場合)。OCI_ERROR(エラーが返された場合)。ベクトルを保持するための十分な割当てメモリーが入力バッファにない場合、OCI_ERRORが返されます。
39.5.4 OCIVectorToArray
ベクトルを配列形式に変換します。
用途
OCIVectorToArray関数は、記述子に格納されているベクトルを配列形式に変換するために、OCIVectorDescriptor、エラー・ハンドル、ベクトル形式、ベクトル次元へのポインタ、配列へのポインタ、その他様々なベクトル・フラグを使用します。
構文
sword OCIVectorToArray(OCIVector *vectord, OCIError *errhp, ub1 vformat,
ub4 *vdim, void *vecarray, ub4 mode);
表39-4 パラメータ
| パラメータ | 用途 |
|---|---|
OCIVector *vectord
|
データのベクトル表現を格納するOCIVector記述子を指定します。
|
OCIError *errhp |
変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。 |
ub1 vformat |
記述子に格納されるベクトルの形式(OCI_ATTR_VECTOR_FORMAT_*値)を指定します。
|
ub4 *vdim |
配列バッファ内の次元数へのポインタを指定します。出力値はベクトル内の実際のディメンション数です。 |
void *vecarray |
ベクトル配列へのポインタを指定します。この関数のコール元は、ベクトルの次元数に対応するためにこのメモリーを割り当てる必要があります。これは、vformatパラメータを使用して指定されたベクトル形式のサイズを乗算したvdimパラメータを使用して指定されます。
|
ub4 mode
|
将来役立つ可能性のあるフラグを指定します。
現在のデフォルト・フラグは |
戻り値
OCI_SUCCESS(正常に実行された場合)。OCI_ERROR(エラーが返された場合)。ベクトルを保持するための十分な割当てメモリーが入力バッファにない場合、OCI_ERRORが返されます。
39.5.5 OCIVectorFromSparseArray
要素のSPARSE配列表現をOCIVector記述子に変換します。
用途
OCIVectorFromSparseArray関数は、要素のSPARSE配列表現をOCIVector記述子に変換します。この記述子は、DMLのプレースホルダをバインドするために使用することや、記述子属性操作で使用することができます。
構文
sword OCIVectorFromSparseArray(OCIVector *vectord, OCIError *errhp, ub1 vformat, ub4 vdim,
ub4 indices, void *indarray, void *vecarray, ub4 mode);
表39-5 パラメータ
| パラメータ | 説明 |
|---|---|
vectord (IN/OUT) |
ベクトル記述子へのポインタを指定します。 |
errhp (IN/OUT) |
エラー・ハンドルを指定します。 |
vformat (IN) |
ベクトルの形式を指定します。サポートされている形式値:
|
vdim (IN) |
SPARSEベクトルの合計次元数を指定します。 |
indices (IN) |
索引配列の次元数を指定します。 |
indarray (IN) |
ゼロ以外の次元索引位置値を含む配列へのポインタを指定します。 |
vecarray (IN) |
SPARSEベクトルのvformat値の要素の配列へのポインタを指定します。
|
mode (IN) |
操作モードを指定します。 |
戻り値
-
OCI_ERROR: エラーが返された場合。 OCI_SUCCESS: 関数が正常に実行された場合。OCI_INVALID_HANDLE: 記述子またはエラー・ハンドルが無効な場合。
ノート:
indarrayの入力には、ゼロ以外の次元の索引が含まれています。vecarrayの入力には、これらの索引のvformatの要素の配列が含まれています。索引は1ベースで、索引配列の最初の要素は0ではなく1です。例39-1
密配列[0, 1.0, 0, 1.0, 0]の入力は次のようになります:
vdim = 5、indices = 2、indarray = [2,4]、vecarray = [1.0, 1.0]
39.5.6 OCIVectorToSparseArray
OCIVector記述子の内容を、要素のSPARSE配列表現に変換します。
用途
OCIVectorToSparseArray関数は、OCIVector記述子の内容を要素のSPARSE配列表現に変換します。この配列表現を使用すると、DMLのプレースホルダをバインドしたり、記述子属性操作で使用できます。
構文
sword OCIVectorToSparseArray(OCIVector *vectord, OCIError *errhp, ub1 vformat,
ub4 *vdim, ub4 *indices, void *indarray, void *vecarray, ub4 mode);
表39-6 パラメータ
| パラメータ | 説明 |
|---|---|
vectord (IN/OUT)
|
ベクトル記述子へのポインタを指定します。 |
errhp (IN/OUT) |
エラー・ハンドルを指定します。 |
vformat (IN) |
ベクトルの形式を指定します。OCI_ATTR_VECTOR_FORMAT_*を参照してください |
vdim (IN/OUT) |
indarrayのサイズを含むポインタを指定します。出力値には、SPARSEベクトルの合計次元数が含まれています。 |
indices (OUT) |
indarrayの次元数が移入されるポインタを指定します。 |
indarray (OUT) |
ゼロ以外のSPARSEベクトルの次元の索引が移入されるバッファへのポインタを指定します。 |
vecarray (OUT) |
SPARSEベクトルのvformat要素の配列が移入されるバッファへのポインタを指定します |
mode (IN) |
操作モードを指定します。 |
戻り値
OCI_ERROR: エラーが発生して、エラーが返された場合。OCI_SUCCESS: 関数が正常に実行された場合。OCI_INVALID_HANDLE: 記述子またはエラー・ハンドルが無効な場合。
ノート:
indarrayの出力には、ゼロ以外の次元の索引が含まれています。vecarrayの出力には、これらの索引のvformat要素の配列が含まれています。索引は1ベースで、索引配列の最初の要素は0ではなく1です。たとえば、密配列[0, 1.0, 0, 1.0, 0]の場合、次の出力が返されます:
vdim = 5、indices = 2、indarray = [2,4]、vecarray = [1.0, 1.0]
39.6 OCIVectorのバインドと定義 *
OCIユーザーは、OCIVector*型の記述子を割り当て、これにinteger、floatまたはdoubleコンテンツの配列を割り当てて、SQLデータ型がVECTORであるデータベース表の列の書き込みに使用することができます。バインドおよび定義用の入力データ型は、SQLT_VECである必要があります。
SQLT_CHR: 文字列SQLT_CLOB: 文字LOBSQLT_STR: NULLで終了する文字列SQLT_LNG: 長い文字列SQLT_LVC: より長い文字列SQLT_AFC: ANSI固定文字列SQLT_AVC: ANSI可変文字列SQLT_VCS: 可変文字列
39.7 OCIDescribeAnyの拡張機能
この項では、新しいVECTOR列タイプの表またはビューに関する説明をサポートするために、OCIDescribeAnyに含まれる機能拡張について説明します。
OCIには、データベース・オブジェクト(表など)を明示的に記述してメタデータを取得する機能があります。また、OCIは、問合せ実行への応答の一部として選択されている列のメタデータを暗黙的に受信します。明示的記述と暗黙的記述の両方の場合、列メタデータは、OCIParam *型のパラメータ・ハンドルまたはベクトル記述子を介してアクセスされます。新しく導入されたOCIParamハンドル属性OCI_ATTR_VECTOR_DIMENSION、OCI_ATTR_VECTOR_DATA_FORMATおよびOCI_ATTR_VECTOR_PROPERTYは、ベクトル次元、ベクトル・データ形式およびベクトル・プロパティにそれぞれアクセスするために使用されます。
vector_dimensionの長さがub4に固定されているため、Vector_dimension_lenは移入されません。OCIAttrGet((dvoid*) colParamHandle, (ub4) OCI_DTYPE_PARAM,
(dvoid*) &vector_dimension, (ub4 *) &vector_dimension_len,
(ub4) OCI_ATTR_VECTOR DIMENSION,
(OCIError *) errhp)
vector_data_typeの長さがub1に固定されているため、Vector_data_format_lenは返されません。
OCIAttrGet((dvoid*) colParamHandle, (ub4) OCI_DTYPE_PARAM,
(dvoid*) &vector_data_format, (ub4 *) &vector_data_format_len,
(ub4) OCI_ATTR_VECTOR_DATA_FORMAT,
(OCIError *) errhp)
次のコールは、指定された列パラメータ・ハンドルのベクトルのプロパティを返し、列に関連付けられたプロパティがない場合は0を返します。現在、実装されている唯一のプロパティはOCI_ATTR_VECTOR_COL_PROPERTY_IS_FLEXです。
OCIAttrGet((dvoid*) colParamHandle, (ub4) OCI_DTYPE_PARAM,
(dvoid*) &vector_property, (ub4 *) &vector_property_len,
(ub4) OCI_ATTR_VECTOR_PROPERTY,
(OCIError *) errhp)
属性OCI_ATTR_VECTOR_DIMENSION、OCI_ATTR_VECTOR_DATA_FORMATおよびOCI_ATTR_VECTOR_PROPERTYは、実表の列、ビュー列、およびベクトルが関連付けられているSELECTリスト内のすべての要素に対して適用する必要があります。
OCIAttrGetをコールして属性を取得することもできます:
OCIAttrGet((dvoid *)vectorDescriptor, OCI_DTYPE_VECTOR, (void *)&vectdim, (ub4*) 0, OCI_ATTR_VECTOR_DIMENSION, (OCIError *)errhp);OCIAttrGet((dvoid *)vectorDescriptor, OCI_DTYPE_VECTOR, (void *)&vectformat, (ub4*) 0, OCI_ATTR_VECTOR_FORMAT, (OCIError *)errhp);OCIAttrGet((dvoid *)vectorDescriptor, OCI_DTYPE_VECTOR, (void *)&vectprop, (ub4*) 0, OCI_ATTR_VECTOR_PROPERTY, (OCIError *)errhp);
39.8 ベクトル用のコード・スニペットの例
SELECT文
OCIStmt *ociStmt = (OCIStmt *)NULL;
OCIDefine *defnhp1 = NULL;
OCIVector *vecp = NULL;
OraText *selstmt = "SELECT embedding FROM test ORDER BY id";
sb2 ind1 = 0;
OCIHandleAlloc(ociEnv, (void*) &ociStmt, OCI_HTYPE_STMT, 0, 0);
OCIStmtPrepare2(ociSvcCtx, ociStmt, ociError, selstmt, (ub4)sizeof((selstmt) - 1),
(ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
OCIDescriptorAlloc(ociEnv, (void**) &vecp, OCI_DTYPE_VECTOR, 0, 0);
OCIDefineByPos(ociStmt, &defnhp1, ociError,1, &vecp, 0, SQLT_VEC, &ind1, NULL, 0, OCI_DEFAULT);
OCIStmtExecute(ociSvcCtx, ociStmt, ociError, 0, 0, 0, 0, OCI_DEFAULT);OraText *insStmt = "INSERT INTO test VALUES(%d, '[%d.1, %d.2, %d.3]')";
OCIHandleAlloc(ociEnv, (void*) &insStmt, OCI_HTYPE_STMT, 0, 0);
OCIStmtPrepare2(ociSvcCtx, ociStmt, ociError, insStmt, (ub4)stmtlen,
(ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
OCIStmtExecute(ociSvcCtx, ociStmt, ociError, 0, 0, 0, 0, OCI_DEFAULT);OCIStmt * ociStmt = (OCIStmt *)NULL;
OCIBind * ociBind1 = (OCIBind *)NULL;
OCIBind * ociBind2 = (OCIBind *)NULL;
OraText *insstmtbnd = "INSERT INTO test VALUES(:1, :2)";
signed int bnd1 = 500;
OCIVector *vecp = NULL;
sb2 ind1 = 0;
sb2 ind2 = 0;
OCIHandleAlloc(ociEnv, (void*) &ociStmt, OCI_HTYPE_STMT, 0, 0);
OCIStmtPrepare2(ociSvcCtx, ociStmt, ociError, insstmtbnd, (ub4)(sizeof(insstmtbnd) - 1),
(ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
OCIDescriptorAlloc(ociEnv, (void**) &vecp, OCI_DTYPE_VECTOR, 0, 0);
OCIBindByPos(ociStmt, &ociBind1, ociError,
1, &bnd1, sizeof(signed int), SQLT_INT,
&ind1, NULL, NULL, 0, NULL, OCI_DEFAULT);
OCIBindByPos(ociStmt, &ociBind2, ociError,2, &vecp, 0, SQLT_VEC, &ind2, NULL, NULL, 0, NULL,
OCI_DEFAULT);OCIVector API
ub2 vformat = OCI_ATTR_VECTOR_TYPE_FLOAT32;
ub4 vdim = 3;
float vfarr[3];
text vtext[UB2MAXVAL];
OCIError *errhp = (OCIError *) NULL;
OCIVector *vecp = NULL;
ub4 indx;
OCIVectorToText(vecp, errhp, &vtext[0], &vtextl, OCI_DEFAULT);
for (indx=0; indx++; indx < vdim)
vfarr[idx] = indx + indx * 3.1427;
OCIVectorFromArray(vecp, errhp, vformat, vdim,
(void *)&vfarr[0], OCI_DEFAULT);