7 スキーマ・メタデータの記述
この章では、OCIDescribeAny()
関数を使用して、スキーマ要素に関する情報を取得する方法を説明します。
この章には次のトピックが含まれます:
関連項目:
7.1 OCIDescribeAny()の使用について
スキーマ・オブジェクトおよびそのサブスキーマ・オブジェクトの明示的記述を実行します。
OCIDescribeAny()
関数を使用すると、次のスキーマ・オブジェクトおよびそのサブスキーマ・オブジェクトを明示的に記述できます。
-
表とビュー
-
シノニム
-
プロシージャ
-
ファンクション
-
パッケージ
-
順序
-
コレクション
-
型
-
スキーマ
-
データベース
他のスキーマ要素(ファンクションの引数、列、型属性および型メソッド)の情報は、前述のスキーマ・オブジェクトのいずれかの記述、あるいはサブスキーマ・オブジェクトの明示的な記述によって取得できます。
アプリケーションで表を記述する場合は、その表の列の情報も取り出すことができます。さらに、OCIDescribeAny()
では、表の列、関数のパッケージ、型のフィールドなどのサブスキーマ・オブジェクトの名前が指定されている場合、それらのサブスキーマ・オブジェクトを直接記述できます。
OCIDescribeAny()
コールには、引数の1つとして記述ハンドルが必要です。記述ハンドルは、OCIHandleAlloc()
へのコールを使用して、事前に割り当ててください。
図7-1のように、OCIDescribeAny()
で戻された情報は、ツリーのように階層的に編成されています。
OCIDescribeAny()
によって戻される記述ハンドルには、このような記述ツリーを指し示す属性OCI_ATTR_PARAM
があります。ツリーの各ノードには、そのノードに関連する属性、および再帰的な記述ハンドルのように詳細情報を含むサブツリーを指し示す属性があります。列リストなどのリスト要素のように、すべての属性が同じ構造である場合、それらの属性をパラメータと呼びます。ノードに関連付けられた属性はOCIAttrGet()
によって、パラメータはOCIParamGet()
によって戻されます。
表の記述ハンドルについてのOCIAttrGet()
に対するコールは、列リストの情報のハンドルを戻します。アプリケーションでは、OCIParamGet()
を使用して、列リスト内の特定の列の列記述へのハンドルを取り出します。列記述子へのハンドルをOCIAttrGet()
へ受け渡すことによって、名前やデータ型などの列に関する詳細を得ることができます。
SQL文を実行した後、文ハンドルの属性として選択リストに関する情報を取得できます。明示的な記述コールは必要ありません。アプリケーションで文ハンドルから選択リストに関する情報を取り出すには、選択リストの各位置に対してOCIParamGet()
を1回ずつコールし、その位置のパラメータ記述子を割り当てる必要があります。
注意:
後続のOCIAttrGet()
コールまたはOCIParamGet()
コールでは、すべての記述がOCIDescribeAny()
によってクライアント側のキャッシュに保存されているので、追加のネットワーク・ラウンドトリップは発生しません。
7.1.1 OCIDescribeAny()に関する制限
OCIDescribeAny()
コールは基本情報に戻される情報を制限し、それが別の記述操作になる場合、ノードの拡張を停止します。
たとえば、表の列がオブジェクト型である場合、OCIでは型を記述しているサブツリーを戻しませんが、これはその情報が別の記述によって取得できるからです。
OCIDescribeAny()
によって、またはOCIStmtExecute()
を暗黙的に使用することでは、表名は戻されません。列が表に関連付けられていないこともあります。ほとんどの場合、この表はすでに認識されています。
7.1.2 型および属性の注意
記述操作を行う際の注意点について説明します。
7.1.2.1 データ型コード
OCI_ATTR_TYPECODE
は、CREATE TYPE
文を使用して新しい型が作成されたときに、ユーザーが指定した型を表す型コードを戻します。
これらの型コードは、数え上げ可能な型のOCITypeCode
で、OCI_TYPECODE
定数で表されます。内部PL/SQL型(ブール)はサポートされません。
OCI_ATTR_DATA_TYPE
は、データベースの列に格納されるデータ型を表す型コードを戻します。これらは、Oracle Databaseの以前のバージョンで戻される記述値に似ています。これらの値は、SQLT定数(ub2
値)で表されます。ブール型はSQLT_BOL
を戻します。
7.1.2.2 型の記述について
型オブジェクトを記述するには、OCIプロセスをオブジェクト・モードで初期化する必要があります。
この例を例7-1に示します。
例7-1 オブジェクト・モードでのOCIプロセスの初期化
/* Initialize the OCI Process */ if (OCIEnvCreate((OCIEnv **) &envhp, (ub4) OCI_OBJECT, (voivoid *) 0, (void * (*)(void *,size_t)) 0, (void * (*)(void *, void *, size_t)) 0, (void (*)(void *, void *)) 0, (size_t) 0, (void **) 0)) { printf("FAILED: OCIEnvCreate()\n"); return OCI_ERROR; }
関連項目:
7.1.2.3 暗黙的および明示的記述操作
OCIStmtExecute()
による暗黙的記述およびOCIDescribeAny()
による明示的記述を使用して、列属性OCI_ATTR_PRECISION
を戻すことができます。
暗黙的記述を使用する場合は、精度をsb2
に設定します。明示的記述を使用する場合は、精度をプレースホルダに対してub1
に設定します。この設定は、ディクショナリ内の精度のデータ型と一致させるために必要です。
7.2 パラメータ属性
この項では、複数のパラメータに属している属性およびハンドルについて説明します。
パラメータは、OCIParamGet()
によって戻されます。パラメータは、複数の型のオブジェクトまたは情報を記述して、そこに含まれる記述の型に応じた属性または型固有の属性を持つことができます。
OCIDescribeAny()
では、3つ以上の名前コンポーネント(たとえば、schema.type.attr1.attr2.method1
)はサポートされません。コンポーネントが複数である場合、最初のコンポーネントはスキーマ名として解釈されます(他のフラグが設定されていない場合)。フラグの中には、オブジェクトがPUBLIC下で参照されるように指定する、つまり「a」を記述するものがあります(ここで、「a」はカレント・スキーマ内のオブジェクトまたはパブリック・シノニムのいずれか)。
オブジェクト型が何であるかわからない場合は、OCI_PTYPE_UNK
を指定してください。そうでない場合、実際のオブジェクト型が指定した型と一致しない場合にはエラーが戻されます。
次の表7-1は、すべてのパラメータの属性のリストです。
表7-1 すべてのパラメータの属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
オブジェクトIDまたはスキーマID。 |
ub4 |
|
スキーマ内のデータベース名またはオブジェクト名。 |
OraText * |
|
そのオブジェクトが存在しているスキーマの名前。 |
OraText * |
|
パラメータによって記述される情報の型。可能な値は次のとおりです。
|
ub1 |
|
Oracle日付書式がその記述の基礎となるオブジェクトのタイムスタンプ。 |
ub1 * |
7.2.1 表またはビューのパラメータ
表またはビューのパラメータの型固有の属性をリストし、説明します。
表7-2では、表またはビュー(OCI_PTYPE_TABLE
型またはOCI_PTYPE_VIEW
型)のパラメータの型に特有の属性を示しています。
表7-2 表またはビューの属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
オブジェクトID |
ub4 |
|
列の数 |
ub2 |
|
列リスト( |
OCIParam * |
|
エクステント表の基本型の型記述オブジェクト(TDO)に対する |
OCIRef * |
|
表が一時表であることを示します。 |
ub1 |
|
|
表に型が指定されていることを示します。 |
ub1 |
一時表の継続時間。可能な値は次のとおりです。
|
OCIDuration |
表7-3では、表に属する追加属性を示しています。
7.2.2 プロシージャ、ファンクションおよびサブプログラムの属性
プロシージャまたは関数のパラメータの場合の型固有の属性をリストし、説明します。
表7-4では、プロシージャまたはファンクションのパラメータ(OCI_PTYPE_PROC
型またはOCI_PTYPE_FUNC
型)の場合の型に特有の属性を示しています。
表7-4 プロシージャまたはファンクションの属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
引数のリスト。「リスト属性」を参照してください。 |
void * |
|
プロシージャまたはファンクションに実行者権限があることを示します。 |
ub1 |
表7-5では、パッケージ・サブプログラム用にのみ定義されている属性を示しています。
表7-5 パッケージ・サブプログラムに特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
プロシージャまたはファンクションの名前。 |
OraText * |
|
オーバーロードする側のID番号(これはプロシージャまたはファンクションがパッケージの一部でかつそれらをオーバーロードする場合に必要です)。戻り値は、PL/SQLファンクションまたはプロシージャによる直接問合せとは異なる可能性があります。 |
ub2 |
7.2.3 パッケージ属性
パッケージのパラメータの場合の属性をリストし、説明します。
表7-6では、パッケージのパラメータ(OCI_PTYPE_PKG
型)の場合の属性を示しています。
表7-6 パッケージの属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
|
void * |
|
サブプログラム・リスト。「リスト属性」を参照してください。 |
void * |
|
パッケージに実行者権限があることを示します。 |
ub1 |
7.2.4 型属性
型のパラメータの場合の属性をリストし、説明します。
表7-7では、型のパラメータ(OCI_PTYPE_TYPE
型)の場合の属性を示しています。これらの属性は、OCIEnvCreate()
のコールの際に、アプリケーションによってOCI_OBJECT
モードでOCIプロセスが初期化された場合にのみ有効です。
表7-7 型の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
列の型がオブジェクト型の場合は、その型の型記述子オブジェクト(TDO)のインメモリー |
OCIRef * |
|
型コード。「データ型コード」を参照してください。現在は、 |
OCITypeCode |
|
型がコレクションの場合はコレクションの型コードで、それ以外の場合は無効です。「データ型コード」を参照してください。現在は、 |
OCITypeCode |
|
不完全な型であることを示します。 |
ub1 |
|
システム型であることを示します。 |
ub1 |
|
事前定義済の型であることを示します。 |
ub1 |
|
一時的な型であることを示します。 |
ub1 |
|
システム生成型であることを示します。 |
ub1 |
|
ネストした表属性を含む型です。 |
ub1 |
|
LOB属性を含む型です。 |
ub1 |
|
|
ub1 |
|
コレクション要素へのハンドル。「コレクション属性」を参照してください。 |
void * |
|
型属性の数。 |
ub2 |
|
型属性のリスト。「リスト属性」を参照してください。 |
void * |
|
型メソッドの数。 |
ub2 |
|
型メソッドのリスト。「リスト属性」を参照してください。 |
void * |
|
型のマップ・メソッド。「型メソッド属性」を参照してください。 |
void * |
|
型のオーダー・メソッド。「型メソッド属性」を参照してください。 |
void * |
|
型に実行者権限があることを示します。 |
ub1 |
|
型属性名である文字列へのポインタ。 |
OraText * |
|
属性がパッケージ型の場合、パッケージ名を持つ文字列。 |
OraText * |
|
型作成時のスキーマ名が付いた文字列。 |
OraText * |
|
最後の型であることを示します。 |
ub1 |
|
インスタンス化可能な型であることを示します。 |
ub1 |
|
サブタイプであることを示します。 |
ub1 |
|
スーパータイプを含むスキーマの名前。 |
OraText * |
|
スーパータイプの名前。 |
OraText * |
関連項目:
7.2.5 型属性の属性
型の属性のパラメータの場合の属性をリストし、説明します。
表7-8では、型の属性のパラメータ(OCI_PTYPE_TYPE_ATTR
型)の場合の属性を示しています。
表7-8 型属性の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
型属性の最大サイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。 |
ub2 |
|
型コード。「データ型コード」を参照してください。 |
OCITypeCode |
|
型属性のデータ型。「データ型コード」を参照してください。 |
ub2 |
|
型属性名である文字列へのポインタ。 |
OraText * |
|
数値型属性の精度。精度が0 (ゼロ)以外でスケールが-127の場合は |
ub1明示的記述の場合 sb2暗黙的記述の場合 |
|
数値型属性のスケール。精度が0 (ゼロ)以外でスケールが-127の場合は |
sb1 |
|
パッケージ型の場合、型のパッケージ名である文字列。 |
OraText * |
|
型名である文字列。データ型が |
OraText * |
|
型作成時のスキーマ名が付いた文字列。 |
OraText * |
|
列の型がオブジェクト型の場合は、その型のTDOのインメモリー |
OCIRef * |
|
型属性が文字列また文字型の場合は、キャラクタ・セットID。 |
ub2 |
|
型属性が文字列または文字型の場合は、キャラクタ・セット・フォーム。 |
ub1 |
|
日時または時間隔の小数秒の精度。 |
ub1 |
|
時間隔の先行フィールドの精度。 |
ub1 |
7.2.6 型メソッド属性
型のメソッドのパラメータの場合の属性をリストし、説明します。
表7-9では、型のメソッドのパラメータ(OCI_PTYPE_TYPE_METHOD
型)の場合の属性を示しています。
表7-9 型メソッドの属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
メソッド名(プロシージャまたはファンクション)。 |
OraText * |
|
メソッドのカプセル化レベル( |
OCITypeEncap |
|
引数のリスト。「OCI_ATTR_LIST_ARGUMENTS属性」および「リスト属性」を参照してください。 |
void * |
|
メソッドがコンストラクタであることを示します。 |
ub1 |
|
メソッドがデストラクタであることを示します。 |
ub1 |
|
メソッドが演算子であることを示します。 |
ub1 |
|
メソッドが自己参照的であることを示します。 |
ub1 |
|
メソッドがマップ・メソッドであることを示します。 |
ub1 |
|
メソッドがオーダー・メソッドであることを示します。 |
ub1 |
|
「Read No Data State」がメソッドに設定されていることを示します。 |
ub1 |
|
「Read No Process State」がメソッドに設定されていることを示します。 |
ub1 |
|
「Write No Data State」がメソッドに設定されていることを示します。 |
ub1 |
|
「Write No Process State」がメソッドに設定されていることを示します。 |
ub1 |
|
最後のメソッドであることを示します。 |
ub1 |
|
インスタンス化可能なメソッドであることを示します。 |
ub1 |
|
オーバーライドするメソッドであることを示します。 |
ub1 |
7.2.7 コレクション属性
コレクション型のパラメータの場合の属性をリストし、説明します。
表7-10では、コレクション型のパラメータ(OCI_PTYPE_COLL
型)の場合の属性を示しています。
表7-10 コレクション型の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
型属性の最大サイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。 |
ub2 |
|
型コード。「データ型コード」を参照してください。 |
OCITypeCode |
|
型属性のデータ型。「データ型コード」を参照してください。 |
ub2 |
|
配列の要素の数。コレクションが配列である場合にのみ有効です。 |
ub4 |
|
型属性名である文字列へのポインタ。 |
OraText * |
|
数値型属性の精度。精度が0 (ゼロ)以外でスケールが-127の場合は |
ub1 明示的記述の場合 sb2 暗黙的記述の場合 |
|
数値型属性のスケール。精度が0 (ゼロ)以外でスケールが-127の場合は |
sb1 |
|
パッケージ型の場合、型のパッケージ名である文字列。 |
OraText * |
|
型名である文字列。データ型が |
OraText * |
|
型作成時のスキーマ名が付いた文字列。 |
OraText * |
|
列の型がオブジェクト型の場合は、その型の型記述子オブジェクト(TDO)のインメモリー |
OCIRef * |
|
型属性が文字列また文字型の場合は、キャラクタ・セットID。 |
ub2 |
|
型属性が文字列または文字型の場合は、キャラクタ・セット・フォーム。 |
ub1 |
7.2.8 シノニム属性
シノニムのパラメータの場合の属性をリストし、説明します。
表7-11では、シノニムのパラメータ(OCI_PTYPE_SYN
型)の場合の属性を示しています。
表7-11 シノニムの属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
オブジェクトID |
ub4 |
|
シノニム翻訳のスキーマ名を含む文字列。 |
OraText * |
|
シノニム翻訳のオブジェクト名を含む、 |
OraText * |
|
シノニム翻訳のデータベース・リンク名を含む、 |
OraText * |
7.2.9 順序属性
順序のパラメータの場合の属性をリストし、説明します。
表7-12では、順序のパラメータ(OCI_PTYPE_SEQ
型)の場合の属性を示しています。
表7-12 順序の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
オブジェクトID |
ub4 |
|
最小値(Oracle |
ub1 |
|
最大値(Oracle |
ub1 |
|
増分(Oracle |
ub1 |
|
キャッシュされた順序番号の数。順序がキャッシュされた順序でない場合は、0 (ゼロ)です(Oracle |
ub1 |
|
順序が順序指定されているかどうか。 |
ub1 |
|
最高水位標( |
ub1 |
関連項目:
7.2.10 列属性
表またはビューの列のパラメータの場合の属性をリストし、説明します。
注意:
BINARY_FLOAT
およびBINARY_DOUBLE
の場合:
OCIDescribeAny()
を使用して、表のBINARY_FLOAT
列またはBINARY_DOUBLE
列の列データ型(OCI_ATTR_DATA_TYPE
)を取り出す場合は、内部データ型コードが戻されます。
BINARY_FLOAT
およびBINARY_DOUBLE
の内部データ型コードに対応するSQLTコードは、SQLT_IBFLOAT
およびSQLT_IBDOUBLE
です。
次の表では、表またはビューの列のパラメータ(OCI_PTYPE_COL
型)の場合の属性を示しています。
表7-13 表またはビューの列の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
列の長さセマンティクスの型を戻します。0 (ゼロ)はバイト長セマンティクスを示し、1は文字長セマンティクスを示します。「記述操作での文字長セマンティクスのサポート」を参照してください。 |
ub1 |
|
列の文字長、つまり列内で使用可能な文字数を戻します。これは |
ub2 |
|
列の導出された照合IDを戻します。 注意: SQLの組込みファンクション 関連項目:
|
ub4 * |
|
特定の列のプロパティに関する記述データが戻されます。
使用例を次に示します。 OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM, (dvoid*) &col_prop, (ub4 *) 0,(ub4) OCI_ATTR_COL_PROPERTIES, (OCIError *) errhp )); if(col_prop & OCI_ATTR_COL_PROPERTY_IS_IDENTITY) printf("Identity Column \n"); if(col_prop & OCI_ATTR_COL_PROPERTY_IS_GEN_ALWAYS) printf("Column is always generated\n"); if(col_prop & OCI_ATTR_COL_PROPERTY_IS_GEN_BY_DEF_ON_NULL) printf("Column is generated by default on NULL\n"); if(col_prop & OCI_ATTR_COL_PROPERTY_IS_LPART) printf("Column is an implicitly generated logical partitioning column for container_map enabled objects\n"); if(col_prop & OCI_ATTR_COL_PROPERTY_IS_CONID) printf("Column is a CON_ID column implicitly generated by CONTAINERS() or is an ORIGIN_CON_ID column implicitly generated for Extended Data Link\n");
|
ub8 |
|
列が非表示であるかどうかが戻されます。 |
ub1 |
|
列の最大サイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。 |
ub2 |
|
列のデータ型。「データ型コード」を参照してください。 |
ub2 |
|
列名である文字列へのポインタ。 |
OraText * |
|
数値列の精度。精度が0 (ゼロ)以外でスケールが-127の場合は |
ub1 明示的記述の場合 sb2 暗黙的記述の場合 |
|
数値列のスケール。精度が0 (ゼロ)以外でスケールが-127の場合は |
sb1 |
|
列にNULL値が許可されていない場合に、0 (ゼロ)を戻します。 |
ub1 |
|
型名である文字列を戻します。データ型が |
OraText * |
|
型の作成時に使用したスキーマ名を持つ文字列を戻します。 |
OraText * |
|
列の型がオブジェクト型の場合は、その型のTDOの |
OCIRef * |
|
列が文字列または文字型の場合は、キャラクタ・セットID。 |
ub2 |
|
列が文字列または文字型の場合は、キャラクタ・セット・フォーム。 |
ub1 |
表7-14は、一般的に使用される複数の照合IDに対して事前定義された定数で、OCI_ATTR_COLLATION_ID
属性に対して戻されることがあります。定数は、その値(カッコ内)および対応する照合のSQL名とともにリストされています。
表7-14 事前定義された照合ID、そのub4
の値(カッコ内)およびそのSQL名
照合ID (値) | SQL名 |
---|---|
OCI_COLLATION_NONE (0) | 未定義の照合(照合は指定されていません)。 |
OCI_COLLATION_NLS_COMP (16382) | USING_NLS_COMP |
OCI_COLLATION_NLS_SORT (16381) | USING_NLS_SORT |
OCI_COLLATION_NLS_SORT_CI (16380) | USING_NLS_SORT_CI |
OCI_COLLATION_NLS_SORT_AI (16379) | USING_NLS_SORT_AI |
OCI_COLLATION_NLS_SORT_CS (16378) | USING_NLS_SORT_CS |
OCI_COLLATION_BINARY (16383) | BINARY |
OCI_COLLATION_BINARY_CI (147455) | BINARY_CI |
OCI_COLLATION_BINARY_AI (81919) | BINARY_AI |
関連項目:
7.2.11 引数属性および結果属性
プロシージャまたは関数の引数のパラメータの場合の属性をリストし、説明します。
表7-15では、プロシージャやファンクションの引数のパラメータ(OCI_PTYPE_ARG
型)、型メソッド引数のパラメータ(OCI_PTYPE_TYPE_ARG
型)またはメソッド結果のパラメータ(OCI_PTYPE_TYPE_RESULT
型)の場合の属性を示しています。
表7-15 引数および結果の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
引数名である文字列へのポインタを戻します。 |
OraText * |
|
引数リストの引数の位置。常に0 (ゼロ)を戻します。 |
ub2 |
|
型コード。「データ型コード」を参照してください。 |
OCITypeCode |
|
引数のデータ型。「データ型コード」を参照してください。 |
ub2 |
|
引数のデータ型のサイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。 |
ub2 |
|
数値引数の精度。精度が0 (ゼロ)以外でスケールが-127の場合は |
明示的記述の場合は 暗黙的記述の場合は |
|
数値引数のスケール。精度が0 (ゼロ)以外でスケールが-127の場合は |
|
|
データ型のレベル。この属性は常に0 (ゼロ)を戻します。 |
ub2 |
|
引数にデフォルト値があるかどうかを示します。 |
ub1 |
|
次のレベルの引数のリスト(引数がレコード型または表型のとき)。 |
void * |
|
次の引数モードを示します。 0はIN ( 1はOUT ( 2はIN/OUT ( |
OCITypeParamMode |
|
基数を戻します(数値型の場合)。 |
ub1 |
|
列にNULL値が許可されていない場合に、0 (ゼロ)を戻します。 |
ub1 |
|
パッケージのローカル型の場合は、型名またはパッケージ名の文字列を戻します。データ型が |
OraText * |
|
|
OraText * |
|
|
OraText * |
|
|
OraText * |
|
引数型がオブジェクトの場合は、その型の型記述子オブジェクト(TDO)の |
OCIRef * |
|
引数が文字列または文字型の場合は、キャラクタ・セットIDを戻します。 |
ub2 |
|
引数が文字列または文字型の場合は、キャラクタ・セット・フォームを戻します。 |
ub1 |
7.2.12 リスト属性
列、引数、サブプログラムまたはパッケージ・レコード型のフィールドのリストのパラメータの場合の属性をリストし、説明します。
列、引数、サブプログラムまたはパッケージ・レコード型のフィールドのリストのパラメータ(OCI_PTYPE_LIST
型)の場合、表7-16に示すような型に特有の属性およびハンドル(パラメータ)があります。
リストには、リスト型を指定するOCI_ATTR_LTYPE
属性があります。表7-16では、リストの横断時に予想される値とその下限を示しています。
表7-16 リスト属性
リスト属性 | 説明 | 下限 |
---|---|---|
|
列リスト |
1 |
|
プロシージャ引数リスト |
1 |
|
ファンクション引数リスト |
0 |
|
サブプログラム・リスト |
0 |
|
型属性リスト |
1 |
|
型メソッド・リスト |
1 |
|
結果引数なしの型メソッド・リスト。 |
0 |
|
結果引数なしの型メソッド・リスト。 |
1 |
|
スキーマ内のオブジェクト・リスト。 |
0 |
|
データベース内のスキーマ・リスト。 |
0 |
リストには、リスト内の要素数を調べるOCI_ATTR_NUM_PARAMS
属性があります。
各リストには、LowerBound
... OCI_ATTR_NUM_PARAMS
パラメータがあります。LowerBound
は、表7-16の「下限」列の値です。ファンクション引数リストの場合、位置0には、戻り値(OCI_PTYPE_ARG
型)のパラメータがあります。
7.2.13 スキーマ属性
スキーマ型のパラメータの場合の属性をリストし、説明します。
表7-17では、スキーマ型のパラメータ(OCI_PTYPE_SCHEMA
型)の場合の属性を示しています。
表7-17 スキーマ固有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
スキーマ内のオブジェクトのリスト。 |
OCIParam * |
7.2.14 データベース属性
データベース型のパラメータの場合の属性をリストし、説明します。
表7-18では、データ型のパラメータ(OCI_PTYPE_DATABASE
型)の場合の属性を示しています。
表7-18 データベース固有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
データベースのバージョン |
OraText * |
|
サーバー・ハンドルからのデータベース・キャラクタ・セットID。 |
ub2 |
|
サーバー・ハンドルからのデータベース各国語キャラクタ・セットID。 |
ub2 |
|
データベース内のスキーマのリスト( |
ub1 |
|
プロシージャ名の最大長。 |
ub4 |
|
列名の最大長。 |
ub4 |
|
|
ub1 |
|
カタログ(データベース)名の最大長。 |
ub1 |
|
修飾表内のカタログの位置。値は |
ub1 |
|
データベースがセーブポイントをサポートするかどうか。値は |
ub1 |
|
データベースがNOWAIT句をサポートするかどうか。値は |
ub1 |
|
DDL文で自動コミット・モードが必要かどうか。値は |
ub1 |
|
データベースのロック・モード。値は |
ub1 |
7.2.15 ルール属性
ルールのパラメータの場合の属性をリストし、説明します。
表7-19では、ルールのパラメータ(OCI_PTYPE_RULE
型)の場合の属性を示しています。
表7-19 ルールに特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
ルール条件 |
OraText * |
|
ルールに関連する評価コンテキストの所有者名(ある場合)。 |
OraText * |
|
ルールに関連する評価コンテキストのオブジェクト名(ある場合)。 |
OraText * |
|
ルールに関連するコメント(ある場合)。 |
OraText * |
|
処理コンテキストの名前/値ペアのリスト( |
void * |
7.2.16 ルール・セット属性
ルール・セットのパラメータの場合の属性をリストし、説明します。
表7-20では、ルール・セットのパラメータ(OCI_PTYPE_RULE_SET
型)の場合の属性を示しています。
表7-20 ルール・セットに特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
ルール・セットに関連する評価コンテキストの所有者名(ある場合)。 |
OraText * |
|
ルール・セットに関連する評価コンテキストのオブジェクト名(ある場合)。 |
OraText * |
|
ルール・セットに関連するコメント(ある場合)。 |
OraText * |
|
ルール・セットのルールのリスト( |
void * |
7.2.17 評価コンテキスト属性
評価コンテキストのパラメータの場合の属性をリストし、説明します。
表7-21では、評価コンテキストのパラメータ(OCI_PTYPE_EVALUATION_CONTEXT
型)の場合の属性を示しています。
表7-21 評価コンテキストに特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
評価コンテキストに関連する評価ファンクション(ある場合)。 |
OraText * |
|
評価コンテキストに関連するコメント(ある場合)。 |
OraText * |
|
評価コンテキストの表別名のリスト( |
void * |
|
評価コンテキストの変数型のリスト( |
void * |
7.2.18 表別名の属性
表別名のパラメータの場合の属性をリストし、説明します。
表7-22では、表別名のパラメータ(OCI_PTYPE_TABLE_ALIAS
型)の場合の属性を示しています。
表7-22 表別名に特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
表別名 |
OraText * |
|
別名に関連する表名。 |
OraText * |
7.2.19 変数型の属性
変数のパラメータの場合の属性をリストし、説明します。
表7-23では、変数のパラメータ(OCI_PTYPE_VARIABLE_TYPE
型)の場合の属性を示しています。
表7-23 変数型に特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
変数名 |
OraText * |
|
変数型 |
OraText * |
|
変数に関連する変数値ファンクション(ある場合)。 |
OraText * |
|
変数に関連する変数メソッド・ファンクション(ある場合)。 |
OraText * |
7.2.20 名前/値の属性
名前/値ペアのパラメータの場合の属性をリストし、説明します。
表7-24では、名前/値ペアのパラメータ(OCI_PTYPE_NAME_VALUE
型)の場合の属性を示しています。
表7-24 名前/値ペアに特有の属性
属性 | 説明 | 属性のデータ型 |
---|---|---|
|
名前 |
OraText * |
|
値 |
OCIAnyData* |
7.3 記述操作での文字長セマンティクスのサポート
問合せ情報と列情報は、文字長セマンティクスでサポートされます。
Oracle9i以上での問合せ情報と列情報は、文字長セマンティクスでサポートされます。
記述ハンドルの次の属性は、文字長セマンティクスをサポートします。
-
OCI_ATTR_CHAR_SIZE
は、列の文字長、つまり、列内で使用可能な文字数を示します。これはOCI_ATTR_DATA_SIZE
に相当するもので、バイト長で使用します。 -
ストアド・プロシージャ・パラメータがバインドされていないため、属性
OCI_ATTR_CHAR_SIZE
またはOCI_ATTR_DATA_SIZE
を使用してOCIAttrGet()
をコールすると、ストアド・プロシージャ・パラメータのデータは戻されません。 -
OCI_ATTR_CHAR_USED
では、列の長さセマンティクスの型を取得します。0 (ゼロ)はバイト長セマンティクスを示し、1は文字長セマンティクスを示します。
アプリケーションでは、OCIStmtExecute()
を使用して選択リスト問合せを暗黙的にも明示的にも記述できます。その他のスキーマ要素は、OCIDescribeAny()
を使用して明示的に記述する必要があります。
7.3.1 暗黙的記述
データベース列が文字長セマンティクスを使用して作成されている場合、暗黙的な記述情報には、文字長、バイト長、およびデータベース列の作成方法を示すフラグが含まれます。
OCI_ATTR_CHAR_SIZE
は、列または式の文字長です。この場合、OCI_ATTR_CHAR_USED
フラグは、列または式が文字長セマンティクスを使用して作成されたことを示す1になります。
OCI_ATTR_DATA_SIZE
は常に、すべてのデータ、すなわちOCI_ATTR_CHAR_SIZE
の文字数と同じだけのデータを保持するのに十分な大きさの値になります。OCI_ATTR_DATA_SIZE
は通常、(OCI_ATTR_CHAR_SIZE
)×(クライアントの各文字の最大バイト数)に設定されます。
データベース列がバイト長セマンティクスを使用して作成されている場合、暗黙的な記述では(その動作はリリース9.0より前と同じ)、戻されるOCI_ATTR_DATA_SIZE
は、(列のバイト長)×(クライアントとサーバーのキャラクタ・セット間での最大変換率)の値になります。つまり、(列のバイト長)÷(サーバーの各文字の最大バイト数)×(クライアントの各文字の最大バイト数)になります。OCI_ATTR_CHAR_USED
値は0で、OCI_ATTR_CHAR_SIZE
値はOCI_ATTR_DATA_SIZE
と同じ値に設定されます。
7.3.2 明示的記述
表の明示的記述には、OCI_ATTR_DATA_SIZE
、OCI_ATTR_CHAR_SIZE
およびOCI_ATTR_CHAR_USED
という3つの属性があります。
表の明示的記述には、次の属性が含まれます。
-
OCI_ATTR_DATA_SIZE
は、サーバーで表示される列のサイズをバイト数で取得します。 -
OCI_ATTR_CHAR_SIZE
は、列の長さを文字数で示します。 -
OCI_ATTR_CHAR_USED
は、列の長さセマンティクスの型に関して前に述べたように、列の作成方法を示すフラグです。
OCI_ATTR_CHAR_USED
のフラグが設定されている場合は、挿入時に、バインド・バンドルのOCI_ATTR_MAXCHAR_SIZE
を、パラメータ・ハンドルのOCI_ATTR_CHAR_SIZE
によって戻される値に設定できます。これにより、列のサイズ制限に違反することを防ぎます。
この項には次のトピックが含まれます。「記述に関するクライアントとサーバー間の互換性の問題」。
関連項目:
7.3.2.1 記述に関するクライアントとサーバー間の互換性の問題
文字長セマンティクスはサーバーまたはクライアントのリリースに依存します。記述には、サーバーとクライアントの両方をOracle9i以上にすることをお薦めします。そうしないと、次に説明するような互換性の問題が発生します。
Oracle9i 以上のクライアントがOracle8i 以下のサーバーと通信を行うと、そのクライアントは、データベースがバイト長セマンティクスのみを使用しているかのように動作します。
Oracle8i 以下のクライアントがOracle9i 以上のサーバーと通信を行うと、クライアント側でOCI_ATTR_CHAR_SIZE
属性とOCI_ATTR_CHAR_USED
属性を使用することはできません。
いずれの場合も、サーバーまたはクライアントがOracle8i 以下のソフトウェア・リリースである場合、文字長セマンティクスは記述できません。
7.4 OCIDescribeAny()の使用例
次の例では、異なる種類のスキーマ・オブジェクトを記述するためのOCIDescribeAny()
の使用方法を示します。
より詳細なコード例は、Oracle Databaseのインストールに含まれているデモ・プログラムcdemodsa.c
を参照してください。
関連項目:
-
デモ・プログラムの詳細は、「OCIデモ・プログラム」を参照してください
7.4.1 表用の列データ型の取出し
表の列データ型を取り出す明示的な記述の使用方法を示します。
例7-2では、表の列データ型を取り出す明示的な記述の使用方法を示しています。
例7-2 表の列データ型を取り出す明示的な記述の使用方法
... int i=0; text objptr[] = "EMPLOYEES"; /* the name of a table to be described */ ub2 numcols, col_width; ub1 char_semantics; ub2 coltyp; ub4 objp_len = (ub4) strlen((char *)objptr); OCIParam *parmh = (OCIParam *) 0; /* parameter handle */ OCIParam *collsthd = (OCIParam *) 0; /* handle to list of columns */ OCIParam *colhd = (OCIParam *) 0; /* column handle */ OCIDescribe *dschp = (OCIDescribe *)0; /* describe handle */ OCIHandleAlloc((void *)envhp, (void **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (void **)0); /* get the describe handle for the table */ if (OCIDescribeAny(svch, errh, (void *)objptr, objp_len, OCI_OTYPE_NAME, 0, OCI_PTYPE_TABLE, dschp)) return OCI_ERROR; /* get the parameter handle */ if (OCIAttrGet((void *)dschp, OCI_HTYPE_DESCRIBE, (void *)&parmh, (ub4 *)0, OCI_ATTR_PARAM, errh)) return OCI_ERROR; /* The type information of the object, in this case, OCI_PTYPE_TABLE, is obtained from the parameter descriptor returned by the OCIAttrGet(). */ /* get the number of columns in the table */ numcols = 0; if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, (void *)&numcols, (ub4 *)0, OCI_ATTR_NUM_COLS, errh)) return OCI_ERROR; /* get the handle to the column list of the table */ if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, (void *)&collsthd, (ub4 *)0, OCI_ATTR_LIST_COLUMNS, errh)==OCI_NO_DATA) return OCI_ERROR; /* go through the column list and retrieve the data type of each column, and then recursively describe column types. */ for (i = 1; i <= numcols; i++) { /* get parameter for column i */ if (OCIParamGet((void *)collsthd, OCI_DTYPE_PARAM, errh, (void **)&colhd, (ub4)i)) return OCI_ERROR; /* for example, get data type for ith column */ coltyp = 0; if (OCIAttrGet((void *)colhd, OCI_DTYPE_PARAM, (void *)&coltyp, (ub4 *)0, OCI_ATTR_DATA_TYPE, errh)) return OCI_ERROR; /* Retrieve the length semantics for the column */ char_semantics = 0; OCIAttrGet((void*) colhd, (ub4) OCI_DTYPE_PARAM, (void*) &char_semantics,(ub4 *) 0, (ub4) OCI_ATTR_CHAR_USED, (OCIError *) errh); col_width = 0; if (char_semantics) /* Retrieve the column width in characters */ OCIAttrGet((void*) colhd, (ub4) OCI_DTYPE_PARAM, (void*) &col_width, (ub4 *) 0, (ub4) OCI_ATTR_CHAR_SIZE, (OCIError *) errh); else /* Retrieve the column width in bytes */ OCIAttrGet((void*) colhd, (ub4) OCI_DTYPE_PARAM, (void*) &col_width,(ub4 *) 0, (ub4) OCI_ATTR_DATA_SIZE, (OCIError *) errh); } if (dschp) OCIHandleFree((void *) dschp, OCI_HTYPE_DESCRIBE); ...
7.4.2 ストアド・プロシージャの記述
型メソッドの記述に必要なステップ(ファンクションとプロシージャへの分割も行います)は、通常のPL/SQLファンクションおよびプロシージャのステップとまったく同じです。
プロシージャとファンクションの違いは、ファンクションには引数リストに位置0 (ゼロ)の戻り型がありますが、プロシージャには、引数リストの位置0 (ゼロ)に対応する引数がないことです。プロシージャおよびファンクションは、オブジェクトのデフォルト型を引数として使用できることに注意してください。次のプロシージャで考えてみます。
P1 (arg1 emp.sal%type, arg2 emp%rowtype)
例7-3では、emp
表の各行には、name(VARCHAR2(20))
およびsal(NUMBER)
の2列があると想定します。P1
の引数リストには、arg1
とarg2
の2つの引数がそれぞれレベル0 (ゼロ)の位置1と位置2にあり、引数のname
とsal
がそれぞれレベル1の位置1と位置2にあります。P1
の記述では、引数の数を2として戻し、レベル0 (ゼロ)を超える(> 0)引数を、レベル0 (ゼロ)の引数の属性として戻します。
例7-3 ストアド・プロシージャの記述
... int i = 0, j = 0; text objptr[] = "add_job_history"; /* the name of a procedure to be described */ ub4 objp_len = (ub4)strlen((char *)objptr); ub2 numargs = 0, numargs1, pos, level; text *name, *name1; ub4 namelen, namelen1; OCIParam *parmh = (OCIParam *) 0; /* parameter handle */ OCIParam *arglst = (OCIParam *) 0; /* list of args */ OCIParam *arg = (OCIParam *) 0; /* argument handle */ OCIParam *arglst1 = (OCIParam *) 0; /* list of args */ OCIParam *arg1 = (OCIParam *) 0; /* argument handle */ OCIDescribe *dschp = (OCIDescribe *)0; /* describe handle */ OCIHandleAlloc((void *)envhp, (void **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (void **)0); /* get the describe handle for the procedure */ if (OCIDescribeAny(svch, errh, (void *)objptr, objp_len, OCI_OTYPE_NAME, 0, OCI_PTYPE_PROC, dschp)) return OCI_ERROR; /* get the parameter handle */ if (OCIAttrGet((void *)dschp, OCI_HTYPE_DESCRIBE, (void *)&parmh, (ub4 *)0, OCI_ATTR_PARAM, errh)) return OCI_ERROR; /* Get the number of arguments and the arg list */ if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, (void *)&arglst, (ub4 *)0, OCI_ATTR_LIST_ARGUMENTS, errh)) return OCI_ERROR; if (OCIAttrGet((void *)arglst, OCI_DTYPE_PARAM, (void *)&numargs, (ub4 *)0, OCI_ATTR_NUM_PARAMS, errh)) return OCI_ERROR; /* For a procedure, you begin with i = 1; for a function, you begin with i = 0. */ for (i = 1; i <= numargs; i++) { OCIParamGet ((void *)arglst, OCI_DTYPE_PARAM, errh, (void **)&arg, (ub4)i); namelen = 0; OCIAttrGet((void *)arg, OCI_DTYPE_PARAM, (void *)&name, (ub4 *)&namelen, OCI_ATTR_NAME, errh); /* to print the attributes of the argument of type record (arguments at the next level), traverse the argument list */ OCIAttrGet((void *)arg, OCI_DTYPE_PARAM, (void *)&arglst1, (ub4 *)0, OCI_ATTR_LIST_ARGUMENTS, errh); /* check if the current argument is a record. For arg1 in the procedure arglst1 is NULL. */ if (arglst1) { numargs1 = 0; OCIAttrGet((void *)arglst1, OCI_DTYPE_PARAM, (void *)&numargs1, (ub4 *)0, OCI_ATTR_NUM_PARAMS, errh); /* Note that for both functions and procedures,the next higher level arguments start from index 1. For arg2 in the procedure, the number of arguments at the level 1 would be 2 */ for (j = 1; j <= numargs1; j++) { OCIParamGet((void *)arglst1, OCI_DTYPE_PARAM, errh, (void **)&arg1, (ub4)j); namelen1 = 0; OCIAttrGet((void *)arg1, OCI_DTYPE_PARAM, (void *)&name1, (ub4 *)&namelen1, OCI_ATTR_NAME, errh); } } } if (dschp) OCIHandleFree((void *) dschp, OCI_HTYPE_DESCRIBE); ...
7.4.3 オブジェクト型の属性の取出し
名前付きオブジェクト型についての明示的な記述の使用方法を示します。
例7-4では、名前付きオブジェクト型についての明示的な記述の使用方法を示しています。オブジェクトを名前またはオブジェクト参照(OCIRef
)によって記述する方法を説明します。次のコード・フラグメントによって、オブジェクト型の属性について各データ型値の取出しが試みられます。
例7-4 名前付きオブジェクト型についての明示的な記述の使用方法
... int i = 0; text type_name[] = "inventory_typ"; ub4 type_name_len = (ub4)strlen((char *)type_name); OCIRef *type_ref = (OCIRef *) 0; ub2 numattrs = 0, describe_by_name = 1; ub2 datatype = 0; OCITypeCode typecode = 0; OCIDescribe *dschp = (OCIDescribe *) 0; /* describe handle */ OCIParam *parmh = (OCIParam *) 0; /* parameter handle */ OCIParam *attrlsthd = (OCIParam *) 0; /* handle to list of attrs */ OCIParam *attrhd = (OCIParam *) 0; /* attribute handle */ /* allocate describe handle */ if (OCIHandleAlloc((void *)envh, (void **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (void **)0)) return OCI_ERROR; /* get the describe handle for the type */ if (describe_by_name) { if (OCIDescribeAny(svch, errh, (void *)type_name, type_name_len, OCI_OTYPE_NAME, 0, OCI_PTYPE_TYPE, dschp)) return OCI_ERROR; } else { /* get ref to type using OCIAttrGet */ /* get the describe handle for the type */ if (OCIDescribeAny(svch, errh, (void*)type_ref, 0, OCI_OTYPE_REF, 0, OCI_PTYPE_TYPE, dschp)) return OCI_ERROR; } /* get the parameter handle */ if (OCIAttrGet((void *)dschp, OCI_HTYPE_DESCRIBE, (void *)&parmh, (ub4 *)0, OCI_ATTR_PARAM, errh)) return OCI_ERROR; /* The type information of the object, in this case, OCI_PTYPE_TYPE, is obtained from the parameter descriptor returned by OCIAttrGet */ /* get the number of attributes in the type */ if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, (void *)&numattrs, (ub4 *)0, OCI_ATTR_NUM_TYPE_ATTRS, errh)) return OCI_ERROR; /* get the handle to the attribute list of the type */ if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, (void *)&attrlsthd, (ub4 *)0, OCI_ATTR_LIST_TYPE_ATTRS, errh)) return OCI_ERROR; /* go through the attribute list and retrieve the data type of each attribute, and then recursively describe attribute types. */ for (i = 1; i <= numattrs; i++) { /* get parameter for attribute i */ if (OCIParamGet((void *)attrlsthd, OCI_DTYPE_PARAM, errh, (void **)&attrhd, i)) return OCI_ERROR; /* for example, get data type and typecode for attribute; note that OCI_ATTR_DATA_TYPE returns the SQLT code, whereas OCI_ATTR_TYPECODE returns the Oracle Type System typecode. */ datatype = 0; if (OCIAttrGet((void *)attrhd, OCI_DTYPE_PARAM, (void *)&datatype, (ub4 *)0, OCI_ATTR_DATA_TYPE,errh)) return OCI_ERROR; typecode = 0; if (OCIAttrGet((void *)attrhd, OCI_DTYPE_PARAM,(void *)&typecode, (ub4 *)0, OCI_ATTR_TYPECODE, errh)) return OCI_ERROR; /* if attribute is an object type, recursively describe it */ if (typecode == OCI_TYPECODE_OBJECT) { OCIRef *attr_type_ref; OCIDescribe *nested_dschp; /* allocate describe handle */ if (OCIHandleAlloc((void *)envh,(void**)&nested_dschp, (ub4)OCI_HTYPE_DESCRIBE,(size_t)0, (void **)0)) return OCI_ERROR; if (OCIAttrGet((void *)attrhd, OCI_DTYPE_PARAM, (void *)&attr_type_ref, (ub4 *)0, OCI_ATTR_REF_TDO,errh)) return OCI_ERROR; OCIDescribeAny(svch, errh,(void*)attr_type_ref, 0, OCI_OTYPE_REF, 0, OCI_PTYPE_TYPE, nested_dschp); /* go on describing the attribute type... */ } } if (dschp) OCIHandleFree((void *) dschp, OCI_HTYPE_DESCRIBE); ...
7.4.4 名前付きコレクション型のコレクション要素のデータ型の取出し
名前付きコレクション型についての明示的な記述の使用方法を示します。
例7-5では、名前付きコレクション型についての明示的な記述の使用方法を示しています。
例7-5 名前付きコレクション型についての明示的な記述の使用
text type_name[] = "phone_list_typ"; ub4 type_name_len = (ub4) strlen((char *)type_name); OCIRef *type_ref = (OCIRef *) 0; ub2 describe_by_name = 1; ub4 num_elements = 0; OCITypeCode typecode = 0, collection_typecode = 0, element_typecode = 0; void *collection_element_parmh = (void *) 0; OCIDescribe *dschp = (OCIDescribe *) 0; /* describe handle */ OCIParam *parmh = (OCIParam *) 0; /* parameter handle */ /* allocate describe handle */ if (OCIHandleAlloc((void *)envh, (void **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (void **)0)) return OCI_ERROR; /* get the describe handle for the type */ if (describe_by_name) { if (OCIDescribeAny(svch, errh, (void *)type_name, type_name_len, OCI_OTYPE_NAME, 0, OCI_PTYPE_TYPE, dschp)) return OCI_ERROR; } else { /* get ref to type using OCIAttrGet */ /* get the describe handle for the type */ if (OCIDescribeAny(svch, errh, (void*)type_ref, 0, OCI_OTYPE_REF, 0, OCI_PTYPE_TYPE, dschp)) return OCI_ERROR; } /* get the parameter handle */ if (OCIAttrGet((void *)dschp, OCI_HTYPE_DESCRIBE, (void *)&parmh, (ub4 *)0, OCI_ATTR_PARAM, errh)) return OCI_ERROR; /* get the Oracle Type System type code of the type to determine that this is a collection type */ typecode = 0; if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM,(void *)&typecode, (ub4 *)0, OCI_ATTR_TYPECODE, errh)) return OCI_ERROR; /* if typecode is OCI_TYPECODE_NAMEDCOLLECTION, proceed to describe collection element */ if (typecode == OCI_TYPECODE_NAMEDCOLLECTION) { /* get the collection's type: OCI_TYPECODE_VARRAY or OCI_TYPECODE_TABLE */ collection_typecode = 0; if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, (void *)&collection_typecode, (ub4 *)0, OCI_ATTR_COLLECTION_TYPECODE, errh)) return OCI_ERROR; /* get the collection element; you MUST use this to further retrieve information about the collection's element */ if (OCIAttrGet((void *)parmh, OCI_DTYPE_PARAM, &collection_element_parmh, (ub4 *)0, OCI_ATTR_COLLECTION_ELEMENT, errh)) return OCI_ERROR; /* get the number of elements if collection is a VARRAY; not valid for nested tables */ if (collection_typecode == OCI_TYPECODE_VARRAY) { if (OCIAttrGet((void *)collection_element_parmh, OCI_DTYPE_PARAM, (void *)&num_elements, (ub4 *)0, OCI_ATTR_NUM_ELEMS, errh)) return OCI_ERROR; } /* now use the collection_element parameter handle to retrieve information about the collection element */ element_typecode = 0; if (OCIAttrGet((void *)collection_element_parmh, OCI_DTYPE_PARAM, (void *)&element_typecode, (ub4 *)0, OCI_ATTR_TYPECODE, errh)) return OCI_ERROR; /* do the same to describe additional collection element information; this is very similar to describing type attributes */ } if (dschp) OCIHandleFree((void *) dschp, OCI_HTYPE_DESCRIBE); ...
7.4.5 文字長セマンティクスを使用した記述
問合せの実行後に、問合せに対応する列名およびデータ型を取り出すループを示します。
例7-6では、問合せの実行後に、問合せに対応する列名およびデータ型を取り出すループを示しています。この問合せは、事前にOCIStmtPrepare2()のコールによって文ハンドルと関連付けられています。
例7-6 データ型、列名および文字長セマンティクスを取り出すためのパラメータ記述子の使用
... OCIParam *mypard = (OCIParam *) 0; ub2 dtype; text *col_name; ub4 counter, col_name_len, char_semantics; ub2 col_width; sb4 parm_status; text *sqlstmt = (text *)"SELECT * FROM employees WHERE employee_id = 100"; checkerr(errhp, OCIStmtPrepare2(svchp, &stmthp, errhp, (OraText *)sqlstmt, (ub4)strlen((char *)sqlstmt), NULL, 0, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)); checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, 0, 0, (OCISnapshot *)0, (OCISnapshot *)0, OCI_DEFAULT)); /* Request a parameter descriptor for position 1 in the select list */ counter = 1; parm_status = OCIParamGet((void *)stmthp, OCI_HTYPE_STMT, errhp, (void **)&mypard, (ub4) counter); /* Loop only if a descriptor was successfully retrieved for current position, starting at 1 */ while (parm_status == OCI_SUCCESS) { /* Retrieve the data type attribute */ checkerr(errhp, OCIAttrGet((void*) mypard, (ub4) OCI_DTYPE_PARAM, (void*) &dtype,(ub4 *) 0, (ub4) OCI_ATTR_DATA_TYPE, (OCIError *) errhp )); /* Retrieve the column name attribute */ col_name_len = 0; checkerr(errhp, OCIAttrGet((void*) mypard, (ub4) OCI_DTYPE_PARAM, (void**) &col_name, (ub4 *) &col_name_len, (ub4) OCI_ATTR_NAME, (OCIError *) errhp )); /* Retrieve the length semantics for the column */ char_semantics = 0; checkerr(errhp, OCIAttrGet((void*) mypard, (ub4) OCI_DTYPE_PARAM, (void*) &char_semantics,(ub4 *) 0, (ub4) OCI_ATTR_CHAR_USED, (OCIError *) errhp )); col_width = 0; if (char_semantics) /* Retrieve the column width in characters */ checkerr(errhp, OCIAttrGet((void*) mypard, (ub4) OCI_DTYPE_PARAM, (void*) &col_width, (ub4 *) 0, (ub4) OCI_ATTR_CHAR_SIZE, (OCIError *) errhp )); else /* Retrieve the column width in bytes */ checkerr(errhp, OCIAttrGet((void*) mypard, (ub4) OCI_DTYPE_PARAM, (void*) &col_width,(ub4 *) 0, (ub4) OCI_ATTR_DATA_SIZE, (OCIError *) errhp )); /* increment counter and get next descriptor, if there is one */ counter++; parm_status = OCIParamGet((void *)stmthp, OCI_HTYPE_STMT, errhp, (void **)&mypard, (ub4) counter); } /* while */ ...
7.4.6 非表示の列かどうかを判別するための各列の記述
非表示の列のプロパティの使用方法、および各列が非表示であるかどうかをチェックする方法を示しています。
次のコード例は、非表示の列のプロパティの使用方法、および各列が非表示であるかどうかをチェックする方法を示しています。詳細は、「列属性」の表のOCI_ATTR_INVISIBLE_COL
属性の説明を参照してください。
例7-7 非表示列のチェック
..... ..... checkerr(errhp, OCIHandleAlloc((dvoid *) envhp, (dvoid **) &dschp, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0)); /* Set the invisible column attribute to get the invisible column(s). */ checkerr(errhp, OCIAttrSet(dschp, OCI_HTYPE_DESCRIBE, &invscols, 0, OCI_ATTR_SHOW_INVISIBLE_COLUMNS, errhp)); if ((retval = OCIDescribeAny(svchp, errhp, (dvoid *)tablename, (ub4) strlen((char *) tablename), OCI_OTYPE_NAME, (ub1)1, OCI_PTYPE_TABLE, dschp)) != OCI_SUCCESS) { if (retval == OCI_NO_DATA) { printf("NO DATA: OCIDescribeAny on %s\n", tablename); } else /* OCI_ERROR */ { printf( "ERROR: OCIDescribeAny on %s\n", tablename); checkerr(errhp, retval); return; } } else { ub1 colIsInv; /* Get the parameter descriptor. */ checkerr (errhp, OCIAttrGet((dvoid *)dschp, (ub4)OCI_HTYPE_DESCRIBE, (dvoid *)&parmp, (ub4 *)0, (ub4)OCI_ATTR_PARAM, (OCIError *)errhp)); /* Get the attributes of the table. */ checkerr (errhp, OCIAttrGet((dvoid*) parmp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &objid, (ub4 *) 0, (ub4) OCI_ATTR_OBJID, (OCIError *)errhp)); /* Get the column list of the table. */ checkerr (errhp, OCIAttrGet((dvoid*) parmp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &collst, (ub4 *) 0, (ub4) OCI_ATTR_LIST_COLUMNS, (OCIError *)errhp)); /* Get the number of columns. */ checkerr (errhp, OCIAttrGet((dvoid*) parmp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &numcols, (ub4 *) 0, (ub4) OCI_ATTR_NUM_COLS, (OCIError *)errhp)); /* Now describe each column to know whether it is a invisible column or not. */ for (pos = 1; pos <= parmcnt; pos++) { /* Get the parameter descriptor for each column. */ checkerr (errhp, OCIParamGet((dvoid *)parmp, (ub4)OCI_DTYPE_PARAM, errhp, (dvoid *)&parmdp, (ub4) pos)); ..... ..... checkerr (errhp, OCIAttrGet((dvoid*) parmdp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &colIsInv, (ub4 *) 0, (ub4) OCI_ATTR_INVISIBLE_COL, (OCIError *)errhp)); ..... ..... } } ..... .....