プライマリ・コンテンツに移動
Oracle® Call Interfaceプログラマーズ・ガイド
12c リリース1 (12.1)
B72465-07
目次へ移動
目次
索引へ移動
索引

前
次

6 スキーマ・メタデータの記述

この章では、OCIDescribeAny()関数を使用して、スキーマ要素に関する情報を取得する方法を説明します。

この章は、次の項目で構成されています。

関連項目:

OCIDescribeAny()

OCIDescribeAny()の使用について

スキーマ・オブジェクトおよびそのサブスキーマ・オブジェクトの明示的記述を実行します。

OCIDescribeAny()関数を使用すると、次のスキーマ・オブジェクトおよびそのサブスキーマ・オブジェクトを明示的に記述できます。

  • 表とビュー

  • シノニム

  • プロシージャ

  • 関数

  • パッケージ

  • 順序

  • コレクション

  • スキーマ

  • データベース

他のスキーマ要素(ファンクションの引数、列、型属性および型メソッド)の情報は、前述のスキーマ・オブジェクトのいずれかの記述、あるいはサブスキーマ・オブジェクトの明示的な記述によって取得できます。

アプリケーションで表を記述する場合は、その表の列の情報も取り出すことができます。さらに、OCIDescribeAny()では、表の列、関数のパッケージ、型のフィールドなどのサブスキーマ・オブジェクトの名前が指定されている場合、それらのサブスキーマ・オブジェクトを直接記述できます。

OCIDescribeAny()コールには、引数の1つとして記述ハンドルが必要です。記述ハンドルは、OCIHandleAlloc()へのコールを使用して、事前に割り当ててください。

図6-1のように、OCIDescribeAny()で戻された情報は、ツリーのように階層的に編成されています。

図6-1 OCIDescribeAny()の表記述

図6-1の説明は次にあります
「図6-1 OCIDescribeAny()の表記述」の説明

OCIDescribeAny()によって戻される記述ハンドルには、このような記述ツリーを指し示す属性OCI_ATTR_PARAMがあります。ツリーの各ノードには、そのノードに関連する属性、および再帰的な記述ハンドルのように詳細情報を含むサブツリーを指し示す属性があります。列リストなどのリスト要素のように、すべての属性が同じ構造である場合、それらの属性をパラメータと呼びます。ノードに関連付けられた属性はOCIAttrGet()によって、パラメータはOCIParamGet()によって戻されます。

表の記述ハンドルについてのOCIAttrGet()に対するコールは、列リストの情報のハンドルを戻します。アプリケーションでは、OCIParamGet()を使用して、列リスト内の特定の列の列記述へのハンドルを取り出します。列記述子へのハンドルをOCIAttrGet()へ受け渡すことによって、名前やデータ型などの列に関する詳細を得ることができます。

SQL文を実行した後、文ハンドルの属性として選択リストに関する情報を取得できます。明示的な記述コールは必要ありません。アプリケーションで文ハンドルから選択リストに関する情報を取り出すには、選択リストの各位置に対してOCIParamGet()を1回ずつコールし、その位置のパラメータ記述子を割り当てる必要があります。

注意:

後続のOCIAttrGet()コールまたはOCIParamGet()コールでは、すべての記述がOCIDescribeAny()によってクライアント側のキャッシュに保存されているので、追加のネットワーク・ラウンドトリップは発生しません。

この項には次のトピックが含まれます:

OCIDescribeAny()に関する制限

OCIDescribeAny()コールは基本情報に戻される情報を制限し、それが別の記述操作になる場合、ノードの拡張を停止します。

たとえば、表の列がオブジェクト型である場合、OCIでは型を記述しているサブツリーを戻しませんが、これはその情報が別の記述によって取得できるからです。

OCIDescribeAny()によって、またはOCIStmtExecute()を暗黙的に使用することでは、表名は戻されません。列が表に関連付けられていないこともあります。ほとんどの場合、この表はすでに認識されています。

型および属性の注意

記述操作を行う際の注意点について説明します。

記述操作を行う際には、次のことに注意する必要があります。

データ型コード

OCI_ATTR_TYPECODEは、CREATE TYPE文を使用して新しい型が作成されたときに、ユーザーが指定した型を表す型コードを戻します。

これらの型コードは、数え上げ可能な型のOCITypeCodeで、OCI_TYPECODE定数で表されます。内部PL/SQL型(ブール)はサポートされません。

OCI_ATTR_DATA_TYPEは、データベースの列に格納されるデータ型を表す型コードを戻します。これらは、Oracle Databaseの以前のバージョンで戻される記述値に似ています。これらの値は、SQLT定数(ub2値)で表されます。ブール型はSQLT_BOLを戻します。

関連項目:

  • SQLT_BOLの詳細は、「外部データ型」を参照してください

  • 型コード(OCI_ATTR_TYPECODE属性に戻されるOCI_TYPECODE値、OCI_ATTR_DATA_TYPE属性に戻されるSQLT型コードなど)の詳細は、「型コード」を参照してください

型の記述について

型オブジェクトを記述するには、OCIプロセスをオブジェクト・モードで初期化する必要があります。

この例を例6-1に示します。

例6-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;
 }

関連項目:

OCIEnvCreate()

暗黙的および明示的記述操作

OCIStmtExecute()による暗黙的記述およびOCIDescribeAny()による明示的記述を使用して、列属性OCI_ATTR_PRECISIONを戻すことができます。

暗黙的記述を使用する場合は、精度をsb2に設定します。明示的記述を使用する場合は、精度をプレースホルダに対してub1に設定します。この設定は、ディクショナリ内の精度のデータ型と一致させるために必要です。

OCI_ATTR_LIST_ARGUMENTS属性

型メソッドのOCI_ATTR_LIST_ARGUMENTS属性は、そのメソッドの2次レベルの引数を表します。

たとえば、次のように、レコードmy_typeと、型my_typeの引数が指定されたプロシージャmy_procを指定するとします。

my_type record(a number, b char)
my_proc (my_input my_type)

この例では、OCI_ATTR_LIST_ARGUMENTS属性は、my_typeレコードの引数abに適用されます。

パラメータ属性

この項では、複数のパラメータに属している属性およびハンドルについて説明します。

パラメータは、OCIParamGet()によって戻されます。パラメータは、複数の型のオブジェクトまたは情報を記述して、そこに含まれる記述の型に応じた属性または型固有の属性を持つことができます。

OCIDescribeAny()では、3つ以上の名前コンポーネント(たとえば、schema.type.attr1.attr2.method1)はサポートされません。コンポーネントが複数である場合、最初のコンポーネントはスキーマ名として解釈されます(他のフラグが設定されていない場合)。フラグの中には、オブジェクトがPUBLIC下で参照されるように指定する、つまり「a」を記述するものがあります(ここで、「a」はカレント・スキーマ内のオブジェクトまたはパブリック・シノニムのいずれか)。

オブジェクト型が何であるかわからない場合は、OCI_PTYPE_UNKを指定してください。そうでない場合、実際のオブジェクト型が指定した型と一致しない場合にはエラーが戻されます。

次の表6-1は、すべてのパラメータの属性のリストです。

表6-1 すべてのパラメータの属性

属性 説明 属性のデータ型

OCI_ATTR_OBJ_ID

オブジェクトIDまたはスキーマID。

ub4

OCI_ATTR_OBJ_NAME

スキーマ内のデータベース名またはオブジェクト名。

OraText *

OCI_ATTR_OBJ_SCHEMA

そのオブジェクトが存在しているスキーマの名前。

OraText *

OCI_ATTR_PTYPE

パラメータによって記述される情報の種類。可能な値は次のとおりです。

OCI_PTYPE_TABLE- 表

OCI_PTYPE_VIEW- ビュー

OCI_PTYPE_PROC- プロシージャ

OCI_PTYPE_FUNC- ファンクション

OCI_PTYPE_PKG- パッケージ

OCI_PTYPE_TYPE - パッケージ型などの型

OCI_PTYPE_TYPE_ATTR- パッケージのレコード型など、型の属性

OCI_PTYPE_TYPE_COLL- パッケージのコレクション要素など、コレクション型の情報

OCI_PTYPE_TYPE_METHOD - 型のメソッド

OCI_PTYPE_SYN- シノニム

OCI_PTYPE_SEQ- 順序

OCI_PTYPE_COL- 表またはビューの列

OCI_PTYPE_ARG- ファンクションまたはプロシージャの引数

OCI_PTYPE_TYPE_ARG- 型メソッドの引数

OCI_PTYPE_TYPE_RESULT - メソッドの結果

OCI_PTYPE_LIST- 表およびビューの列のリスト、ファンクションおよびプロシージャの引数リスト、またはパッケージのサブプログラム・リスト

OCI_PTYPE_SCHEMA- スキーマ

OCI_PTYPE_DATABASE- データベース

OCI_PTYPE_UNK- 不明なスキーマ・オブジェクト

ub1 

OCI_ATTR_TIMESTAMP

Oracle日付書式がその記述の基礎となるオブジェクトのタイムスタンプ。

ub1 *

表またはビューのパラメータ

表6-2では、表またはビュー(OCI_PTYPE_TABLE型またはOCI_PTYPE_VIEW型)のパラメータの型に特有の属性を示しています。

表6-2 表またはビューの属性

属性 説明 属性のデータ型

OCI_ATTR_OBJID

オブジェクトID

ub4

OCI_ATTR_NUM_COLS

列の数。

ub2

OCI_ATTR_LIST_COLUMNS

列リスト(OCI_PTYPE_LIST型)。

OCIParam *

OCI_ATTR_REF_TDO

エクステント表の基本型の型記述オブジェクト(TDO)に対するREF

OCIRef *

OCI_ATTR_IS_TEMPORARY

表が一時表であることを示します。

ub1

OCI_ATTR_IS_TYPED

表に型が指定されていることを示します。

ub1

OCI_ATTR_DURATION

一時表の継続時間。可能な値は次のとおりです。

OCI_DURATION_SESSION- セッション

OCI_DURATION_TRANS- トランザクション

OCI_DURATION_NULL- 非一時表

OCIDuration

表6-3では、表に属する追加属性を示しています。

表6-3 表に特有の属性

属性 説明 属性のデータ型

OCI_ATTR_RDBA

セグメント・ヘッダーのデータ・ブロック・アドレス。

ub4

OCI_ATTR_TABLESPACE

表が存在する表領域

word

OCI_ATTR_CLUSTERED

表がクラスタ化表であることを示します。

ub1

OCI_ATTR_PARTITIONED

表がパーティション表であることを示します。

ub1

OCI_ATTR_INDEX_ONLY

表が索引のみの表であることを示します。

ub1

プロシージャ、ファンクション、サブプログラム属性

プロシージャまたは関数のパラメータの場合の型固有の属性をリストし、説明します。

表6-4では、プロシージャまたはファンクションのパラメータ(OCI_PTYPE_PROC型またはOCI_PTYPE_FUNC型)の場合の型に特有の属性を示しています。

表6-4 プロシージャまたはファンクションの属性

属性 説明 属性のデータ型

OCI_ATTR_LIST_ARGUMENTS

引数リスト。「リスト属性」を参照してください。

void *

OCI_ATTR_IS_INVOKER_RIGHTS

プロシージャまたはファンクションに実行者権限があることを示します。

ub1

表6-5では、パッケージ・サブプログラム用にのみ定義されている属性を示しています。

表6-5 パッケージ・サブプログラムに特有の属性

属性 説明 属性のデータ型

OCI_ATTR_NAME

プロシージャまたはファンクションの名前。

OraText *

OCI_ATTR_OVERLOAD_ID

ID番号のオーバーロード(プロシージャまたはファンクションがパッケージの一部で、オーバーロードされる場合)。戻される値が、PL/SQLファンクションまたはプロシージャの直接問合せとは異なる場合があります。

ub2

パッケージ属性

パッケージのパラメータの場合の属性をリストし、説明します。

表6-6では、パッケージのパラメータ(OCI_PTYPE_PKG型)の場合の属性を示しています。

表6-6 パッケージの属性

属性 説明 属性のデータ型

OCI_ATTR_LIST_PKG_TYPES

OCI_PTYPE_PKGパッケージのパラメータ・ハンドル内のすべての型のリストを取得します。

void *

OCI_ATTR_LIST_SUBPROGRAMS

サブプログラム・リスト。「リスト属性」を参照してください。

void *

OCI_ATTR_IS_INVOKER_RIGHTS

パッケージに実行者権限があることを示します。

ub1

型属性

型のパラメータの場合の属性をリストし、説明します。

表6-7では、型のパラメータ(OCI_PTYPE_TYPE型)の場合の属性を示しています。これらの属性は、OCIEnvCreate()のコールの際に、アプリケーションによってOCI_OBJECTモードでOCIプロセスが初期化された場合にのみ有効です。

表6-7 型の属性

属性 説明 属性のデータ型

OCI_ATTR_REF_TDO

列の型がオブジェクト型の場合は、その型の型記述子オブジェクト(TDO)のインメモリーREFを戻します。OCIRef用の領域が確保されていない場合は、領域がキャッシュ内に暗黙的に割り当てられます。次に、コール元はOCIObjectPin()を使用してTDOを確保できます。

OCIRef *

OCI_ATTR_TYPECODE

型コード。「データ型コード」を参照してください。現在は、OCI_TYPECODE_OBJECTOCI_TYPECODE_NAMEDCOLLECTIONまたはOCI_TYPECODE_RECORDのみが使用できます。

OCITypeCode

OCI_ATTR_COLLECTION_TYPECODE

型がコレクションの場合はコレクションの型コードで、それ以外の場合は無効です。「データ型コード」を参照してください。現在は、OCI_TYPECODE_VARRAYOCI_TYPECODE_TABLEまたはOCI_TYPECODE_ITABLEのみが使用できます。この属性がコレクションでない型に対して問い合せられれば、エラーが発生します。

OCITypeCode

OCI_ATTR_IS_INCOMPLETE_TYPE

不完全な型であることを示します。

ub1

OCI_ATTR_IS_SYSTEM_TYPE

システム型であることを示します。

ub1

OCI_ATTR_IS_PREDEFINED_TYPE

事前定義済の型であることを示します。

ub1

OCI_ATTR_IS_TRANSIENT_TYPE

一時的な型であることを示します。

ub1

OCI_ATTR_IS_SYSTEM_GENERATED_TYPE

システム生成型であることを示します。

ub1

OCI_ATTR_HAS_NESTED_TABLE

ネストした表属性を含む型です。

ub1

OCI_ATTR_HAS_LOB

LOB属性を含む型です。

ub1

OCI_ATTR_HAS_FILE

BFILE属性を含む型です。

ub1

OCI_ATTR_COLLECTION_ELEMENT

コレクション要素へのハンドル。「コレクション属性」を参照してください。

void *

OCI_ATTR_NUM_TYPE_ATTRS

型属性の数。

ub2

OCI_ATTR_LIST_TYPE_ATTRS

型属性のリスト。「リスト属性」を参照してください。

void *

OCI_ATTR_NUM_TYPE_METHODS

型メソッドの数。

ub2

OCI_ATTR_LIST_TYPE_METHODS

型メソッドのリスト。「リスト属性」を参照してください。

void *

OCI_ATTR_MAP_METHOD

型のマップ・メソッド。「型メソッド属性」を参照してください。

void *

OCI_ATTR_ORDER_METHOD

型のオーダー・メソッド。「型メソッド属性」を参照してください。

void *

OCI_ATTR_IS_INVOKER_RIGHTS

型に実行者権限があることを示します。

ub1

OCI_ATTR_NAME

型属性名である文字列へのポインタ。

OraText *

OCI_ATTR_PACKAGE_NAME

属性がパッケージ型の場合、パッケージ名を持つ文字列。

OraText *

OCI_ATTR_SCHEMA_NAME

型作成時のスキーマ名が付いた文字列。

OraText *

OCI_ATTR_IS_FINAL_TYPE

最後の型であることを示します。

ub1

OCI_ATTR_IS_INSTANTIABLE_TYPE

インスタンス化可能な型であることを示します。

ub1

OCI_ATTR_IS_SUBTYPE

サブタイプであることを示します。

ub1

OCI_ATTR_SUPERTYPE_SCHEMA_NAME

スーパータイプを含むスキーマの名前。

OraText *

OCI_ATTR_SUPERTYPE_NAME

スーパータイプの名前。

OraText *

関連項目:

OCIEnvCreate()

型属性の属性

型の属性のパラメータの場合の属性をリストし、説明します。

表6-8では、型の属性のパラメータ(OCI_PTYPE_TYPE_ATTR型)の場合の属性を示しています。

表6-8 型属性の属性

属性 説明 属性のデータ型

OCI_ATTR_DATA_SIZE

型属性の最大サイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。NUMBERについては22を戻します。

ub2

OCI_ATTR_TYPECODE

型コード。「データ型コード」を参照してください。

OCITypeCode

OCI_ATTR_DATA_TYPE

型属性のデータ型。「データ型コード」を参照してください。

ub2

OCI_ATTR_NAME

型属性名である文字列へのポインタ。

OraText *

OCI_ATTR_PRECISION

数値型属性の精度。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

ub1
明示的記述の場合
sb2
暗黙的記述の場合

OCI_ATTR_SCALE

数値型属性のスケール。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

sb1

OCI_ATTR_PACKAGE_NAME

パッケージ型の場合、型のパッケージ名である文字列。

OraText *

OCI_ATTR_TYPE_NAME

型名である文字列。データ型がSQLT_NTYまたはSQLT_REFの場合は、戻される値に型名が含まれます。データ型がSQLT_NTYの場合は、名前付きデータ型の型名が戻されます。データ型がSQLT_REFの場合は、REFによって示されている名前付きデータ型の型名が戻されます。

OraText *

OCI_ATTR_SCHEMA_NAME

型作成時のスキーマ名が付いた文字列。

OraText *

OCI_ATTR_REF_TDO

列の型がオブジェクト型の場合は、その型のTDOのインメモリーREFを戻します。OCIRef用の領域が確保されていない場合は、領域がキャッシュ内に暗黙的に割り当てられます。次に、コール元はOCIObjectPin()を使用してTDOを確保できます。

OCIRef *

OCI_ATTR_CHARSET_ID

型属性が文字列また文字型の場合は、キャラクタ・セットID。

ub2

OCI_ATTR_CHARSET_FORM

型属性が文字列または文字型の場合は、キャラクタ・セット・フォーム。

ub1

OCI_ATTR_FSPRECISION

日時または時間隔の小数秒の精度。

ub1

OCI_ATTR_LFPRECISION

時間隔の先行フィールドの精度。

ub1

型メソッド属性

型のメソッドのパラメータの場合の属性をリストし、説明します。

表6-9では、型のメソッドのパラメータ(OCI_PTYPE_TYPE_METHOD型)の場合の属性を示しています。

表6-9 型メソッドの属性

属性 説明 属性のデータ型

OCI_ATTR_NAME

メソッド名(プロシージャまたはファンクション)。

OraText *

OCI_ATTR_ENCAPSULATION

メソッドのカプセル化レベル(OCI_TYPEENCAP_PRIVATEまたはOCI_TYPEENCAP_PUBLICのいずれか)。

OCITypeEncap

OCI_ATTR_LIST_ARGUMENTS

引数リスト。「OCI_ATTR_LIST_ARGUMENTS属性」および「リスト属性」を参照してください。

void *

OCI_ATTR_IS_CONSTRUCTOR

メソッドがコンストラクタであることを示します。

ub1

OCI_ATTR_IS_DESTRUCTOR

メソッドがデストラクタであることを示します。

ub1

OCI_ATTR_IS_OPERATOR

メソッドが演算子であることを示します。

ub1

OCI_ATTR_IS_SELFISH

メソッドが自己参照的であることを示します。

ub1

OCI_ATTR_IS_MAP

メソッドがマップ・メソッドであることを示します。

ub1

OCI_ATTR_IS_ORDER

メソッドがオーダー・メソッドであることを示します。

ub1

OCI_ATTR_IS_RNDS

「Read No Data State」がメソッドに設定されていることを示します。

ub1

OCI_ATTR_IS_RNPS

「Read No Process State」がメソッドに設定されていることを示します。

ub1

OCI_ATTR_IS_WNDS

「Write No Data State」がメソッドに設定されていることを示します。

ub1

OCI_ATTR_IS_WNPS

「Write No Process State」がメソッドに設定されていることを示します。

ub1

OCI_ATTR_IS_FINAL_METHOD

最後のメソッドであることを示します。

ub1

OCI_ATTR_IS_INSTANTIABLE_METHOD

インスタンス化可能なメソッドであることを示します。

ub1

OCI_ATTR_IS_OVERRIDING_METHOD

オーバーライドするメソッドであることを示します。

ub1

コレクション属性

コレクション型のパラメータの場合の属性をリストし、説明します。

表6-10では、コレクション型のパラメータ(OCI_PTYPE_COLL型)の場合の属性を示しています。

表6-10 コレクション型の属性

属性 説明 属性のデータ型

OCI_ATTR_DATA_SIZE

型属性の最大サイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。NUMBERについては22を戻します。

ub2

OCI_ATTR_TYPECODE

型コード。「データ型コード」を参照してください。

OCITypeCode

OCI_ATTR_DATA_TYPE

型属性のデータ型。「データ型コード」を参照してください。

ub2

OCI_ATTR_NUM_ELEMS

配列の要素の数。コレクションが配列である場合にのみ有効です。

ub4

OCI_ATTR_NAME

型属性名である文字列へのポインタ。

OraText *

OCI_ATTR_PRECISION

数値型属性の精度。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

ub1

明示的記述の場合

sb2

暗黙的記述の場合

OCI_ATTR_SCALE

数値型属性のスケール。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

sb1

OCI_ATTR_PACKAGE_NAME

パッケージ型の場合、型のパッケージ名である文字列。

OraText *

OCI_ATTR_TYPE_NAME

型名である文字列。データ型がSQLT_NTYまたはSQLT_REFの場合は、戻される値に型名が含まれます。データ型がSQLT_NTYの場合は、名前付きデータ型の型名が戻されます。データ型がSQLT_REFの場合は、REFによって示されている名前付きデータ型の型名が戻されます。

OraText *

OCI_ATTR_SCHEMA_NAME

型作成時のスキーマ名が付いた文字列。

OraText *

OCI_ATTR_REF_TDO

列の型がオブジェクト型の場合は、その型の型記述子オブジェクト(TDO)のインメモリーREFを戻します。OCIRef用の領域が確保されていない場合は、領域がキャッシュ内に暗黙的に割り当てられます。次に、コール元はOCIObjectPin()を使用してTDOを確保できます。

OCIRef *

OCI_ATTR_CHARSET_ID

型属性が文字列また文字型の場合は、キャラクタ・セットID。

ub2

OCI_ATTR_CHARSET_FORM

型属性が文字列または文字型の場合は、キャラクタ・セット・フォーム。

ub1

シノニム属性

シノニムのパラメータの場合の属性をリストし、説明します。

表6-11では、シノニムのパラメータ(OCI_PTYPE_SYN型)の場合の属性を示しています。

表6-11 シノニムの属性

属性 説明 属性のデータ型

OCI_ATTR_OBJID

オブジェクトID

ub4

OCI_ATTR_SCHEMA_NAME

シノニム翻訳のスキーマ名を含む文字列。

OraText *

OCI_ATTR_NAME

シノニム翻訳のオブジェクト名を含む、NULLで終了する文字列。

OraText *

OCI_ATTR_LINK

シノニム翻訳のデータベース・リンク名を含む、NULLで終了する文字列。

OraText *

順序属性

順序のパラメータの場合の属性をリストし、説明します。

表6-12では、順序のパラメータ(OCI_PTYPE_SEQ型)の場合の属性を示しています。

表6-12 順序の属性

属性 説明 属性のデータ型

OCI_ATTR_OBJID

オブジェクトID

ub4

OCI_ATTR_MIN

最小値(Oracle NUMBER書式)。

ub1

OCI_ATTR_MAX

最大値(Oracle NUMBER書式)。

ub1

OCI_ATTR_INCR

増分(Oracle NUMBER書式)。

ub1

OCI_ATTR_CACHE

キャッシュされた順序番号の数。順序がキャッシュされた順序でない場合は、0 (ゼロ)です(Oracle NUMBER書式)。

ub1

OCI_ATTR_ORDER

順序が順序指定されているかどうか。

ub1

OCI_ATTR_HW_MARK

最高水位標(NUMBER書式)。

ub1

関連項目:

OCINumberの例

列属性

注意:

BINARY_FLOATおよびBINARY_DOUBLEの場合:

OCIDescribeAny()を使用して、表のBINARY_FLOAT列またはBINARY_DOUBLE列の列データ型(OCI_ATTR_DATA_TYPE)を取り出す場合は、内部データ型コードが戻されます。

BINARY_FLOATおよびBINARY_DOUBLEの内部データ型コードに対応するSQLTコードは、SQLT_IBFLOATおよびSQLT_IBDOUBLEです。

表6-13では、表またはビューの列のパラメータ(OCI_PTYPE_COL型)の場合の属性を示しています。

表6-13 表またはビューの列の属性

属性 説明 属性のデータ型

OCI_ATTR_CHAR_USED

列の長さセマンティクスの型を戻します。0 (ゼロ)はバイト長セマンティクスを示し、1は文字長セマンティクスを示します。「記述操作での文字長セマンティクスのサポート」を参照してください。

ub1

OCI_ATTR_CHAR_SIZE

列の文字長、つまり列内で使用可能な文字数を戻します。これはOCI_ATTR_DATA_SIZEに相当するもので、バイト長で使用します。「記述操作での文字長セマンティクスのサポート」を参照してください。

ub2

OCI_ATTR_COLUMN_ PROPERTIES

特定の列のプロパティに関する記述データが戻されます。OCI_ATTR_COLUMN_PROPERTIESで使用可能なフラグを次に示します。

  • OCI_ATTR_COLUMN_PROPERTY_IS_IDENTITY

  • OCI_ATTR_COLUMN_PROPERTY_IS_GEN_ALWAYS

    • 1はALWAYS GENERATEDであることを示します。

    • 0はGENERATED BY DEFAULTを示します。

  • OCI_ATTR_COLUMN_PROPERTY_IS_GEN_BY_DEF_ON_NULL

使用例を次に示します。

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

CREATE TABLE文内の列の定義用の識別句でこれらのプロパティを指定するSQL構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

ub8

OCI_ATTR_INVISIBLE_COL

この属性では、列が非表示であるかどうかが戻されます。TRUEは列が非表示列であることを示し、そうでない場合はFALSEが戻されます。例は、「非表示の列かどうかを判別するための各列の記述」を参照してください。

ub1 *

OCI_ATTR_DATA_SIZE

列の最大サイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。NUMBERについては22を戻します。

ub2

OCI_ATTR_DATA_TYPE

列のデータ型。「データ型コード」を参照してください。

ub2

OCI_ATTR_NAME

列名である文字列へのポインタ。

OraText *

OCI_ATTR_PRECISION

数値列の精度。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

ub1 for explicit describe
sb2 for implicit describe

OCI_ATTR_SCALE

数値列のスケール。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

sb1

OCI_ATTR_IS_NULL

列にNULL値が許可されていない場合に、0 (ゼロ)を戻します。CUBEまたはROLLUP操作に対する正しい値を戻しません。

ub1

OCI_ATTR_TYPE_NAME

型名である文字列を戻します。データ型がSQLT_NTYまたはSQLT_REFの場合は、戻される値に型名が含まれます。データ型がSQLT_NTYの場合は、名前付きデータ型の型名が戻されます。データ型がSQLT_REFの場合は、REFによって示されている名前付きデータ型の型名が戻されます。

OraText *

OCI_ATTR_SCHEMA_NAME

型の作成時に使用したスキーマ名を持つ文字列を戻します。

OraText *

OCI_ATTR_REF_TDO

列の型がオブジェクト型の場合は、その型のTDOのREF

OCIRef *

OCI_ATTR_CHARSET_ID

列が文字列または文字型の場合は、キャラクタ・セットID。

ub2

OCI_ATTR_CHARSET_FORM

列が文字列または文字型の場合は、キャラクタ・セット・フォーム。

ub1

引数および結果の属性

プロシージャまたは関数の引数のパラメータの場合の属性をリストし、説明します。

表6-14では、プロシージャやファンクションの引数のパラメータ(OCI_PTYPE_ARG型)、型メソッド引数のパラメータ(OCI_PTYPE_TYPE_ARG型)またはメソッド結果のパラメータ(OCI_PTYPE_TYPE_RESULT型)の場合の属性を示しています。

表6-14 引数および結果の属性

属性 説明 属性のデータ型

OCI_ATTR_NAME

引数名である文字列へのポインタを戻します。

OraText *

OCI_ATTR_POSITION

引数リストの引数の位置。常に0 (ゼロ)を戻します。

ub2

OCI_ATTR_TYPECODE

型コード。「データ型コード」を参照してください。

OCITypeCode

OCI_ATTR_DATA_TYPE

引数のデータ型。「データ型コード」を参照してください。

ub2

OCI_ATTR_DATA_SIZE

引数のデータ型のサイズ。この長さは、文字列と行について、文字ではなくバイト単位で戻されます。NUMBERについては22を戻します。

ub2

OCI_ATTR_PRECISION

数値引数の精度。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

明示的記述の場合はsb1

暗黙的記述の場合はsb2

OCI_ATTR_SCALE

数値引数のスケール。精度が0 (ゼロ)以外でスケールが-127の場合はFLOATで、それ以外の場合はNUMBER(precision, scale)です。精度が0 (ゼロ)の場合は、NUMBER(precision, scale)を単にNUMBERと表すことができます。

sb1

OCI_ATTR_LEVEL

データ型のレベル。この属性は常に0 (ゼロ)を戻します。

ub2

OCI_ATTR_HAS_DEFAULT

引数にデフォルト値があるかどうかを示します。

ub1

OCI_ATTR_LIST_ARGUMENTS

次のレベルの引数のリスト(引数がレコード型または表型のとき)。

void *

OCI_ATTR_IOMODE

次の引数モードを示します。

0はIN (OCI_TYPEPARAM_IN)

1はOUT (OCI_TYPEPARAM_OUT)

2はIN/OUT (OCI_TYPEPARAM_INOUT)

OCITypeParamMode

OCI_ATTR_RADIX

基数を戻します(数値型の場合)。

ub1

OCI_ATTR_IS_NULL

列にNULL値が許可されていない場合に、0 (ゼロ)を戻します。

ub1

OCI_ATTR_TYPE_NAME

パッケージのローカル型の場合は、型名またはパッケージ名の文字列を戻します。データ型がSQLT_NTYまたはSQLT_REFの場合は、戻される値に型名が含まれます。データ型がSQLT_NTYの場合は、名前付きデータ型の型名が戻されます。データ型がSQLT_REFの場合は、REFによって示されている名前付きデータ型の型名が戻されます。

OraText *

OCI_ATTR_SCHEMA_NAME

SQLT_NTYまたはSQLT_REFについては、型の作成時、またはパッケージ・ローカル型用のパッケージの作成時に使用したスキーマ名を持つ文字列を戻します。

OraText *

OCI_ATTR_SUB_NAME

SQLT_NTYまたはSQLT_REFの場合、パッケージ・ローカル型にはタイプ名を持つ文字列を戻します。

OraText *

OCI_ATTR_LINK

SQLT_NTYまたはSQLT_REFについては、型が存在しているデータベースのデータベース・リンク名を持つ文字列を戻します。これは、パッケージがリモートで、そのパッケージがローカル型の場合にのみ発生します。

OraText *

OCI_ATTR_REF_TDO

引数型がオブジェクトの場合は、その型の型記述子オブジェクト(TDO)のREFを戻します。

OCIRef *

OCI_ATTR_CHARSET_ID

引数が文字列または文字型の場合は、キャラクタ・セットIDを戻します。

ub2

OCI_ATTR_CHARSET_FORM

引数が文字列または文字型の場合は、キャラクタ・セット・フォームを戻します。

ub1

リスト属性

列、引数、サブプログラムまたはパッケージ・レコード型のフィールドのリストのパラメータの場合の属性をリストし、説明します。

列、引数、サブプログラムまたはパッケージ・レコード型のフィールドのリストのパラメータ(OCI_PTYPE_LIST型)の場合、表6-15に示すような型に特有の属性およびハンドル(パラメータ)があります。

リストには、リスト型を指定するOCI_ATTR_LTYPE属性があります。表6-15では、リストの横断時に予想される値とその下限を示しています。

表6-15 リスト属性

リスト属性 説明 下限

OCI_LTYPE_COLUMN

列リスト。

1

OCI_LTYPE_ARG_PROC

プロシージャ引数リスト。

1

OCI_LTYPE_ARG_FUNC

ファンクション引数リスト。

0

OCI_LTYPE_SUBPRG

サブプログラム・リスト。

0

OCI_LTYPE_TYPE_ATTR

型属性リスト。

1

OCI_LTYPE_TYPE_METHOD

型メソッド・リスト。

1

OCI_LTYPE_TYPE_ARG_PROC

結果引数なしの型メソッド・リスト。

0

OCI_LTYPE_TYPE_ARG_FUNC

結果引数なしの型メソッド・リスト。

1

OCI_LTYPE_SCH_OBJ

スキーマ内のオブジェクト・リスト。

0

OCI_LTYPE_DB_SCH

データベース内のスキーマ・リスト。

0

リストには、リスト内の要素数を調べるOCI_ATTR_NUM_PARAMS属性があります。

各リストには、LowerBound ... OCI_ATTR_NUM_PARAMSパラメータがあります。LowerBoundは、表6-15の「下限」列の値です。ファンクション引数リストの場合、位置0には、戻り値(OCI_PTYPE_ARG型)のパラメータがあります。

スキーマ属性

スキーマ型のパラメータの場合の属性をリストし、説明します。

表6-16では、スキーマ型のパラメータ(OCI_PTYPE_SCHEMA型)の場合の属性を示しています。

表6-16 スキーマ固有の属性

属性 説明 属性のデータ型

OCI_ATTR_LIST_OBJECTS

スキーマ内のオブジェクトのリスト。

OCIParam *

データベース属性

データベース型のパラメータの場合の属性をリストし、説明します。

表6-17では、データ型のパラメータ(OCI_PTYPE_DATABASE型)の場合の属性を示しています。

表6-17 データベース固有の属性

属性 説明 属性のデータ型

OCI_ATTR_VERSION

データベースのバージョン。

OraText *

OCI_ATTR_CHARSET_ID

サーバー・ハンドルからのデータベース・キャラクタ・セットID。

ub2

OCI_ATTR_NCHARSET_ID

サーバー・ハンドルからのデータベース各国語キャラクタ・セットID。

ub2

OCI_ATTR_LIST_SCHEMAS

データベース内のスキーマのリスト(OCI_PTYPE_SCHEMA型)。

ub1

OCI_ATTR_MAX_PROC_LEN

プロシージャ名の最大長。

ub4

OCI_ATTR_MAX_COLUMN_LEN

列名の最大長。

ub4

OCI_ATTR_CURSOR_COMMIT_BEHAVIOR

COMMIT操作によりデータベース内のカーソルおよびプリペアド文が受ける影響。値は次のとおりです。

OCI_CURSOR_OPEN: カーソルの状態をCOMMIT操作の前の状態に保持します。

OCI_CURSOR_CLOSED: カーソルは、COMMITでにクローズされますが、アプリケーションでは、文を再度プリコンパイルせずに再実行できます。

ub1

OCI_ATTR_MAX_CATALOG_NAMELEN

カタログ(データベース)名の最大長。

ub1

OCI_ATTR_CATALOG_LOCATION

修飾表内のカタログの位置。値はOCI_CL_STARTおよびOCI_CL_ENDです。

ub1

OCI_ATTR_SAVEPOINT_SUPPORT

データベースがセーブポイントをサポートするかどうか。値はOCI_SP_SUPPORTEDおよびOCI_SP_UNSUPPORTEDです。

ub1

OCI_ATTR_NOWAIT_SUPPORT

データベースがNOWAIT句をサポートするかどうか。値はOCI_NW_SUPPORTEDおよびOCI_NW_UNSUPPORTEDです。

ub1

OCI_ATTR_AUTOCOMMIT_DDL

DDL文で自動コミット・モードが必要かどうか。値はOCI_AC_DDLおよびOCI_NO_AC_DDLです。

ub1

OCI_ATTR_LOCKING_MODE

データベースのロック・モード。値はOCI_LOCK_IMMEDIATEおよびOCI_LOCK_DELAYEDです。

ub1

ルール属性

ルールのパラメータの場合の属性をリストし、説明します。

表6-18では、ルールのパラメータ(OCI_PTYPE_RULE型)の場合の属性を示しています。

表6-18 ルールに特有の属性

属性 説明 属性のデータ型

OCI_ATTR_CONDITION

ルール条件。

OraText *

OCI_ATTR_EVAL_CONTEXT_OWNER

ルールに関連する評価コンテキストの所有者名(ある場合)。

OraText *

OCI_ATTR_EVAL_CONTEXT_NAME

ルールに関連する評価コンテキストのオブジェクト名(ある場合)。

OraText *

OCI_ATTR_COMMENT

ルールに関連するコメント(ある場合)。

OraText *

OCI_ATTR_LIST_ACTION_CONTEXT

処理コンテキストの名前/値ペアのリスト(OCI_PTYPE_LIST型)。

void *

ルール・セット属性

ルール・セットのパラメータの場合の属性をリストし、説明します。

表6-19では、ルール・セットのパラメータ(OCI_PTYPE_RULE_SET型)の場合の属性を示しています。

表6-19 ルール・セットに特有の属性

属性 説明 属性のデータ型

OCI_ATTR_EVAL_CONTEXT_OWNER

ルール・セットに関連する評価コンテキストの所有者名(ある場合)。

OraText *

OCI_ATTR_EVAL_CONTEXT_NAME

ルール・セットに関連する評価コンテキストのオブジェクト名(ある場合)。

OraText *

OCI_ATTR_COMMENT

ルール・セットに関連するコメント(ある場合)。

OraText *

OCI_ATTR_LIST_RULES

ルール・セットのルールのリスト(OCI_PTYPE_LIST型)。

void *

評価コンテキスト属性

評価コンテキストのパラメータの場合の属性をリストし、説明します。

表6-20では、評価コンテキストのパラメータ(OCI_PTYPE_EVALUATION_CONTEXT型)の場合の属性を示しています。

表6-20 評価コンテキストに特有の属性

属性 説明 属性のデータ型

OCI_ATTR_EVALUATION_FUNCTION

評価コンテキストに関連する評価ファンクション(ある場合)。

OraText *

OCI_ATTR_COMMENT

評価コンテキストに関連するコメント(ある場合)。

OraText *

OCI_ATTR_LIST_TABLE_ALIASES

評価コンテキストの表別名のリスト(OCI_PTYPE_LIST型)。

void *

OCI_ATTR_LIST_VARIABLE_TYPES

評価コンテキストの変数型のリスト(OCI_PTYPE_LIST型)。

void *

表別名の属性

表別名のパラメータの場合の属性をリストし、説明します。

表6-21では、表別名のパラメータ(OCI_PTYPE_TABLE_ALIAS型)の場合の属性を示しています。

表6-21 表別名に特有の属性

属性 説明 属性のデータ型

OCI_ATTR_NAME

表別名。

OraText *

OCI_ATTR_TABLE_NAME

別名に関連する表名。

OraText *

変数型の属性

変数のパラメータの場合の属性をリストし、説明します。

表6-22では、変数のパラメータ(OCI_PTYPE_VARIABLE_TYPE型)の場合の属性を示しています。

表6-22 変数型に特有の属性

属性 説明 属性のデータ型

OCI_ATTR_NAME

変数名。

OraText *

OCI_ATTR_TYPE

変数型。

OraText *

OCI_ATTR_VAR_VALUE_FUNCTION

変数に関連する変数値ファンクション(ある場合)。

OraText *

OCI_ATTR_VAR_METHOD_FUNCTION

変数に関連する変数メソッド・ファンクション(ある場合)。

OraText *

名前/値の属性

名前/値ペアのパラメータの場合の属性をリストし、説明します。

表6-23では、名前/値ペアのパラメータ(OCI_PTYPE_NAME_VALUE型)の場合の属性を示しています。

表6-23 名前/値ペアに特有の属性

属性 説明 属性のデータ型

OCI_ATTR_NAME

名前。

OraText *

OCI_ATTR_VALUE

OCIAnyData*

記述操作での文字長セマンティクスのサポート

問合せ情報と列情報は、文字長セマンティクスでサポートされます。

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()を使用して明示的に記述する必要があります。

この項には次のトピックが含まれます:

暗黙的記述

データベース列が文字長セマンティクスを使用して作成されている場合、暗黙的な記述情報には、文字長、バイト長、およびデータベース列の作成方法を示すフラグが含まれます。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と同じ値に設定されます。

明示的記述

表の明示的記述には、OCI_ATTR_DATA_SIZEOCI_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によって戻される値に設定できます。これにより、列のサイズ制限に違反することを防ぎます。

この項には次のトピックが含まれます。「記述に関するクライアントとサーバー間の互換性の問題」

関連項目:

INバインド

記述に関するクライアントとサーバー間の互換性の問題

文字長セマンティクスはサーバーまたはクライアントのリリースに依存します。記述には、サーバーとクライアントの両方をOracle9i以上にすることをお薦めします。そうしないと、次に説明するような互換性の問題が発生します。

Oracle9i 以上のクライアントがOracle8i 以下のサーバーと通信を行うと、そのクライアントは、データベースがバイト長セマンティクスのみを使用しているかのように動作します。

Oracle8i 以下のクライアントがOracle9i 以上のサーバーと通信を行うと、クライアント側でOCI_ATTR_CHAR_SIZE属性とOCI_ATTR_CHAR_USED属性を使用することはできません。

いずれの場合も、サーバーまたはクライアントがOracle8i 以下のソフトウェア・リリースである場合、文字長セマンティクスは記述できません。

OCIDescribeAny()の使用例

次の例では、異なる種類のスキーマ・オブジェクトを記述するためのOCIDescribeAny()の使用方法を示します。

より詳細なコード例は、Oracle Databaseのインストールに含まれているデモ・プログラムcdemodsa.cを参照してください。

関連項目:

表用の列データ型の取出し

例6-2では、表の列データ型を取り出す明示的な記述の使用方法を示しています。

例6-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);
...

ストアド・プロシージャの記述

プロシージャとファンクションの違いは、ファンクションには引数リストに位置0 (ゼロ)の戻り型がありますが、プロシージャには、引数リストの位置0 (ゼロ)に対応する引数がないことです。型メソッドの記述に必要なステップ(ファンクションとプロシージャへの分割も行います)は、通常のPL/SQLファンクションおよびプロシージャのステップとまったく同じです。プロシージャおよびファンクションは、オブジェクトのデフォルト型を引数として使用できることに注意してください。次のプロシージャで考えてみます。

P1 (arg1 emp.sal%type, arg2 emp%rowtype)

例6-3では、emp表の各行には、name(VARCHAR2(20))およびsal(NUMBER)の2列があると想定します。P1の引数リストには、arg1arg2の2つの引数がそれぞれレベル0 (ゼロ)の位置1と位置2にあり、引数のnamesalがそれぞれレベル1の位置1と位置2にあります。P1の記述では、引数の数を2として戻し、レベル0 (ゼロ)を超える(> 0)引数を、レベル0 (ゼロ)の引数の属性として戻します。

例6-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);
...

オブジェクト型の属性の取出し

例6-4では、名前付きオブジェクト型についての明示的な記述の使用方法を示しています。オブジェクトを名前またはオブジェクト参照(OCIRef)によって記述する方法を説明します。次のコード・フラグメントによって、オブジェクト型の属性について各データ型値の取出しが試みられます。

例6-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);
...

名前付きコレクション型のコレクション要素のデータ型の取出し

例6-5では、名前付きコレクション型についての明示的な記述の使用方法を示しています。

例6-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);
...

文字長セマンティクスを使用した記述

問合せの実行後に、問合せに対応する列名およびデータ型を取り出すループを示します。

例6-6では、問合せの実行後に、問合せに対応する列名およびデータ型を取り出すループを示しています。この問合せは、事前にOCIStmtPrepare2()のコールによって文ハンドルと関連付けられています。

例6-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 */
...

非表示の列かどうかを判別するための各列の記述

非表示の列のプロパティの使用方法、および各列が非表示であるかどうかをチェックする方法を示しています。

次のコード例は、非表示の列のプロパティの使用方法、および各列が非表示であるかどうかをチェックする方法を示しています。詳細は、「列属性」の表にあるOCI_ATTR_INVISIBLE_COL属性の説明を参照してください。

例6-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));
 
       .....
       .....
 
       }
 
   }
    .....
    .....