20 ダイレクト・パス・ロード・インタフェース
ダイレクト・パス・ロード関数は、データを外部ファイルから表とパーティションにロードするために使用します。
この章には次のトピックが含まれます:
20.1 ダイレクト・パス・ロードの概要
ダイレクト・パス・ロード・インタフェースを使用すると、OCIアプリケーションからOracle Databaseのダイレクト・パス・ロード・エンジンにアクセスし、SQL*Loaderユーティリティの関数を実行できます。
この機能によって、データを外部ファイルから表またはパーティション表のパーティションのいずれかにロードできます。
図20-1では、この章のテーマを紹介しています。この図のクライアント側では、データは入力バッファを通して列配列に入力されます。OCIDirPathColArrayToStream()
コールにより、データがストリーム形式でサーバー側に移動します。これによりデータが列配列に渡され、この列配列はブロック・フォーマッタを使用して、データをデータベース表に送信します。
OCIダイレクト・パス・ロード・インタフェースには、複数行のデータが含まれたダイレクト・パス・ストリームをロードすることによって複数の行をロードできます。
ダイレクト・パスAPIを使用するには、クライアント・アプリケーションで次のステップを実行します。
-
OCIを初期化します。
-
ダイレクト・パス・コンテキスト・ハンドルを割り当てて、属性を設定します。
-
ロードするオブジェクト(表、パーティションまたはサブパーティション)の名前を指定します。
-
オブジェクトの列の外部データ型を記述します。
-
ダイレクト・パス・インタフェースを準備します。
-
1列以上の列配列を割り当てます。
-
1つ以上のダイレクト・パス・ストリームを割り当てます。
-
列配列内のエントリを、各列に対する入力データ値を指し示すように設定します。
-
列配列をダイレクト・パス・ストリーム形式に変換します。
-
ダイレクト・パス・ストリームをロードします。
-
発生したエラーをすべて取り出します。
-
ダイレクト・パス終了関数をコールします。
-
ハンドルおよびデータ構造を解放します。
-
サーバーから切断します。
ステップ8から11は、ロード対象のデータに従って繰り返すことができます。
ダイレクト・ロード操作では、オブジェクトでDML操作が行われないように、ロード対象のオブジェクトをロックする必要があります。オブジェクトがロードされる間、問合せはロック解除されており、使用可能です。DMLロックのモードおよび取得されるDMLロックは、OCI_ATTR_DIRPATH_PARALLEL
オプションの仕様、および表全体のロードではなくパーティションまたはサブパーティションのロードが実行されているかどうかに応じて異なります。
-
表のロードの場合、
OCI_ATTR_DIRPATH_PARALLEL
オプションの設定とその結果は、次のとおりです。-
FALSEの場合、表DML X-Lockが取得されます。
-
TRUEの場合、表DML S-Lockが取得されます。
-
-
パーティションのロードの場合、
OCI_ATTR_DIRPATH_PARALLEL
オプションの設定とその結果は、次のとおりです。-
FALSEの場合、表DML SX-LockとパーティションDML X-Lockが取得されます。
-
TRUEの場合、表DML SS-LockとパーティションDML S-Lockが取得されます。
-
20.1.1 ダイレクト・パス・ロードでサポートされるデータ型
ダイレクト・パス・ロード操作でスカラー列に対して有効な外部データ型を示します。
ダイレクト・パス・ロード操作では、スカラー列に対して有効な外部データ型は次のとおりです。
-
SQLT_CHR
-
SQLT_DAT
-
SQLT_INT
-
SQLT_UIN
-
SQLT_FLT
-
SQLT_BIN
-
SQLT_NUM
-
SQLT_PDN
-
SQLT_CLOB
-
SQLT_BLOB
-
SQLT_DATE
-
SQLT_TIMESTAMP
-
SQLT_TIMESTAMP_TZ
-
SQLT_TIMESTAMP_LTZ
-
SQLT_INTERVAL_YM
-
SQLT_INTERVAL_DS
次の外部オブジェクトのデータ型がサポートされています。
-
SQLT_NTY
- 列オブジェクト(FINAL
とNOT FINAL
)およびSQL文字列の列 -
SQLT_REF
-REF
列(FINAL
とNOT FINAL
)
次の表の型がサポートされています。
-
ネストした表
-
オブジェクト表(
FINAL
とNOT FINAL
)
関連項目:
-
列のデータ型の設定または取出しの詳細は、「列パラメータ属性へのアクセスについて」を参照してください
-
データ型の詳細は、表4-2を参照してください。
20.1.2 ダイレクト・パス・ハンドル
ダイレクト・パス・ロードは、ダイレクト・パス配列の挿入操作に対応しています。
ダイレクト・パス・ロード・インタフェースでは、次のハンドルを使用してロードされるオブジェクトおよび操作するデータの指定が記録されます。
-
関連項目:
「ダイレクト・パス・ロード・ハンドル属性」およびこの後述のダイレクト・パス属性に関する説明を参照してください
20.1.2.1 ダイレクト・パス・コンテキスト
ダイレクト・パス・コンテキスト・ハンドルは、ロード対象の各オブジェクト(表またはパーティション表のパーティションのいずれか)に対して割り当てる必要があります。
OCIDirPathCtx
ハンドルは、OCIDirPathFuncCtx
、OCIDirPathColArray
およびOCIDirPathStream
ハンドルの親ハンドルであるため、OCIDirPathCtx
ハンドルを解放すると、その子ハンドルも解放されます(ただし、親ハンドルの解放前に、子ハンドルを個別に解放するコーディングをお薦めします)。
ダイレクト・パス・コンテキストは、OCIHandleAlloc()
を使用して割り当てます。ダイレクト・パス・コンテキストの親ハンドルは、常に環境ハンドルです。ダイレクト・パス・コンテキストは、OCIHandleFree()
を使用して解放します。例20-1に示すように、すべてのダイレクト・パス・プログラムの最初の2行にヘッダー・ファイルを組み込みます。
例20-1 ヘッダー・ファイルを組み込む必要があるダイレクト・パス・プログラム
... #include <cdemodp0.h> #include <cdemodp.h> OCIEnv *envp; OCIDirPathCtx *dpctx; sword error; error = OCIHandleAlloc((void *)envp, (void **)&dpctx, OCI_HTYPE_DIRPATH_CTX, (size_t)0,(void **)0); ... error = OCIHandleFree(dpctx, OCI_HTYPE_DIRPATH_CTX);
20.1.2.2 OCIダイレクト・パス関数コンテキスト
ダイレクト・パス関数コンテキスト・ハンドルを使用して、名前付き型とREF
列(列オブジェクト、REF列およびSQL文字列の列)を記述します。
OCIDirPathFuncCtx
型のダイレクト・パス関数コンテキスト・ハンドルは、次の名前付き型とREF
列の記述に使用します。
-
列オブジェクト。このオブジェクト内の関数コンテキストでは、オブジェクト型が記述され、デフォルト・コンストラクタとして使用されて、オブジェクトとそのコンストラクタのオブジェクト属性を作成します。
-
REF
列。この列内の関数コンテキストでは、行オブジェクトの参照元である単一のオブジェクト表(オプション)および各行オブジェクトを識別するREF
引数が記述されます。 -
SQL文字列の列。この列内の関数コンテキストでは、列にロードする値を計算するためのSQL文字列とその引数が記述されます。
例20-2に示すように、関数コンテキストの割当てを示すには、OCI_HTYPE_DIRPATH_FN_CTX
ハンドル型をOCIHandleAlloc()
に渡します。
ダイレクト・パス関数コンテキストの親ハンドルは、常にダイレクト・パス・コンテキスト・ハンドルであることに注意してください。次のOCIHandleFree()
を使用して、ダイレクト・パス関数コンテキスト・ハンドルを解放します。
error = OCIHandleFree(dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX);
例20-2 関数コンテキストを割り当てるためにハンドル型を渡す例
OCIDirPathCtx *dpctx; /* direct path context */ OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (size_t)0, (void **)0);
関連項目:
-
サポートされているデータ型の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください
20.1.2.3 ダイレクト・パス列配列およびダイレクト・パス関数列配列
ダイレクト・パス・インタフェースに行配列を表示するには、ダイレクト・パス列配列ハンドルおよびダイレクト・パス関数列配列ハンドルを使用します。
行は、列の値、列の長さおよび列フラグの3つの配列によって表します。列配列で使用するメソッドには、配列ハンドルの割当て、および配列のエントリに対応する値の設定や取得があります。
これらのハンドルは同じデータ構造体OCIDirPathColArray
を共有しますが、この2つの列配列ハンドルは、親ハンドルとハンドル型が異なります。
ダイレクト・パス列配列ハンドルは、OCIHandleAlloc()
を使用して割り当てます。例20-3のコード・フラグメントは、ダイレクト・パス列配列ハンドルの明示的な割当てを示します。
ダイレクト・パス列配列ハンドルは、OCIHandleFree()
を使用して解放します。
error = OCIHandleFree(dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY);
例20-4は、ダイレクト・パス関数列配列ハンドルをほとんど同じ方法で割り当てることを示しています。
ダイレクト・パス関数列配列ハンドルは、OCIHandleFree()
を使用して解放します。
error = OCIHandleFree(dpfnca, OCI_HTYPE_DIRPATH_FN_COL_ARRAY);
OCIDirPathColArray
ハンドルの解放により、そのハンドルに関連付けられた列配列も解放されます。
例20-3 ダイレクト・パス列配列ハンドルの明示的な割当て
OCIDirPathCtx *dpctx; /* direct path context */ OCIDirPathColArray *dpca; /* direct path column array */ sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, (size_t)0, (void **)0);
例20-4 ダイレクト・パス関数列配列ハンドルの明示的な割当て
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ OCIDirPathColArray *dpfnca; /* direct path function column array */ sword error; error = OCIHandleAlloc((void *)dpfnctx, (void **)&dpfnca, (ub4)OCI_HTYPE_DIRPATH_FN_COL_ARRAY, (size_t)0, (void **)0);
関連項目:
20.1.2.4 ダイレクト・パス・ストリーム
ダイレクト・パス・ストリームは、Oracle表データの線形表現です。
変換操作OCIDirPathColArrayToStream()
およびロード操作OCIDirPathLoadStream()
には、ダイレクト・パス・ストリーム・ハンドルを使用します。
ダイレクト・パス・ストリーム・ハンドルは、クライアントがOCIHandleAlloc()
を使用して割り当てます。OCIDirPathStream
ハンドルの構造体は、フォーム(バッファ、バッファ長)内のペアとみなすことができます。
変換操作は、常にストリームの最後に追加されます。ロード操作は、常にストリームの最初に起動します。ストリームのロードが正常終了した後、OCIDirPathStreamReset()
をコールしてストリームをリセットする必要があります。
例20-5は、OCIHandleAlloc()
を使用して割り当てられるダイレクト・パス・ストリーム・ハンドルを示しています。親ハンドルは、常にOCIDirPathCtx
ハンドルです。
ダイレクト・パス・ストリーム・ハンドルは、OCIHandleFree()
を使用して解放します。
error = OCIHandleFree(dpstr, OCI_HTYPE_DIRPATH_STREAM);
OCIDirPathStream
ハンドルの解放によって、そのハンドルに関連付けられているストリーム・バッファも解放されます。
例20-5 ダイレクト・パス・ストリーム・ハンドルの割当て
OCIDirPathCtx *dpctx; /* direct path context */ OCIDirPathStream *dpstr; /* direct path stream */ sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpstr, OCI_HTYPE_DIRPATH_STREAM, (size_t)0,(void **)0);
20.1.3 ダイレクト・パス・インタフェースの関数について
ダイレクト・パス・ロード・インタフェースとともに使用する関数をリストし、説明します。
この項にリストされた関数は、ダイレクト・パス・ロード・インタフェースとともに使用します。
ダイレクト・パス・コンテキストの操作は、表20-1の関数で実行します。
表20-1 ダイレクト・パス・コンテキストの関数
関数 | 用途 |
---|---|
ダイレクト・パス処理を終了します。 |
|
データのセーブポイントを実行します。 |
|
ロードされたデータをコミットします。 |
|
サーバーから部分的にロードされた行をフラッシュします。この関数は非推奨です。 |
|
ダイレクト・パス・ストリーム形式に変換されたデータをロードします。 |
|
行の変換またはロードを行うために、ダイレクト・パス・インタフェースを準備します。 |
ダイレクト・パス列配列の操作は、表20-2の関数で実行します。
表20-2 ダイレクト・パス列配列の関数
関数 | 用途 |
---|---|
列配列内の特定のエントリを取得します。 |
|
列配列内の特定のエントリを特定の値に設定します。 |
|
特定の行番号の基本行ポインタを取得します。 |
|
行配列の状態をリセットします。 |
|
列配列形式からダイレクト・パス・ストリーム形式に変換します。 |
ダイレクト・パス・ストリームの操作は、ダイレクト・ストリームの状態をリセットするOCIDirPathStreamReset()関数で実行します。
関連項目:
各関数の詳細は、「ダイレクト・パス・ロード関数」を参照してください
20.1.4 ダイレクト・パス・ロード・インタフェースに関する制限と制約
ダイレクト・パス・ロード・インタフェースの制限事項をリストします。
ダイレクト・パス・ロード・インタフェースには、SQL*Loaderと同じ次の制限があります。
-
トリガーがサポートされていません。
-
参照整合性制約がサポートされていません。
-
クラスタ化表がサポートされていません。
-
リモート・オブジェクトのロードがサポートされていません。
-
LONG
は最後に指定してください。 -
LOB、オブジェクトまたはコレクションを戻すSQL文字列がサポートされていません。
-
VARRAY
列のロードがサポートされていません。 -
すべてのパーティション列は、LOBの前に指定する必要があります。これは、LOBをパーティションに書き込む前に、書込み先のパーティションを確認する必要があるためです。
20.1.5 スカラー列に対するダイレクト・パス・ロードの例
この項では、スカラー列に対するダイレクト・パス・ロードの例を説明します。
20.1.5.1 ダイレクト・パス・ロードの例で使用されているデータ構造
ダイレクト・パス・ロードでデータ構造を使用する例を示します。
例20-6は、例20-7から例20-17までで使用されるデータ構造を示しています。
例20-7は、複数の構造体を定義するdemo
ディレクトリのヘッダー・ファイルcdemodp.h
を示しています。
例20-6 ダイレクト・パス・ロードの例で使用されているデータ構造
/* load control structure */ struct loadctl { ub4 nrow_ctl; /* number of rows in column array */ ub2 ncol_ctl; /* number of columns in column array */ OCIEnv *envhp_ctl; /* environment handle */ OCIServer *srvhp_ctl; /* server handle */ OCIError *errhp_ctl; /* error handle */ OCIError *errhp2_ctl; /* yet another error handle */ OCISvcCtx *svchp_ctl; /* service context */ OCISession *authp_ctl; /* authentication context */ OCIParam *colLstDesc_ctl; /* column list parameter handle */ OCIDirPathCtx *dpctx_ctl; /* direct path context */ OCIDirPathColArray *dpca_ctl; /* direct path column array handle */ OCIDirPathColArray *dpobjca_ctl; /* dp column array handle for obj*/ OCIDirPathColArray *dpnestedobjca_ctl; /* dp col array hndl for nested obj*/ OCIDirPathStream *dpstr_ctl; /* direct path stream handle */ ub1 *buf_ctl; /* pre-alloc'd buffer for out-of-line data */ ub4 bufsz_ctl; /* size of buf_ctl in bytes */ ub4 bufoff_ctl; /* offset into buf_ctl */ ub4 *otor_ctl; /* Offset to Recnum mapping */ ub1 *inbuf_ctl; /* buffer for input records */ struct pctx pctx_ctl; /* partial field context */ boolean loadobjcol_ctl; /* load to obj col(s)? T/F */ };
例20-7 ヘッダー・ファイルcdemodp.hの内容
#ifndef cdemodp_ORACLE # define cdemodp_ORACLE # include <oratypes.h> # ifndef externdef # define externdef # endif /* External column attributes */ struct col { text *name_col; /* column name */ ub2 id_col; /* column load ID */ ub2 exttyp_col; /* external type */ text *datemask_col; /* datemask, if applicable */ ub1 prec_col; /* precision, if applicable */ sb1 scale_col; /* scale, if applicable */ ub2 csid_col; /* character set ID */ ub1 date_col; /* is column a chrdate or date? 1=TRUE. 0=FALSE */ struct obj * obj_col; /* description of object, if applicable */ #define COL_OID 0x1 /* col is an OID */ ub4 flag_col; }; /* Input field descriptor * For this example (and simplicity), * fields are strictly positional. */ struct fld { ub4 begpos_fld; /* 1-based beginning position */ ub4 endpos_fld; /* 1-based ending position */ ub4 maxlen_fld; /* max length for out-of-line field */ ub4 flag_fld; #define FLD_INLINE 0x1 #define FLD_OUTOFLINE 0x2 #define FLD_STRIP_LEAD_BLANK 0x4 #define FLD_STRIP_TRAIL_BLANK 0x8 }; struct obj { text *name_obj; /* type name*/ ub2 ncol_obj; /* number of columns in col_obj*/ struct col *col_obj; /* column attributes*/ struct fld *fld_obj; /* field descriptor*/ ub4 rowoff_obj; /* current row offset in the column array*/ ub4 nrows_obj; /* number of rows in col array*/ OCIDirPathFuncCtx *ctx_obj; /* Function context for this obj column*/ OCIDirPathColArray *ca_obj; /* column array for this obj column*/ ub4 flag_obj; /* type of obj */ #define OBJ_OBJ 0x1 /* obj col */ #define OBJ_OPQ 0x2 /* opaque/sql str col */ #define OBJ_REF 0x4 /* ref col */ }; struct tbl { text *owner_tbl; /* table owner */ text *name_tbl; /* table name */ text *subname_tbl; /* subname, if applicable */ ub2 ncol_tbl; /* number of columns in col_tbl */ text *dfltdatemask_tbl; /* table level default date mask */ struct col *col_tbl; /* column attributes */ struct fld *fld_tbl; /* field descriptor */ ub1 parallel_tbl; /* parallel: 1 for true */ ub1 nolog_tbl; /* no logging: 1 for true */ ub4 xfrsz_tbl; /* transfer buffer size in bytes */ text *objconstr_tbl; /* obj constr/type if loading a derived obj */ }; struct sess /* options for a direct path load session */ { text *username_sess; /* user */ text *password_sess; /* password */ text *inst_sess; /* remote instance name */ text *outfn_sess; /* output filename */ ub4 maxreclen_sess; /* max size of input record in bytes */ }; #endif /* cdemodp_ORACLE */
20.1.5.2 スカラー列に対するダイレクト・パス・ロードの例の概略
OCIダイレクト・パス・インタフェースの使用方法を説明するサンプル・コードを示します。
例20-8は、OCIダイレクト・パス・インタフェースの使用方法の例を示すサンプル・コードです。これは一部省略されたコード例です。
init_load関数は、tblpで記述された表上で、ダイレクト・パスAPIを使用してダイレクト・パス・ロードを実行します。ctlpによって指定されたloadctl構造体の環境およびサービス・コンテキストは、適切に初期化されています。サーバーへの接続は確立されています。
OCI_ATTR_SUB_NAME
、OCI_ATTR_SCHEMA_NAME
など、その他の属性も設定します。属性を設定した後、ロードの準備をします。
OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp, OCIDirPathPrepare(dpctx, ctlp->svchp_ctl, ctlp->errhp_ctl));
列配列とストリーム・ハンドルの割当て
例20-9に示すように、ダイレクト・パス・コンテキスト・ハンドルは、列配列ハンドルおよびストリーム・ハンドルの親ハンドルです。また、エラーは、ダイレクト・パス・コンテキストに関連付けられている環境ハンドルとともに戻されます。
行数と列数の取得
例20-10に示すように、割り当てた列配列から行数および列数を取得します。
入力データ・フィールドの設定
例20-11に示すように、入力データ・フィールドを対応するデータ列に設定します。
列配列の状態のリセット
例20-12に示すように、前の変換を続ける必要がある場合、または行にデータを追加する場合は、列配列の状態をリセットします。
ストリームの状態のリセット
例20-13に示すように、ストリームの状態をリセットして、新しいストリームを開始します。リセットしなかった場合は、ストリーム内のデータが既存のデータの末尾に追加されます。
列配列内のデータのストリーム形式への変換
例20-14に示すように、データの入力後、列配列内のデータをストリーム形式に変換し、不正なレコードを削除します。
ストリームのロード
ストリーム内での位置は、ストリームを作成した列配列のオフセット情報とともに、ストリーム・ハンドルに内部的に保持されます。例20-15に示すように、ストリーム形式への変換が実行されると、ストリームにデータが追加されます。適切な場合にストリームをリセットすることはコール元の責任です。エラーが発生すると、位置は次の行に移動します。エラーが最後の行で発生した場合は、ストリームの最後に移動します。次のOCIDirPathLoadStream()
コールがある場合は、次の行で開始されます。OCIDirPathLoadStream()
コールが実行され、ストリームの最後に達した場合は、OCI_NO_DATA
が戻されます。
ダイレクト・パス・ロードの終了
例20-16に示すように、ダイレクト・パス・ロードを終了します。
ダイレクト・パス・ハンドルの解放
例20-17に示すように、割り当てられているすべてのダイレクト・パス・ハンドルを解放します。親のダイレクト・パス・コンテキスト・ハンドルの解放前に、ダイレクト・パス列配列ハンドルとストリーム・ハンドルが解放されます。
例20-8 OCIダイレクト・パス・インタフェースの使用方法
STATICF void init_load(ctlp, tblp) struct loadctl *ctlp; struct tbl *tblp; { struct col *colp; struct fld *fldp; sword ociret; /* return code from OCI calls */ OCIDirPathCtx *dpctx; /* direct path context */ OCIParam *colDesc; /* column parameter descriptor */ ub1 parmtyp; ub1 *timestamp = (ub1 *)0; ub4 size; ub4 i; ub4 pos; /* allocate and initialize a direct path context */ /* See cdemodp.c for the definition of OCI_CHECK */ OCI_CHECK(ctlp->envhp_ctl, OCI_HTYPE_ENV, ociret, ctlp, OCIHandleAlloc((void *)ctlp->envhp_ctl, (void **)&ctlp->dpctx_ctl, (ub4)OCI_HTYPE_DIRPATH_CTX, (size_t)0, (void **)0)); dpctx = ctlp->dpctx_ctl; /* shorthand */ OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp, OCIAttrSet((void *)dpctx, (ub4)OCI_HTYPE_DIRPATH_CTX, (void *)tblp->name_tbl, (ub4)strlen((const char *)tblp->name_tbl), (ub4)OCI_ATTR_NAME, ctlp->errhp_ctl));
例20-9 列配列とストリーム・ハンドルの割当て
OCI_CHECK(ctlp->envhp_ctl, OCI_HTYPE_ENV, ociret, ctlp, OCIHandleAlloc((void *)ctlp->dpctx_ctl, (void **)&ctlp->dpca_ctl, (ub4)OCI_HTYPE_DIRPATH_COLUMN_ARRAY, (size_t)0, (void **)0)); OCI_CHECK(ctlp->envhp_ctl, OCI_HTYPE_ENV, ociret, ctlp, OCIHandleAlloc((void *)ctlp->dpctx_ctl,(void **)&ctlp->dpstr_ctl, (ub4)OCI_HTYPE_DIRPATH_STREAM, (size_t)0, (void **)0));
例20-10 行数と列数の取得
OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp, OCIAttrGet(ctlp->dpca_ctl, (ub4)OCI_HTYPE_DIRPATH_COLUMN_ARRAY, &ctlp->nrow_ctl, 0, OCI_ATTR_NUM_ROWS, ctlp->errhp_ctl)); OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp, OCIAttrGet(ctlp->dpca_ctl, (ub4)OCI_HTYPE_DIRPATH_COLUMN_ARRAY, &ctlp->ncol_ctl, 0, OCI_ATTR_NUM_COLS, ctlp->errhp_ctl));
例20-11 入力データ・フィールドの設定
ub4 rowoff; /* column array row offset */ ub4 clen; /* column length */ ub1 cflg; /* column state flag */ ub1 *cval; /* column character value */ OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp, OCIDirPathColArrayEntrySet(ctlp->dpca_ctl, ctlp->errhp_ctl, rowoff, colp->id_col, cval, clen, cflg));
例20-12 列配列の状態のリセット
(void) OCIDirPathColArrayReset(ctlp->dpca_ctl, ctlp->errhp_ctl);
例20-13 ストリームの状態のリセット
(void) OCIDirPathStreamReset(ctlp->dpstr_ctl, ctlp->errhp_ctl);
例20-14 データのストリーム形式への変換
ub4 rowcnt; /* number of rows in column array */ ub4 startoff; /* starting row offset into column array */ /* convert array to stream, filter out bad records */ ocierr = OCIDirPathColArrayToStream(ctlp->dpca_ctl, ctlp->dpctx_ctl, ctlp->dpstr_ctl, ctlp->errhp_ctl, rowcnt, startoff);
例20-15 ストリームのロード
/* load the stream */ ociret = OCIDirPathLoadStream(ctlp->dpctx_ctl, ctlp->dpstr_ctl, ctlp->errhp_ctl);
例20-16 ダイレクト・パス・ロード操作の終了
/* finish the direct path load operation */ OCI_CHECK(ctlp->errhp_ctl, OCI_HTYPE_ERROR, ociret, ctlp, OCIDirPathFinish(ctlp->dpctx_ctl, ctlp->errhp_ctl));
例20-17 ダイレクト・パス・ハンドルの解放
/* free up server data structures for the load */ ociret = OCIHandleFree((void *)ctlp->dpca_ctl, OCI_HTYPE_DIRPATH_COLUMN_ARRAY); ociret = OCIHandleFree((void *)ctlp->dpstr_ctl, OCI_HTYPE_DIRPATH_STREAM); ociret = OCIHandleFree((void *)ctlp->dpctx_ctl, OCI_HTYPE_DIRPATH_CTX);
関連項目:
20.1.6 OCIのダイレクト・パス・ロードでの日付キャッシュの使用について
表に格納するためにデータ型変換が必要なOracle日付およびタイムスタンプの値をロードする場合は、日付キャッシュ機能を使用するとパフォーマンスが向上します。
ダイレクト・パス・ロードでのこの機能の使用方法の詳細は、『Oracle Databaseユーティリティ』を参照してください。
この機能は、同じ日付またはタイムスタンプの値が入力値として繰返しロードされるダイレクト・パス・ロードを特に対象としています。日付変換は(特に複数の日付列がロードされる場合)、非常に時間がかかり、ロード時間の中で大きな割合を占める場合があります。入力データに多数の同じ日付値がある場合は、日付キャッシュ機能を使用すると実際に変換される日付の数が減少するため、パフォーマンスが向上します。ただし、日付キャッシュ機能によってパフォーマンスが向上するのは、多数の同じ日付が入力値として日付列にロードされる場合のみです(この章で使用する「日付」という用語は、日付およびタイムスタンプのすべてのデータ型を指します)。
日付キャッシュは、デフォルトで使用可能です。日付キャッシュ・サイズを明示的に指定した場合、デフォルトでは日付キャッシュ機能は使用禁止になりません。この動作をオーバーライドするには、OCI_ATTR_DIRPATH_DCACHE_DISABLE
を1に設定します。この設定以外の場合は、データ変換を回避するためにキャッシュが検索されます。ただし、キャッシュ・ミス(重複した値がないエントリ)は、日付キャッシュ機能の使用による効果がなく、時間がかかる日付変換関数を使用した通常の方法で変換されます。
OCI_ATTR_DIRPATH_DCACHE_NUM
属性、OCI_ATTR_DIRPATH_DCACHE_MISSES
属性およびOCI_ATTR_DIRPATH_DCACHE_HITS
属性を問い合せて、ロードに必要なキャッシュ・サイズを調整します。
キャッシュ・ミスがなく、キャッシュ内の要素数がキャッシュ・サイズより小さい場合は、キャッシュ・サイズを小さくします。多数のキャッシュ・ミスが発生し、相対的にヒット数(重複した値があるエントリ)が少ない場合は、キャッシュ・サイズを大きくすることができます。ただし、多数の日付キャッシュ・ミスが発生すると、アプリケーションの処理速度は日付キャッシュを使用しない場合よりも遅くなる場合があります。キャッシュ・サイズを大きくしすぎると、ページングやメモリー消費量の増加など、別の問題が発生する可能性があります。キャッシュ・サイズを大きくしてもパフォーマンスが向上しない場合、この機能は使用しないでください。
日付キャッシュ機能を明示的かつ全体的に使用禁止にするには、日付キャッシュ・サイズを0 (ゼロ)に設定します。
20.1.6.1 OCI_ATTR_DIRPATH_DCACHE_SIZE
この属性を0 (ゼロ)以外に設定する場合は、表に対する日付キャッシュ・サイズを要素数で設定します。たとえば、日付キャッシュ・サイズを200に設定すると、最大200個の一意の日付またはタイムスタンプ値をキャッシュに格納できます。OCIDirPathPrepare()をコールした後は、日付キャッシュ・サイズを変更できません。デフォルト値は0 (ゼロ)で、これは表に対する日付キャッシュが作成されないことを意味します。日付キャッシュは、データ型変換が必要な1つ以上の日付またはタイムスタンプ値がロードされ、この属性値が0 (ゼロ)以外の場合のみ、表に対して作成されます。
20.1.6.3 OCI_ATTR_DIRPATH_DCACHE_MISSES
この属性を使用して、現在の日付キャッシュ・ミス数を問い合せます。ミスの数が多い場合は、より大きい日付キャッシュ・サイズを使用することを検討してください。日付キャッシュ・サイズを大きくしてもこの数が大幅に減少しない場合は、日付キャッシュ機能を使用しないでください。日付キャッシュ・ミスが発生すると、ハッシングや参照のために時間を費やします。
20.1.6.4 OCI_ATTR_DIRPATH_DCACHE_HITS
この属性を使用して、日付キャッシュ・ヒット数を問い合せます。日付キャッシュ機能の使用による効果があることを確認するには、この数が相対的に多くなる必要があります。
20.1.6.5 OCI_ATTR_DIRPATH_DCACHE_DISABLE
サイズが超過した場合にデータ・キャッシュを使用禁止にするために使用します。
この属性を1に設定すると、サイズを超えた場合に日付キャッシュが使用禁止になります。OCIDirPathPrepare()
をコールした後は、この属性を変更または設定できません。
デフォルト(= 0)では、オーバーフロー時にキャッシュが使用禁止になりません。キャッシュが使用禁止でない場合は、変換を回避するためにキャッシュが検索されますが、入力された日付値のエントリがオーバーフローすると日付キャッシュには追加されず、時間がかかる日付変換関数を使用して変換されます。多数の日付キャッシュ・ミスが発生すると、アプリケーションの処理速度は日付キャッシュを使用しない場合よりも遅くなる場合があります。
この属性を問い合せると、オーバーフローが原因で日付キャッシュが使用禁止になっているかどうかも確認できます。
20.1.7 Oracle NUMBERおよびDATEデータの形式の検証について
ストリーム・データのロード時におけるOracle NUMBERおよびDATEデータの形式の検証について説明します。
ダイレクト・パス・コンテキスト・ハンドルの属性OCI_ATTR_DIRPATH_FLAGS
をOCI_DIRPATH_FLAGS_VLDT
0x01フラグ・セットと組み合せて使用し、サーバーでのストリームの解析時にOracle NUMBER
およびDATE
データの形式を検証します。これは時間のかかる操作であるため、デフォルト値ではこのフラグは設定されません。日付と数値の無効な内部表現を生成するOCIDirPath
に関する問題が疑われる場合、これを使用できます。
詳細は、「ダイレクト・パス・コンテキスト・ハンドル(OCIDirPathCtx)の属性」を参照してください。
20.2 オブジェクト型のダイレクト・パス・ロード
この項では、ダイレクト・パス関数コンテキストによる多様な非スカラー型のロードについて説明します。
非スカラー型は、次のとおりです。
-
ネストした表
-
オブジェクト表(
FINAL
とNOT FINAL
) -
列オブジェクト(
FINAL
とNOT FINAL
) -
REF
列(FINAL
とNOT FINAL
) -
SQL文字列の列
関連項目:
Oracle Databaseのインストールで使用可能なダイレクト・パス・ロードのデモ・プログラムのリストは、表B-1を参照してください。
20.2.1 ネストした表のダイレクト・パス・ロード
ネストした表は、別の表に格納されます。
ダイレクト・パス・ロードAPIを使用して、ネストした表をSETID
という外部キーで、その親の表とは別にロードし、2つの表をリンクします。
注意:
-
現在、
SETID
はシステムで生成されないため、ユーザーによる指定が必要です。 -
親と子の表を別々にロードするときに、子の表に行は挿入されているが、対応する親の行が親の表に挿入されていない場合、孤立した子が作成される可能性があります。また、親の表には親の行が挿入されているが、子の表には子の行が挿入されていない場合、親の行において子が欠落します。
20.2.1.1 ネストした表の列とそのネストした表の記述
ネストした表の列を持つ親表のロード(子であるネストした表のロードとは別のアクション)について説明します。
注意:
スカラー・データのロードと異なるステップは、イタリック表記になっています。
ネストした表の列を持つ親表のロードと、子であるネストした表のロードは、別のアクションです。
-
ネストした表の列を持つ親表をロードする手順は、次のとおりです。
-
親表とその列を通常どおり記述しますが、このとき、次の手順を行います。
-
ネストした表の列を記述するときに、この列にSETIDを格納します。外部データ型は、データ・ファイルのSETIDが文字の場合はSQLT_CHRで、バイナリの場合はSQLT_BINです。
-
-
ネストした表(子)をロードする手順は、次のとおりです。
-
ネストした表とその列を通常どおり記述します。
-
SETID列は必須です。
-
ダミーの名前(setidなど)を使用して、そのOCI_ATTR_NAMEを設定します。これは、APIでは、プログラマがそのシステム名を認識しているとはみなしていないためです。
-
これがSETID列であることを示すように、OCI_ATTR_DIRPATH_SIDで列属性を設定します。
ub1 flg = 1; sword error; error = OCIAttrSet((void *)colDesc, OCI_DTYPE_PARAM, (void *)&flg, (ub4)0, OCI_ATTR_DIRPATH_SID, ctlp->errhp_ctl);
-
-
この項には次のトピックが含まれます。「ネストした表の列とそのネストした表の記述」。
20.2.2 列オブジェクトのダイレクト・パス・ロード
列オブジェクトとは、オブジェクトとして定義される表の列のことです。
現在は、すべての構成属性で構成されるデフォルト・コンストラクタのみがサポートされています。
20.2.2.1 列オブジェクトの記述
列オブジェクトとそのオブジェクト属性を記述するには、ダイレクト・パス関数コンテキストを使用します。
列オブジェクトの記述には、そのオブジェクトのコンストラクタの設定が必要です。オブジェクト属性の記述は、スカラー列のリストの記述に類似しています。
列オブジェクトを記述する手順は、次のとおりです。
注意:
-
ネストした列のオブジェクトがサポートされています。
-
次に説明するステップは、表にロードするスカラー列のリストを記述するステップに類似しています。スカラー・データのロードと異なるステップは、イタリック表記になっています。
-
パラメータ・ハンドルを
OCI_DTYPE_PARAM
で列オブジェクトに割り当てます。このパラメータ・ハンドルを使用して、列の外部属性を設定します。 -
列名とその他の外部列の属性(最大データ・サイズ、精度、スケールなど)を設定します。
-
OCI_ATTR_DATA_TYPEで、外部型をSQLT_NTY (名前付き型)として設定します。
-
ダイレクト・パス関数コンテキスト・ハンドルを割り当てます。このコンテキストを使用して、列のオブジェクト型と属性を記述します。
OCIDirPathFuncCtx *dpfnctx /* direct path function context */; sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (size_t)0, (void **)0);
-
関数コンテキストのOCI_ATTR_NAMEで列のオブジェクト型の名前(Employeeなど)を設定します。
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ text *obj_type; /* column object's object type */ sword error; error = OCIAttrSet((void *)dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (void *)obj_type, (ub4)strlen((const char *)obj_type), OCI_ATTR_NAME, ctlp->errhp_ctl);
-
式の型OCI_ATTR_DIRPATH_EXPR_TYPEをOCI_DIRPATH_EXPR_OBJ_CONSTRに設定します。これは、OCI_ATTR_NAMEを持つ式セットが、デフォルトのオブジェクト・コンストラクタとして使用されることを意味します。
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ ub1 expr_type = OCI_DIRPATH_EXPR_OBJ_CONSTR; sword error; error = OCIAttrSet((void *)dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (void *)&expr_type, (ub4)0, OCI_ATTR_DIRPATH_EXPR_TYPE, ctlp->errhp_ctl);
-
OCI_ATTR_NUM_COLSを使用して、この列オブジェクトにロードする列またはオブジェクト属性の数を設定します。
-
関数コンテキスト
OCIDirPathFuncCtx
の列または属性のパラメータ・リストを取得します。 -
各オブジェクト属性の場合:
-
OCI_DTYPE_PARAM
で、オブジェクト属性の列記述子を取得します。 -
OCI_ATTR_NAME
で属性の列名を設定します。 -
OCI_ATTR_DATA_TYPE
で外部列の型(ダイレクト・パスAPIに渡されるデータの型)を設定します。 -
その他の外部列の属性(最大データ・サイズ、精度、スケールなど)を設定します。
-
この属性の列が列オブジェクトの場合は、そのオブジェクト属性に対してステップ3から10を実行します。
-
列記述子へのハンドルを解放します。
-
-
ステップ4で作成した関数コンテキスト
OCIDirPathFuncCtx
を、親の列オブジェクトのパラメータ・ハンドルにOCI_ATTR_DIRPATH_FN_CTXを使用して設定します。
20.2.2.2 列配列の列オブジェクトへの割当て
列オブジェクトをダイレクト・パス・ロードすると、そのオブジェクトの属性データは、そのオブジェクト専用に作成された個別の列配列にロードされます。
子の列配列は、ネストされているかどうかに関係なく、各列オブジェクトに割り当てられます。子の列配列にあるオブジェクト属性の各行は、その親列配列内の親の列オブジェクトにある対応するNULL以外の行にマップされます。
列オブジェクトのダイレクト・パス関数コンテキスト・ハンドルとOCI_HTYPE_DIRPATH_FN_COL_ARRAY
関数列配列値を使用します。
例20-18は、列オブジェクトに子の列配列を割り当てる方法を示しています。
例20-18 列オブジェクトへの子の列配列の割当て
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ OCIDirPathColArray *dpfnca; /* direct path function column array */ sword error; error = OCIHandleAlloc((void *)dpfnctx, (void **)&dpfnca, OCI_HTYPE_DIRPATH_FN_COL_ARRAY, (size_t)0, (void **)0);
20.2.2.3 列オブジェクト・データの列配列へのロード
列がスカラー列の場合は、その値のアドレスをOCIDirPathColArrayEntrySet()
に渡して、その値を列配列に設定します。
列がオブジェクトの場合は、かわりに、子の列配列ハンドルのアドレスを渡します。子の列配列にはオブジェクトの属性データが格納されます。
データを列オブジェクトにロードする手順は、次のとおりです。
注意:
スカラー・データのロードと異なるステップは、イタリック表記になっています。
(開始。)各列オブジェクトに対して、次の手順を実行します。
-
列がNULL以外の場合:
-
オブジェクト属性の列ごとに、次の操作を行います。
オブジェクト属性がネストされた列オブジェクトの場合は、(開始)に移動し、この全手順を繰り返し実行します。
OCIDirPathColArrayEntrySet()を使用して、子列配列にデータを設定します。
-
子列配列ハンドルのアドレスを
OCIDirPathColArrayEntrySet()
に渡すことにより、列配列で列オブジェクトのデータを設定します。
-
-
列がNULLの場合:
データのNULLアドレス、長さ0 (ゼロ)および
OCI_DIRPATH_COL_NULL
フラグをOCIDirPathColArrayEntrySet()
に渡して、列オブジェクトのデータを列配列に設定します。
20.2.2.4 OCI_DIRPATH_COL_ERROR
OCI_DIRPATH_COL_ERROR
の値をOCIDirPathColArrayEntry()
に渡すことにより、現在の列配列行を無視する必要があることを示します。
一部の列にデータを追加するときにエラーが発生した場合(前のOCIDirPathColArrayToStream()
コールからOCI_NEED_DATA
が戻された場合)は、通常、この値を使用して前のすべての行変換を取り消します。現在の行の出力ストリーム・バッファに格納されている、前に変換されたデータは削除されます。これにより、変換は列配列内の次の行から続行されます。削除された行は、変換された行としてカウントされます。
OCI_DIRPATH_COL_ERROR
を指定すると、現在の行の他、参照される子列配列で対応する任意の行(最上位レベルの列配列行までの行)が無視されます。参照されるすべての子列配列を次の行に移動すると、NULL
子列配列参照は無視されます。
20.2.3 SQL文字列の列のダイレクト・パス・ロード
列の値は、SQL文字列で計算できます。SQL文字列は、スカラー列の型に使用できます。
SQL文字列は、オブジェクト型には使用できませんが、スカラー列の型のオブジェクト属性には使用できます。NESTED TABLE、SEQUENCEおよびLONG
には使用できません。
SQL式は、OCIDirPathFuncCtx
を使用してダイレクト・パスAPIで表現します。式のOCI_ATTR_NAME
の値が、その式の名前付きバインド変数のパラメータ・リストを含むSQL文字列になります。
バインド変数のネームスペースは、列のSQL文字列に限定されています。複数の列に対して同じバインド変数名を使用できますが、同じ名前の引数はその列のSQL文字列に対してのみ適用されます。
列のSQL文字列に1つのバインド変数への複数の参照が含まれており、その名前で複数の引数が指定されている場合は、すべての値を同じにする必要があります。同じにしない場合、結果が未定義になります。この場合、特定のSQL式内の同じバインド変数名への参照がすべて1つの引数にバインドされているため、実際に必要なのは1つの引数のみです。
SQL文字列の例を、次に示します。
substr(substr(:string, :offset, :length), :offset, :length)
この例では、次の点に注意してください。
-
SQL式はネストできます。
-
バインド変数名は、その式内で繰り返し指定できます。
20.2.3.1 SQL文字列の列の記述
SQL文字列の列を記述するためのステップを示します。
注意:
スカラー・データのロードと異なるステップは、イタリック表記になっています。
-
パラメータ・ハンドルを
OCI_DTYPE_PARAM
でSQL文字列の列に割り当てます。このパラメータ・ハンドルを使用して、列の外部属性を設定します。 -
列名とその他の外部列の属性(最大データ・サイズ、精度、スケールなど)を設定します。
-
OCI_ATTR_DATA_TYPEを使用して、SQL文字列の列の外部型をSQLT_NTYとして設定します。
-
ダイレクト・パス関数コンテキスト・ハンドルを割り当てます。このコンテキストを使用して、SQL文字列の引数を記述します。
OCIDirPathFuncCtx *dpfnctx /* direct path function context */; sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (size_t)0, (void **)0);
-
列のSQL文字列を関数コンテキストのOCI_ATTR_NAMEに設定します。
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ text *sql_str; /* column's SQL string expression */ sword error; error = OCIAttrSet((void *)dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (void *)sql_str, (ub4)strlen((const char *)sql_str), OCI_ATTR_NAME, ctlp->errhp_ctl);
-
式の型OCI_ATTR_DIRPATH_EXPR_TYPEをOCI_DIRPATH_EXPR_SQLとして設定します。これは、OCI_ATTR_NAMEを持つ式セットが、値を導出するためのSQL文字列として使用されることを意味します。
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ ub1 expr_type = OCI_DIRPATH_EXPR_SQL; sword error; error = OCIAttrSet((void *)dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (void *)&expr_type, (ub4)0, OCI_ATTR_DIRPATH_EXPR_TYPE, ctlp->errhp_ctl);
-
SQL文字列に渡す引数の数をOCI_ATTR_NUM_COLSを使用して設定します。
-
関数コンテキストの列または属性のパラメータ・リストを取得します。
-
SQL文字列の引数ごとに、次の操作を行います。
-
OCI_DTYPE_PARAM
で、オブジェクト属性の列記述子を取得します。 -
SQL文字列の引数の定義順序は重要ではありません。SQL文字列で使用されている順序と一致させる必要はありません。
-
OCI_ATTR_NAME
で属性の列名を設定します。 -
SQL文字列の引数には、ネーミング規則が適用されます。
-
引数名は、SQL文字列で使用されているバインド変数名と内容が一致している必要がありますが、大/小文字区別を一致させる必要はありません。たとえば、SQL文字列がsubstr(:INPUT_STRING, 3, 5)の場合は、引数名をinput_stringにしてもかまいません。
-
1つの引数をSQL文字列内で繰り返し使用する場合は、宣言は1回のみ実施し、1つの引数としてのみカウントしてください。
-
OCI_ATTR_DATA_TYPE
で外部列の型(ダイレクト・パスAPIに渡されるデータの型)を設定します。 -
その他の外部列の属性(最大データ・サイズ、精度、スケールなど)を設定します。
-
列記述子へのハンドルを解放します。
-
-
ステップ4で作成した関数コンテキスト
OCIDirPathFuncCtx
を、親の列オブジェクトのパラメータ・ハンドルにOCI_ATTR_DIRPATH_FN_CTXを使用して設定します。
20.2.3.2 列配列のSQL文字列の列への割当て
SQL文字列の列をダイレクト・パス・ロードすると、その引数のデータは、そのSQL文字列の列専用に作成された個別の列配列にロードされます。
子の列配列は、SQL文字列の列ごとに割り当てられます。子の列配列にある引数の各行は、その親列配列内の親のSQL文字列の列にある対応するNULL以外の行にマップされます。
例20-19は、SQL文字列の列に子の列配列を割り当てる方法を示しています。
例20-19 SQL文字列の列への子の列配列の割当て
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ OCIDirPathColArray *dpfnca; /* direct path function column array */ sword error; error = OCIHandleAlloc((void *)dpfnctx, (void **)&dpfnca, OCI_HTYPE_DIRPATH_FN_COL_ARRAY, (size_t)0, (void **)0);
20.2.3.3 SQL文字列データの列配列へのロード
列がスカラー列の場合は、その値のアドレスをOCIDirPathColArrayEntrySet()
に渡して、その値を列配列に設定します。
列がSQL文字列型の場合は、かわりに、子の列配列ハンドルのアドレスを渡します。子の列配列には、SQL文字列の引数データが格納されます。
データをSQL文字列の列にロードする手順は、次のとおりです。
注意:
スカラー・データのロードと異なるステップは、イタリック表記になっています。
SQL文字列の列ごとに、次の操作を行います。
-
列がNULL以外の場合:
-
関数の引数の列ごとに、次の操作を行います。
OCIDirPathColArrayEntrySet()を使用して、子列配列にデータを設定します。
-
子列配列ハンドルのアドレスをOCIDirPathColArrayEntrySet()に渡すことにより、SQL文字列の列データを列配列に設定します。
-
-
列がNULLの場合:
データのNULLアドレス、長さ0 (ゼロ)および
OCI_DIRPATH_COL_NULL
フラグをOCIDirPathColArrayEntrySet()
に渡して、SQL文字列の列データを列配列に設定します。
この処理は、列オブジェクトの処理に類似しています。
関連項目:
-
OCI_DIRPATH_COL_ERROR
の値をOCIDirPathColArrayEntry()
に渡して、エラー発生時に現在の列配列行を無視する必要があることを示す方法の詳細は、「OCI_DIRPATH_COL_ERROR」を参照してください
20.2.4 REF列のダイレクト・パス・ロード
REF
型とは、オブジェクト表の行オブジェクトへのポインタ、つまり参照です。
20.2.4.1 REF列の記述
REF
列への引数の記述は、表にロードする列リストの記述に類似しています。
注意:
REF
列は、表のトップレベル列に設定したり、オブジェクト属性として列オブジェクトにネストできます。
スカラー・データのロードと異なるステップは、イタリック表記になっています。
-
OCI_DTYPE_PARAM
で、REF
列のパラメータ・ハンドルを取得します。このパラメータ・ハンドルを使用して、列の外部属性を設定します。 -
列名とその他の外部列の属性(最大データ・サイズ、精度、スケールなど)を設定します。
-
OCI_ATTR_DATA_TYPEを使用して、REF列の外部型をSQLT_REFとして設定します。
-
ダイレクト・パス関数コンテキスト・ハンドルを割り当てます。このコンテキストを使用して、REF列の引数を記述します。
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (size_t)0, (void **)0);
-
オプション: REF列の表名を関数コンテキストのOCI_ATTR_NAMEに設定します。詳細は、次のステップを参照してください。
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ text *ref_tbl; /* column's reference table */ sword error; error = OCIAttrSet((void *)dpfnctx, OCI_HTYPE_DIRPATH_FN_CTX, (void *)ref_tbl, (ub4)strlen((const char *)ref_tbl), OCI_ATTR_NAME, ctlp->errhp_ctl);
-
オプション: 式の型OCI_ATTR_DIRPATH_EXPR_TYPEをOCI_DIRPATH_EXPR_REF_TBLNAMEに設定します。この設定は、ステップ5が完了している場合にのみ実行します。これは、OCI_ATTR_NAMEを持つ式セットが、行オブジェクトを参照するためのオブジェクト表として使用されることを意味します。このパラメータはオプションです。このパラメータの動作は、REFの型によって異なります。
-
有効範囲なしのREF列(有効範囲なし、システムOIDベース)
このパラメータが設定されていない場合、このREF列には、有効範囲なしのREF列の定義により、参照表の名前が引数としてデータ行ごとに含まれている必要があります。
パラメータが設定されている場合、このREF列がロードの継続時間中に参照できるのは、指定されたオブジェクト表の行オブジェクトのみです。このREF列に、参照表の名前を引数として含めることはできません。(ダイレクト・パスAPIは、このパラメータをショート・カットとしてユーザーに提供しています。ユーザーは、このパラメータをロードの継続時間中に同じ参照オブジェクト表を参照する有効範囲なしのREF列にロードします)。
-
有効範囲付REF列(有効範囲付、システムOIDベースおよび主キー・ベース)
このパラメータが設定されていない場合、ダイレクト・パスAPIは、スキーマで指定されている参照表を使用します。
設定されている場合、参照表の名前は、この有効範囲付REF列のスキーマに指定されているオブジェクト表と一致している必要があります。表名が一致していない場合は、エラーが発生します。
このパラメータが設定されているかどうかに関係なく、この参照表の名前がデータ行に存在しているかどうかはAPIにとって問題ではありません。名前がデータ行にある場合、その名前はスキーマに指定されている表名と一致している必要があります。名前がデータ行にない場合、APIはスキーマに指定されている参照表を使用します。
-
-
行オブジェクトの参照に使用するREF引数の数を、OCI_ATTR_NUM_COLSで設定します。必要な引数の数は、REF列の型によって異なります。この数は、前述のステップ6で導出されます。
-
有効範囲なしのREF列(有効範囲なし、システムOIDベースのREF列)
OCI_DIRPATH_EXPR_REF_TBLNAMEが使用されている場合は、1つの引数が導出されます。参照表の名前の引数はなく、OID値の引数が1つです。
OCI_DIRPATH_EXPR_REF_TBLNAMEが使用されていない場合は、2つです。参照表の名前の引数が1つとOID値の引数が1つです。
-
有効範囲付REF列(有効範囲付、システムOIDベースおよび主キー・ベース)
OCI_DIRPATH_EXPR_REF_TBLNAMEを使用しているかどうかにかかわらず、オブジェクトIDを構成している列数がNの場合、受入れ可能な数はNまたはN+1です。参照表の名前がデータ行にない場合、最小値はNです。参照表の名前がデータ行にある場合、その最小値はN+1です。注意: REFがシステムOIDベースの場合、Nは1になります。REFが主キー・ベースの場合、Nは主キーを構成するコンポーネント列の数になります。参照表の名前がデータ行にある場合は、Nに1を加算します。
注意:
NまたはN+1以外のある数の
REF
引数で渡された場合のエラー・メッセージを簡単化するには、Nを予期している際に何らかの数の引数が検出されたことだけを示すエラー・メッセージにします。メッセージではN+1について記述されていませんが、N+1は受入れ可能である(参照表名が必要ない場合でも)ため、エラー・メッセージは表示されません。
-
-
関数コンテキストの列または属性のパラメータ・リストを取得します。
-
REFの引数または属性ごとに、次の操作を行います。
-
OCI_DTYPE_PARAM
で、REF
引数の列記述子を取得します。 -
OCI_ATTR_NAME
で属性の列名を設定します。REF引数の順序は重要です。参照表の名前が指定されている場合は、その名前を最初のREF引数に指定します。オブジェクトIDは、システム生成または主キー・ベースに関係なく、次のREF引数に指定します。
REF引数には次のネーミング規則が適用されます。参照表の名前は表の列ではないため、列名にref-tblなどのダミーの名前を使用できます。システム生成のOID列に対しては、列名にsys-OIDなどのダミーの名前を使用できます。主キー・ベースのオブジェクトIDに対しては、ロード対象のすべての主キー列をリストします。OIDに対してダミーの名前を作成する必要はありません。コンポーネント列名は、指定されている場合(次のショートカットの注意を参照)、任意の順序で指定できます。
ショートカットを使用する場合は、オブジェクトIDに属性列名を設定しないでください。
ショートカット。 - システムOIDベースのREF列をロードする場合は、列名に名前を設定しないでください。名前はAPIによって判断されます。ただし、外部データ型などの他の列属性は、プログラマが設定する必要があります。
主キーREF列をロードしており、その主キーが複数の列で構成されている場合、ショートカットはそれぞれの列名に設定されません。ただし、外部データ型などの他の列属性は、プログラマが設定する必要があります。
注意:
コンポーネント列名がNULLの場合は、APIコードによって、主キーに定義された位置または順序で列名が決定されます。したがって、名前以外の列属性を設定する場合は、その属性がコンポーネントの列に適切な順序で設定されていることを確認してください。
-
OCI_ATTR_DATA_TYPE
を使用して外部列の型(ダイレクト・パスAPIに渡されるデータの型)を設定します。 -
その他の外部列の属性(最大データ・サイズ、精度、スケールなど)を設定します。
-
列記述子へのハンドルを解放します。
-
ステップ4で作成された関数コンテキスト
OCIDirPathFuncCtx
を、OCI_ATTR_DIRPATH_FN_CTXを使用して親の列オブジェクトのパラメータ・ハンドルに設定します。
-
20.2.4.2 列配列のREF列への割当て
REF
列に子の列配列を割り当てる方法を示します。
例20-20は、REF
列に子の列配列を割り当てる方法を示しています。
例20-20 REF列への子の列配列の割当て
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ OCIDirPathColArray *dpfnca; /* direct path function column array */ sword error; error = OCIHandleAlloc((void *)dpfnctx, (void **)&dpfnca, OCI_HTYPE_DIRPATH_FN_COL_ARRAY, (size_t)0, (void **)0);
20.2.4.3 REFデータの列配列へのロード
列がスカラー列の場合は、その値のアドレスをOCIDirPathColArrayEntrySet()
に渡して、その値を列配列に設定します。
列がREF
の場合は、かわりに、子の列配列ハンドルのアドレスを渡します。子の列配列には、REF
の引数のデータが格納されます。
データをREF
列にロードする手順は、次のとおりです。
注意:
スカラー・データのロードと異なるステップは、イタリック表記になっています。
REF列ごとに、次の操作を行います。
-
列がNULL以外の場合:
-
REF引数の列ごとに、次の操作を行います。
OCIDirPathColArrayEntrySet()を使用して、子列配列にデータを設定します。
-
子列配列ハンドルのアドレスをOCIDirPathColArrayEntrySet()に渡すことにより、REF列のデータを列配列に設定します。
-
-
列がNULLの場合:
データのNULLアドレス、長さ0 (ゼロ)および
OCI_DIRPATH_COL_NULL
フラグをOCIDirPathColArrayEntrySet()
に渡して、REF
列のデータを列配列に設定します。
20.2.5 NOT FINALオブジェクトおよびREF列のダイレクト・パス・ロード
SQLオブジェクトの継承は型の階層を形成するオブジェクト型のファミリ・ツリーに基づいていることに注意してください。
型の階層は、スーパータイプという親オブジェクト型と、親から導出された、サブタイプという1つ以上のレベルの子オブジェクト型で構成されます。
20.2.5.1 継承階層
継承可能にするオブジェクト型に対して、オブジェクト型定義では、それが継承可能であることを指定する必要があることに注意してください。
図20-2は、Person
型の列の継承階層を示しています。Person
スーパータイプは、Name
とAddress
の2つの属性を持ち、階層の最上位にあります。Person
には、Employee
とStudent
の2つのサブタイプがあります。Employee
サブタイプには、Manager
とDeptid
の2つの属性があります。Student
サブタイプには、Units
とGPA
の2つの属性があります。ParttimeEmployee
は、Employee
のサブタイプで、これの下に表示されます。サブタイプParttimeEmployee
には、1つの属性Hours
があります。これらは、Person
列に格納できる型です。
指定すると、そこからサブタイプを導出できます。継承可能にするオブジェクトを指定するには、型定義にキーワードNOT FINAL
を指定する必要があります。継承可能にしないオブジェクトを指定するには、型定義にキーワードFINALを指定する必要があります。
Person
型の列を含む表をダイレクト・パス・ロードする場合、実際の型セットには、NOT FINAL
型Person
とその3つのサブタイプであるStudent
、Employee
およびParttimeEmployee
を含めることができます。このロードの継続時間中、ダイレクト・パス・ロードAPIがサポートするのは、このNOT FINAL
列の固定的な派生型のロードのみであるため、ダイレクト・パス・ロードAPIでは、ロード対象となる型、その型に対してロードする属性およびその型の作成に使用する関数などを認識する必要があります。
そのため、派生型を記述およびロードするときは、ロード対象となるその型の全属性を指定する必要があります。サブタイプは、この型とその親の全属性に固有なすべてのオブジェクト属性のフラット表現とみなしてください。したがって、ロード対象の属性列すべてを記述してカウントする必要があります。
たとえば、ParttimeEmployee
のすべての列をロードするには、ロード対象となるName
、Address
、Manager
、Deptid
およびHours
の5つのオブジェクト属性を記述してカウントする必要があります。
関連項目:
FINAL
型およびNOT FINAL
型の定義の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。
20.2.5.2 ロード対象の固定的な派生型の記述について
NOT FINAL
または置換可能オブジェクト列と固定的な派生型のREF
列を記述するステップは、同じ型のFINAL
列を記述するステップと類似していることに注意してください。
次の各項で、この型のFINAL
列について説明します。派生型(スーパータイプまたはサブタイプの場合があります)は、ロードの継続時間中固定されているため、NOT FINAL
列を記述するためのクライアント側インタフェースは、FINAL
列を記述する場合と同じです。
サブタイプは、この型とその親の全属性に固有なすべてのオブジェクト属性のフラット表現とみなすことができます。したがって、ロード対象の属性列すべてを記述してカウントする必要があります。
関連項目:
X型(XはオブジェクトまたはREF
)のNOT FINAL
列を記述する方法の詳細は、「列オブジェクトのダイレクト・パス・ロード」または「REF列のダイレクト・パス・ロード」を参照してください
20.2.6 オブジェクト表のダイレクト・パス・ロード
オブジェクト表とは、すべての行がオブジェクト(つまり、行オブジェクト)である表です。表の各列は、オブジェクト属性です。
オブジェクト表の記述
オブジェクト表の記述は、非オブジェクト表の記述と非常に類似しています。各オブジェクト属性が表の列です。唯一の相違点は、OIDがシステム生成、ユーザー生成または主キー・ベースの場合に、そのOIDの記述が必要になることです。
オブジェクト表を記述する手順は、次のとおりです。
注意:
非オブジェクト表のロードと異なるステップは、イタリック表記になっています。
オブジェクト属性列ごとに、次の操作を行います。
それぞれの型(NUMBER
、REF
など)に基づいて、各オブジェクト属性の列を必要に応じて記述します。
オブジェクト表がOID (Oracle Internet Directory)の場合は、次の操作を行います。
-
オブジェクトIDがシステム生成の場合。
何もする必要はありません。システムがすべての行オブジェクトのOIDを生成します。
-
オブジェクトIDがユーザー生成の場合。
-
仮の名前(cust_oidなど)を使用してOIDの列名を表現します。
-
OCI_ATTR_DIRPATH_OIDでOIDの列属性を設定します。
-
-
オブジェクトIDが主キー・ベースの場合。
-
OIDを構成しているすべての主キー列をロードします。
-
OCI_ATTR_DIRPATH_OIDを設定しないでください。ダミーの名前を持つOID列は作成されていません。
-
列配列のオブジェクト表への割当て
例20-21は、列配列のオブジェクト表への割当ては、非オブジェクト表に列配列を割り当てる方法と同じであることを示しています。
データの列配列へのロード
列配列へのデータのロードは、非オブジェクト表にデータをロードする方法と同じです。
例20-21 列配列のオブジェクト表への割当て
OCIDirPathColArray *dpca; /* direct path column array */ sword error; error = OCIHandleAlloc((void *)dpctx, (void **)&dpca, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, (size_t)0, (void **)0);
20.2.7 NOT FINALオブジェクト表のダイレクト・パス・ロード
NOT FINAL
オブジェクト表は継承をサポートしますが、FINAL
オブジェクト表は継承をサポートできません。
NOT FINALオブジェクト表の記述
固定的な派生型のNOT FINAL
オブジェクト表の記述は、FINAL
オブジェクト表の記述と非常に類似しています。
固定的な派生型のNOT FINAL
オブジェクト表を記述する手順は、次のとおりです。
注意:
FINAL
オブジェクト表の記述と異なるステップは、イタリック表記になっています。
-
OCI_ATTR_DIRPATH_OBJ_CONSTRを使用して、ダイレクト・パス・コンテキストにオブジェクト表のオブジェクト型を設定します。これは、スーパータイプまたは派生型に関係なく、ロードの継続時間中、この表へのロードにはオブジェクト型がデフォルトのオブジェクト・コンストラクタとして使用されることを意味します。
text *obj_type; /* the object type to load into this NOT FINAL */ /* object table */ sword error; error = OCIAttrSet((void *)dpctx, OCI_HTYPE_DIRPATH_CTX, (void *) obj_type, (ub4)strlen((const char *) obj_type), OCI_ATTR_DIRPATH_OBJ_CONSTR, ctlp->errhp_ctl);
-
ロードする各オブジェクト属性列のデータ型に従って記述します。必要に応じて、オブジェクトIDを記述します。これは、
FINAL
オブジェクト表を記述する方法と同じです。
列配列のNOT FINALオブジェクト表への割当て
NOT FINAL
オブジェクト表の列配列の割当ては、FINAL
オブジェクト表の場合と同じです。
20.3 ピース単位のダイレクト・パス・ロード
一度にメモリー内に格納できないデータのロードをサポートするために、ピース単位のロードを使用します。
ダイレクト・パスAPIでは、LONG
とLOBの段階的なロードがサポートされています。これには、次のステップを順に実行します。
- 最初のピースを
OCIDirPathColArrayEntrySet()
を使用して列配列に設定し、OCI_DIRPATH_COL_PARTIAL
フラグに渡して、この列の全データのロードが完了していないことを示します。 - 列配列をストリームに変換します。
- ストリームをロードします。
- そのデータの次のピースを列配列に設定します。このピースが未完了の場合は、パーシャル・フラグを設定してステップ2に戻ります。完了している場合は、
OCI_DIRPATH_COL_COMPLETE
フラグを設定して次の列へ続行します。
このアプローチは、本質的には列オブジェクトの大規模な属性やSQL文字列型の大規模な引数を扱う方法と同じです。
注意:
コレクションは、このようにピース単位でロードしません。NESTED TABLEは、トップレベル表と同じように、個別にロードします。NESTED TABLEは段階的にロードでき、またピース単位でロードされた列を含めることができます。したがって、コレクションを格納している列には、OCI_DIRPATH_COL_PARTIAL
フラグを設定しないでください。
この項には次のトピックが含まれます。「オブジェクト型のピース単位のロード」。
関連項目:
-
OCI_DIRPATH_COL_ERROR
の値をOCIDirPathColArrayEntry()
に渡して、エラー発生時に現在の列配列行を無視する必要があることを示す方法の詳細は、「OCI_DIRPATH_COL_ERROR」を参照してください
20.3.1 オブジェクト型のピース単位のロード
オブジェクトは、そのオブジェクトが格納されている親の表から個別の列配列にロードします。
したがって、オブジェクトをピース単位でロードする必要がある場合は、子の列配列に要素を設定して、ピース化された要素を含める必要があります。
一般的なステップは次のとおりです。
- ピース化された要素に、
OCI_DIRPATH_COL_PARTIAL
フラグを設定します。 - 子の列配列ハンドルを親の列配列に設定し、そのエントリも
OCI_DIRPATH_COL_PARTIAL
フラグでマークします。 - 親の列配列をストリームに変換します。この結果、子の列配列もストリームに変換されます。
- ストリームをロードします。
- ステップ1に戻り、その要素に対する残りのデータのロードを、完了するまで続行します。
ピース単位のロードには、いくつかのルールがあります。
-
パーシャル要素は、任意のレベルで一度に1つしか存在できません。1つのパーシャル要素が完了とマークされた後は、そのレベルの別の要素をパーシャル要素に設定できます。
-
要素がパーシャルで、かつトップレベルでない場合は、制御階層上のその要素のすべての親にもパーシャルのマークを付ける必要があります。
-
ネスト・レベルが複数の場合は、対象データをストリームに変換できるレベルまで移動する必要があります。これがトップレベル表になります。
関連項目:
OCI_DIRPATH_COL_ERROR
の値をOCIDirPathColArrayEntry()
に渡して、エラー発生時に現在の列配列行を無視する必要があることを示す方法の詳細は、「OCI_DIRPATH_COL_ERROR」を参照してください。
20.4 ダイレクト・パス・コンテキスト・ハンドルとオブジェクト型の属性
20.4.1 ダイレクト・パス・コンテキストの属性
1つのダイレクト・パス・コンテキストの属性があります。
関連項目:
OCI_ATTR_DIRPATH_OBJ_CONSTRは、唯一のダイレクト・パス・コンテキストの属性です
20.4.1.1 OCI_ATTR_DIRPATH_OBJ_CONSTR
オブジェクト型がNOT FINAL
オブジェクト表にロードされることを示します。
ttext *obj_type; /* the object type to load into this NOT FINAL */ /* object table */ sword error; error = OCIAttrSet((void *)dpctx, OCI_HTYPE_DIRPATH_CTX, (void *) obj_type, (ub4)strlen((const char *) obj_type), OCI_ATTR_DIRPATH_OBJ_CONSTR, ctlp->errhp_ctl);
20.4.2 ダイレクト・パス関数コンテキストと属性
関数コンテキスト・ハンドルの属性の概要を、次に示します。
20.4.2.1 OCI_ATTR_DIRPATH_OBJ_CONSTR
オブジェクト型が置換可能なオブジェクト表にロードされることを示します。
text *obj_type; /* stores an object type name */ sword error; error = OCIAttrSet((void *)dpctx, OCI_HTYPE_DIRPATH_CTX, (void *) obj_type, (ub4)strlen((const char *) obj_type), OCI_ATTR_DIRPATH_OBJ_CONSTR, ctlp->errhp_ctl);
20.4.2.2 OCI_ATTR_NAME
関数コンテキストの作成時に、非スカラー列を記述する式に相当するOCI_ATTR_NAME
を設定します。
次に、式の型を示すOCI属性を設定します。式の型は、それが列オブジェクト、REF
列またはSQL文字列の列であるかに応じて異なります。
列オブジェクト
必要な式は、オブジェクト型名です。オブジェクト型はデフォルトのオブジェクト・コンストラクタとして使用されます。
式の型OCI_ATTR_DIRPATH_EXPR_TYPE
をOCI_DIRPATH_EXPR_OBJ_CONSTR
に設定し、この式がオブジェクト型名であることを示します。
REF列
このオプションの式は、参照表名です。この表は、REF
列が行オブジェクトを参照する参照元のオブジェクト表です。
式の型OCI_ATTR_DIRPATH_EXPR_TYPE
をOCI_DIRPATH_EXPR_REF_TBLNAME
に設定し、この式が参照オブジェクト表であることを示します。
このパラメータの動作は、設定の有無に関係なく、REF
の型によって異なります。
-
有効範囲なしの
REF
列(有効範囲なし、システムOIDベース)-
このパラメータが設定されていない場合、この
REF
列には、有効範囲なしのREF
列の定義により、参照表の名前が引数としてデータ行ごとに含まれている必要があります。 -
パラメータが設定されている場合、この
REF
列がロードの継続時間中に参照できるのは、指定されたオブジェクト表の行オブジェクトのみです。このREF
列に、参照表の名前を引数として含めることはできません。(ダイレクト・パスAPIは、このパラメータをショートカットとしてユーザーに提供しています。ユーザーは、このパラメータをロードの継続時間中に同じ参照オブジェクト表を参照する有効範囲なしのREF
列にロードします)。
-
-
有効範囲付
REF
列(有効範囲付、システムOIDベースおよび主キー・ベース)-
このパラメータが設定されていない場合、ダイレクト・パスAPIは、スキーマで指定されている参照表を使用します。
-
このパラメータが設定されている場合、参照表の名前は、この有効範囲付
REF
列のスキーマに指定されているオブジェクト表と一致している必要があります。表名が一致していない場合は、エラーが発生します。 -
このパラメータが設定されているかどうかに関係なく、この参照表の名前がデータ行に存在しているかどうかはAPIにとって問題ではありません。名前がデータ行にある場合、その名前はスキーマに指定されている表名と一致している必要があります。名前がデータ行にない場合、APIはスキーマに定義されている参照表を使用します。
-
SQL文字列の列
この必須式には、列に格納される値を導出するSQL文字列が含まれています。
式の型OCI_ATTR_DIRPATH_EXPR_TYPE
をOCI_DIRPATH_EXPR_SQL
に設定し、この式がSQL文字列であることを示します。
20.4.2.3 OCI_ATTR_DIRPATH_EXPR_TYPE
この属性を使用して、非スカラー列の関数コンテキストに対して、OCI_ATTR_NAME
で指定した式の型を示します。
OCI_ATTR_NAME
が設定されている場合、OCI_ATTR_DIRPATH_EXPR_TYPE
は必須です。
OCI_ATTR_DIRPATH_EXPR_TYPE
に使用可能な値は、次のとおりです。
-
OCI_DIRPATH_EXPR_OBJ_CONSTR
-
式がオブジェクト型名であること、この式が列オブジェクトに対するデフォルトのオブジェクト・コンストラクタとして使用されることを示します。
-
列オブジェクトには必須です。
-
-
OCI_DIRPATH_EXPR_REF_TBLNAME
-
式が参照オブジェクト表の名前であることを示します。この表は、
REF
列が行オブジェクトを参照する参照元のオブジェクト表です。 -
REF
列の場合は、オプションです。
-
-
OCI_DIRPATH_EXPR_SQL
-
式は列に格納されている値を導出するために実行されるSQL文字列であることを示します。
-
SQL文字列の列の場合は、必須です。
-
例20-22は、前述のルールおよび値を例示した疑似コードを示しています。
例20-22 OCI_ATTR_DIRPATH_EXPR_TYPE属性への値の指定
OCIDirPathFuncCtx *dpfnctx; /* function context for this nonscalar column */ ub1 expr_type; /* expression type */ sword error; if (...) /* (column type is an object) */ expr_type = OCI_DIRPATH_EXPR_OBJ_CONSTR; ... if (...) /* (column type is a REF && function context name exists) */ expr_type = OCI_DIRPATH_EXPR_REF_TBLNAME; ... if (...) /* (column type is a SQL string) */ expr_type = OCI_DIRPATH_EXPR_SQL; ... error = OCIAttrSet((void *)(dpfnctx), OCI_HTYPE_DIRPATH_FN_CTX, (void *)&expr_type, (ub4)0, OCI_ATTR_DIRPATH_EXPR_TYPE, ctlp->errhp_ctl);
20.4.2.4 OCI_ATTR_DIRPATH_NO_INDEX_ERRORS
OCI_ATTR_DIRPATH_NO_INDEX_ERRORS
が1である場合、索引はロード中のどの時点でも使用不可に設定されません。
索引エラーが検出された場合、ロードは終了します。つまり、行はロードされず、索引はそのままとなります。デフォルトは0 (ゼロ)です。
20.4.2.5 OCI_ATTR_NUM_COLS
この属性は、非スカラー列用にロードまたは処理する属性や引数の数を記述します。
このパラメータは、列リストが取り出される前に設定する必要があります。式の型は、それが列オブジェクト、SQL文字列の列またはREF
列であるかに応じて異なります。
列オブジェクト
この列オブジェクト用にロードするオブジェクト属性列の数。
SQL文字列の列
SQL文字列に渡す引数の数。
引数が関数内で繰り返して使用される場合も、1つとしてカウントしてください。
REF列
REF
列が指し示す必要のある行オブジェクトを識別するREF
引数の数。
必要な引数の数は、REF
列の型によって異なります。
-
有効範囲なしの
REF
列(有効範囲なし、システムOIDベースのREF
列)-
OCI_DIRPATH_EXPR_REF_TBLNAME
を使用している場合。参照表の名前の引数はなく、OID値の引数が1つです。(OID値のみがデータ行にある。) -
OCI_DIRPATH_EXPR_REF_TBLNAME
を使用していない場合。参照表の名前の引数が1つとOID値の引数が1つです。(参照表名とOID値の両方がデータ行にある。)
-
-
有効範囲付
REF
列(有効範囲付、システムOIDベースおよび主キー・ベース)-
OCI_DIRPATH_EXPR_REF_TBLNAME
を使用しているかどうかにかかわらず、オブジェクトIDを構成している列数がNの場合、受入れ可能な数はNまたはN+1です。参照表の名前がデータ行にない場合、最小値はNです。参照表の名前がデータ行にある場合は、N+1を使用します。 -
REF
がシステムOIDベースの場合、Nは1になります。REF
が主キー・ベースの場合、Nは主キーを構成するコンポーネント列の数になります。参照表の名前がデータ行にある場合は、Nに1を加算します。
注意:
NまたはN+1以外のある数の
REF
引数で渡された場合のエラー・メッセージを簡単化するには、Nを予期している際に何らかの数の引数が検出されたことだけを示すエラー・メッセージにします。メッセージではN+1について記述されていませんが、N+1は受入れ可能である(参照表名が必要ない場合でも)ため、エラー・メッセージは表示されません。 -
20.4.2.6 OCI_ATTR_NUM_ROWS
OCI_HTYPE_DIRPATH_FN_CTX
(関数コンテキスト)に対して使用される場合、この属性は、取出し専用のため、ユーザーによる設定はできません。
この属性は、OCIAttrGet()
にのみ使用でき、OCIAttrSet()
には使用できません。OCIAttrGet()
をOCI_ATTR_NUM_ROWS使用してコールすると、それまでにロードされた行数が戻されます。
ただし、属性OCI_ATTR_NUM_ROWS
は、OCI_HTYPE_DIRPATH_CTX
(表レベルのコンテキスト)に対して使用する場合は、設定およびユーザーによる取出しの両方が可能です。
OCIAttrSet()
をOCI_ATTR_NUM_ROWS
とOCI_HTYPE_DIRPATH_CTX
を使用してコールすると、表レベルの列配列に割り当てる行数が設定されます。設定されない場合、ダイレクト・パスAPIコードは、レコード最大サイズと転送バッファのサイズに基づいて適切な数を導出します。割り当てた行数を確認するには、表レベルの列配列については、OCI_ATTR_NUM_ROWS
をOCI_HTYPE_DIRPATH_COLUMN_ARRAY
で使用し、関数列配列については、OCI_HTYPE_DIRPATH_FN_COL_ARRAY
を使用して、OCIAttrGet()
をコールします。
OCIAttrGet()
をOCI_ATTR_NUM_ROWS
とOCI_HTYPE_DIRPATH_CTX
でコールすると、それまでにロードされた行数が戻されます。
この属性は、関数コンテキストではユーザーは設定できません。OCI_ATTR_NUM_ROWS
とOCIAttrSet()
により、関数列配列内で必要な行数を指定することはできません。これは、すべての関数列配列が、表レベルの列配列と同じ行数を持っているためです。この属性は、表レベルのコンテキストでのみ設定することができ、関数コンテキストでは設定できません。
関連項目:
20.4.3 ダイレクト・パス列パラメータ属性
オブジェクト、SQL文字列またはREF
列を記述すると、その列属性の1つが関数コンテキストになります。
列がオブジェクトの場合、その関数コンテキストには、そのオブジェクト型とオブジェクト属性が記述されます。列がSQL文字列の場合、関数コンテキストは、コール対象の式を記述します。列がREFの場合、関数コンテキストは、参照表の名前と行オブジェクトの識別子を記述します。
例20-23は、関数コンテキストを列属性として設定し、OCI_ATTR_DIRPATH_FN_CTX
をOCIAttrSet()
コールで使用することを示しています。
列パラメータ・コンテキスト・ハンドルの属性について次に説明します。
例20-23 列属性としての関数コンテキストの設定
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ sword error; error = OCIAttrSet((void *)colDesc, OCI_DTYPE_PARAM, (void *)(dpfnctx), (ub4)0, OCI_ATTR_DIRPATH_FN_CTX, ctlp->errhp_ctl);
関連項目:
20.4.3.1 OCI_ATTR_NAME
次に、ネストした表、オブジェクト表、SQL文字列の列およびREF
列をロードするためのネーミング規則について説明します。
通常、オブジェクト表のシステム生成オブジェクトID (OID
)列やネストした表のSETID
(SID
)列など、プログラマにとって不明なシステム名を持つシステム列にデータをロードする場合、あるいは列がデータベース表の列を持たない引数(SQL文字列やREF
引数など)である場合は、ダミーの名前を使用します。
列はデータベース表の列であっても、ダミーの名前を使用した場合は、その列がデータベースで識別されない名前の場合でも関数が識別できるように、列属性を設定する必要があります。
ネーミング規則は、次のとおりです。
-
子のネストした表の
SETID
(SID
)列SETID列は必須です。ダミーの名前を使用して、その
OCI_ATTR_NAME
を設定します。これは、APIでは、ユーザーがそのシステム名を認識しているとはみなしていないためです。これがSID
列であることを示すように、OCI_ATTR_DIRPATH_SID
で列属性を設定します。 -
オブジェクト表のオブジェクトID (
OID
)列次の場合、オブジェクトIDは必須です。
-
オブジェクトIDがシステム生成の場合。
列名にダミーの名前(たとえば、cust_oid)を使用します。
OCI_ATTR_DIRPATH_OID
で列属性を設定します。その結果、ダミーの名前を持つ列が複数ある場合にも、システム生成のOID
を表す列を識別できます。 -
オブジェクトIDが主キー・ベースの場合。
列名にはダミーの名前を使用できません。したがって、
OCI_ATTR_DIRPATH_OID
を使用してその列属性を設定する必要はありません。
-
-
SQL文字列の引数
-
OCI_ATTR_NAME
で属性の列名を設定します。 -
SQL文字列の引数の順序は、重要ではありません。SQL文字列で使用されている順序と一致させる必要はありません。
-
SQL文字列の引数には、ネーミング規則が適用されます。
-
引数名は、SQL文字列で使用されているバインド変数名と内容が一致している必要がありますが、大/小文字区別を一致させる必要はありません。たとえば、SQL文字列が
substr(:INPUT_STRING, 3, 5)
の場合は、引数名をinput_stringにできます。 -
1つの引数がSQL文字列で繰り返し使用される場合、それを一度宣言した後は、1つの引数としてカウントできます。
-
-
-
REF
引数-
OCI_ATTR_NAME
で属性の列名を設定します。REF
引数の順序は重要です。-
参照表の名前が指定されている場合は、その名前を最初のREF引数に指定します。
-
オブジェクトIDは、システム生成または主キー・ベースに関係なく、次のREF引数に指定します。
-
-
REF
の引数には、ネーミング規則が適用されます。-
参照表名の引数に対しては、列名にref-tblなどのダミーの名前を使用します。
-
システム生成OIDの引数に対しては、列名にsys-OIDなどのダミーの名前を使用します。注意: この列は、引数として使用され、ロード対象の列としては使用されないため、
OCI_ATTR_DIRPATH_OID
で設定しないでください。 -
主キー・ベースのオブジェクトIDに対しては、ロード対象のすべての主キー列をリストします。OIDに対してダミーの名前を作成する必要はありません。コンポーネント列名は、指定されている場合(次のショートカットのステップを参照)、任意の順序で指定できます。
-
-
ショートカットを使用する場合は、オブジェクトIDに属性列名を設定しないでください。
-
ショートカット。- システムOIDベースの
REF
列をロードする場合は、列名に名前を設定しないでください。名前はAPIによって判断されます。ただし、外部データ型などの他の列属性は、プログラマが設定する必要があります。 -
主キー
REF
列をロードしており、その主キーが複数の列で構成されている場合、ショートカットはそれぞれの列名に設定されません。ただし、外部データ型などの他の列属性は、プログラマが設定する必要があります。注意:
コンポーネント列名がNULLの場合は、APIコードによって、主キーに定義された位置または順序で列名が決定されます。したがって、名前以外の列属性を設定する場合は、その属性がコンポーネントの列に適切な順序で設定されていることを確認してください。
-
-
20.4.3.2 OCI_ATTR_DIRPATH_SID
列がネストした表のSETID
列であることを示します。ネストした表にロードする場合は必須です。
ub1 flg = 1; sword error; error = OCIAttrSet((void *)colDesc, OCI_DTYPE_PARAM, (void *)&flg, (ub4)0, OCI_ATTR_DIRPATH_SID, ctlp->errhp_ctl);
20.4.4 非スカラー列のダイレクト・パス関数列配列ハンドル
列がオブジェクト、SQL文字列またはREF
の場合は、OCI_HTYPE_DIRPATH_FN_COL_ARRAY
ハンドル型を使用します。
構造体OCIDirPathColArray
は、スカラー列と非スカラー列の両方の場合で同じです。
例20-24は、関数コンテキストに子の列配列を割り当てる方法を示しています。
例20-24 関数コンテキストへの子の列配列の割当て
OCIDirPathFuncCtx *dpfnctx; /* direct path function context */ OCIDirPathColArray *dpfnca; /* direct path function column array */ sword error; error = OCIHandleAlloc((void *)dpfnctx, (void **)&dpfnca, OCI_HTYPE_DIRPATH_FN_COL_ARRAY, (size_t)0, (void **)0);
この項には次のトピックが含まれます: OCI_ATTR_NUM_ROWS属性。