360
Oracle8 コール・インタフェース プログラマーズ・ガイド : Vol.1 リリース 8.0 1998 3 部品番号 A56834-1

Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8コール・インタフェース

プログラマーズ・ガイド : Vol.1

リリース 8.0

1998 年 3 月

部品番号 A56834-1

Page 2: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 コール・インタフェース プログラマーズ・ガイド : Vol.1、リリース 8.0

部品番号 A56834-1

原本名 : Oracle Call Interface Programmer’s Guide, Volume 1, Release 8.0

原本部品番号 : A58235-01

Copyright © 1997, Oracle Corporation. All rights reserved.

原本著者 : Phil Locke

原本協力者 : John Bellemore, John Boonleungtomnu, Sashi Chandrasekaran, Debashish Chatterjee, Ernest Chen, Calvin Cheng, Luxi Chidambaran, Diana Foch-Lorentz, Sreenivas Gollapudi, Brajesh Goyal, Radhakrishna Hari, Don Herkimer, Amit Jasuja, Sanjay Kaluskar, Kai Korot, Susan Kotsovolos, Srinath Krishnaswamy, Ramkumar Krishnan, Sanjeev Kumar, Thomas Kurian, Paul Lane, Shoaib Lari, Chon Lei, Nancy Liu, Valarie Moore, Tin Nguyen, Denise Oertel, Rosanne Park, Jacqui Pons, Den Raphaely, Anindo Roy, Tim Smith, Ekrem Soylemez, Ashwini Surpur, Sudheer Thakur, Alan Thiessen, Peter Vasterd, Randall Whitman, Joyo Wijaya, Allen Zhao

All rights reserved.

Printed in Japan.

制限付権利の説明

プログラムの使用、複製、または開示は、オラクル社との契約に記された制限条件に従うものとします。

本書の情報は、予告なしに変更されることがあります。本書に問題を見つけたら、当社にコメントをお送りください。オラクル社は、本書の無謬性を保証しません。

危険な用途への使用について

当社製品は、原子力、航空産業、大量輸送、または医療の分野など、本質的に危険を伴うアプリケーションを用途として特に開発されておりません。当社製品を上述のような危険なアプリケーションに使用することについての安全確保は顧客各位の責任と費用により行っていただきたく、万一かかる用途での使用によりクレームや損害が発生いたしましても、当社および開発元である米国 Oracle Corporation(その関連会社も含みます。)は一切責任を負いかねます。

ORACLEは、Oracle Corporationの登録商標です。

本文中の他社の商品名は、それぞれ各社の商標または登録商標です。

Page 3: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

iii

目次

はじめに ................................................................................................................................................................................... xxv

このマニュアルの目的 .......................................................................... xxvi

このマニュアルの対象 .......................................................................... xxvi

サポートされている機能とその可用性........................................................... xxvii

このマニュアルの使い方 ....................................................................... xxvii

Vol.1 ........................................................................................................................................................................... xxvii

Vol.2 ........................................................................................................................................................................... xxvii

このマニュアルの読み方 ....................................................................................................................................... xxviii

このマニュアルの構成 ......................................................................... xxviii

Vol.1 .......................................................................................................................................................................... xxviii

Vol.2 ............................................................................................................................................................................ xxix

このマニュアルの表記規則 ...................................................................... xxx

第 1部 OCIの基本概念

1 概要および新機能Oracleコール・インタフェース.................................................................. 1-2

SQL文........................................................................................ 1-4

データ定義言語 (DDL) .............................................................................................................................................. 1-4

制御文 .......................................................................................................................................................................... 1-5

データ操作言語 (DML) ............................................................................................................................................. 1-5

問合せ .......................................................................................................................................................................... 1-5

PL/SQL ....................................................................................................................................................................... 1-6

埋込み SQL.................................................................................................................................................................. 1-7

OCI/SQLの特殊用語 ........................................................................... 1-7

OCIでのオブジェクト・サポート................................................................ 1-8

Page 4: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

iv

OCIの分類 ................................................................................... 1-10

リリース 8.0の新機能 .......................................................................... 1-10

使用されなくなった、または廃止された OCIコール............................................... 1-11

コンパイルおよびリンク ....................................................................... 1-11

2 OCIプログラミングの基本概要 .......................................................................................... 2-2

OCIプログラム構造 ............................................................................ 2-2

OCIデータ構造 ................................................................................ 2-4

ハンドル ...................................................................................... 2-5

ハンドルの割当てと解放 .......................................................................................................................................... 2-5

環境ハンドル .............................................................................................................................................................. 2-7

エラー・ハンドル ...................................................................................................................................................... 2-7

サービス・コンテキスト・ハンドルとそれに対応付けられたハンドル .......................................................... 2-7

文ハンドルおよびバインド・ハンドル、定義ハンドル ...................................................................................... 2-9

記述ハンドル .............................................................................................................................................................. 2-9

複合オブジェクト検索ハンドル .............................................................................................................................. 2-9

セキュリティ・ハンドル .......................................................................................................................................... 2-9

ハンドル属性 .............................................................................................................................................................. 2-9

ユーザー・メモリの割当て .................................................................................................................................... 2-11

記述子およびロケータ ......................................................................... 2-11

スナップショット記述子 ........................................................................................................................................ 2-12

LOB/FILEデータ型ロケータ ................................................................................................................................ 2-12

パラメータ記述子 .................................................................................................................................................... 2-13

ROWID記述子......................................................................................................................................................... 2-13

複合オブジェクト記述子 ........................................................................................................................................ 2-13

アドバンスト・キューイング記述子 .................................................................................................................... 2-14

ユーザー・メモリーの割当て ................................................................................................................................ 2-14

OCIプログラミング・ステップ ................................................................. 2-14

初期化および接続、セッション作成 ............................................................. 2-16

OCIプロセスの初期化 ........................................................................................................................................... 2-16

ハンドルおよび記述子の割当て ............................................................................................................................ 2-17

アプリケーションの初期化および接続、セッション作成 ................................................................................ 2-17

複数の接続とハンドルの説明 ................................................................... 2-20

接続の例 .................................................................................................................................................................... 2-20

SQL文の処理................................................................................. 2-22

コミットまたはロールバック ................................................................... 2-22

Page 5: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

v

アプリケーションの終了 ....................................................................... 2-22

エラー処理 ................................................................................... 2-24

他の値を戻す関数 .................................................................................................................................................... 2-26

その他のコーディング・ガイドライン ........................................................... 2-26

パラメータの型 ........................................................................................................................................................ 2-26

Null ............................................................................................................................................................................ 2-27

標識変数 .................................................................................................................................................................... 2-28

コールの取消し ........................................................................................................................................................ 2-29

位置づけ更新および位置づけ削除 ........................................................................................................................ 2-30

アプリケーションのリンク .................................................................................................................................... 2-30

OCIプログラムでの PL/SQL使用............................................................... 2-30

3 データ型Oracleデータ型................................................................................ 3-2

内部のデータ型コード .............................................................................................................................................. 3-4

外部データ型コード .................................................................................................................................................. 3-4

内部データ型 .................................................................................. 3-4

LONG、RAW、LONG RAW、VARCHAR2 ....................................................................................................... 3-5

文字列およびバイト配列 .......................................................................................................................................... 3-6

外部データ型 .................................................................................. 3-7

VARCHAR2................................................................................................................................................................ 3-9

NUMBER................................................................................................................................................................... 3-10

INTEGER................................................................................................................................................................... 3-10

FLOAT ....................................................................................................................................................................... 3-11

STRING ..................................................................................................................................................................... 3-12

VARNUM ................................................................................................................................................................. 3-13

LONG ........................................................................................................................................................................ 3-13

VARCHAR................................................................................................................................................................ 3-13

ROWID ...................................................................................................................................................................... 3-13

DATE ......................................................................................................................................................................... 3-14

RAW........................................................................................................................................................................... 3-15

VARRAW.................................................................................................................................................................. 3-15

LONG RAW.............................................................................................................................................................. 3-15

UNSIGNED............................................................................................................................................................... 3-15

LONG VARCHAR................................................................................................................................................... 3-15

LONG VARRAW..................................................................................................................................................... 3-16

Page 6: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

vi

CHAR........................................................................................................................................................................ 3-16

CHARZ ..................................................................................................................................................................... 3-17

MLSLABEL............................................................................................................................................................... 3-17

新しい OCI 8.0外部データ型.................................................................... 3-17

NAMED DATA TYPE ............................................................................................................................................ 3-18

REF ............................................................................................................................................................................ 3-19

LOB............................................................................................................................................................................ 3-19

新しい Cデータ型マップ ....................................................................................................................................... 3-21

データ変換 ................................................................................... 3-21

型コード ..................................................................................... 3-23

SQLT値および OCI_TYPECODE値の関係 ........................................................................................................ 3-24

oratypes.hの定義 ............................................................................. 3-26

4 SQL文の処理概要 .......................................................................................... 4-2

SQL文の処理.................................................................................. 4-2

文の準備 ...................................................................................... 4-4

複数サーバーでの準備済みの文使用方法 .............................................................................................................. 4-4

バインディング ................................................................................ 4-5

文の実行 ...................................................................................... 4-6

実行スナップショット .............................................................................................................................................. 4-6

実行モード .................................................................................................................................................................. 4-7

選択リスト項目の記述 .......................................................................... 4-8

暗黙的記述 .................................................................................................................................................................. 4-8

問合せの明示的記述 ................................................................................................................................................ 4-10

定義 ......................................................................................... 4-11

結果のフェッチ ............................................................................... 4-11

LOBデータのフェッチ........................................................................................................................................... 4-12

プリフェッチ・カウントの設定 ............................................................................................................................ 4-12

5 バインディングと定義バインディング ................................................................................ 5-2

名前付きバインドおよび定位置バインド .............................................................................................................. 5-3

OCI配列インタフェース ......................................................................................................................................... 5-4

PL/SQLのプレースホルダのバインディング ...................................................................................................... 5-5

バインディングで使うステップ .............................................................................................................................. 5-5

Page 7: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

vii

PL/SQLの例 .............................................................................................................................................................. 5-6

拡張バインド .............................................................................................................................................................. 5-8

拡張バインド操作 .............................................................................. 5-9

静的配列バインド ...................................................................................................................................................... 5-9

名前付きデータ型のバインド .................................................................................................................................. 5-9

REFのバインディング .............................................................................................................................................. 5-9

LOBのバインディング ............................................................................................................................................. 5-9

OCI_DATA_AT_EXECモードでのバインド ...................................................................................................... 5-10

Refカーソル変数のバインディング ..................................................................................................................... 5-11

バインド情報のまとめ ............................................................................................................................................ 5-11

定義 ......................................................................................... 5-12

定義に使用するステップ ........................................................................................................................................ 5-13

拡張定義 .................................................................................................................................................................... 5-14

拡張バインド操作 ............................................................................. 5-15

名前付きデータ型出力変数の定義 ........................................................................................................................ 5-15

REF出力変数の定義 ................................................................................................................................................ 5-15

LOB出力変数の定義 ............................................................................................................................................... 5-15

PL/SQL出力変数の定義 ........................................................................................................................................ 5-15

ピース単位フェッチの定義 .................................................................................................................................... 5-15

構造体配列の定義 .................................................................................................................................................... 5-16

構造体の配列 ................................................................................. 5-16

スキップ・パラメータ ............................................................................................................................................ 5-17

構造体の配列で使用される OCIコール ............................................................................................................... 5-19

構造体の配列と標識変数 ........................................................................................................................................ 5-19

RETURNING句を使用した DML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-19

RETURNING句を使用した DMLの使用方法.................................................................................................... 5-20

RETURNING...INTO変数のバインディング...................................................................................................... 5-21

エラー処理 ................................................................................................................................................................ 5-21

RETURNING REF...INTO句を使用した DML ................................................................................................... 5-21

コールバックに関するその他の注意 .................................................................................................................... 5-23

NCHARおよび文字変換問題 ................................................................... 5-23

NCHAR問題 ............................................................................................................................................................ 5-23

OCI_ATTR_MAXDATA_SIZE属性 ..................................................................................................................... 5-24

文字カウント属性 .................................................................................................................................................... 5-25

PL/SQL REF CURSORおよびネステッド・テーブル .............................................. 5-25

Page 8: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

viii

6 スキーマ・メタデータの記述概要 .......................................................................................... 6-2

OCIDescribeAny()の使用....................................................................... 6-2

制限 .............................................................................................................................................................................. 6-3

データ型コードの注意 .............................................................................................................................................. 6-4

型の記述上の注意 ...................................................................................................................................................... 6-4

OCI_ATTR_LIST_ARGUMENTSについての注意 .............................................................................................. 6-5

パラメータ属性 .......................................................................................................................................................... 6-5

表 /ビュー属性 ......................................................................................................................................................... 6-7

プロシージャ /ファンクション属性 ..................................................................................................................... 6-7

パッケージ属性 .......................................................................................................................................................... 6-8

型属性 .......................................................................................................................................................................... 6-9

型属性 ........................................................................................................................................................................ 6-10

型メソッド属性 ........................................................................................................................................................ 6-11

コレクション属性 .................................................................................................................................................... 6-13

シノニム属性 ............................................................................................................................................................ 6-14

順序属性 .................................................................................................................................................................... 6-14

列属性 ........................................................................................................................................................................ 6-15

引数 /結果属性 ....................................................................................................................................................... 6-17

リスト属性 ................................................................................................................................................................ 6-19

例 ........................................................................................... 6-20

表用の列データ型の検索 ........................................................................................................................................ 6-20

ストアド・プロシージャの記述 ............................................................................................................................ 6-21

オブジェクト型の属性の検索 ................................................................................................................................ 6-22

名前付きコレクション型のコレクション要素のデータ型の検索 .................................................................... 6-24

7 OCIプログラミングの応用概要 .......................................................................................... 7-2

トランザクション .............................................................................. 7-3

トランザクションの複雑性のレベル ...................................................................................................................... 7-3

トランザクションの例 .............................................................................................................................................. 7-8

関連する初期化パラメータ .................................................................................................................................... 7-10

ユーザー認証およびパスワードの管理 ........................................................... 7-11

認証 ............................................................................................................................................................................ 7-11

パスワード管理 ........................................................................................................................................................ 7-12

スレッド・セーフティ ......................................................................... 7-13

Page 9: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ix

OCIスレッド・セーフティの利点 ........................................................................................................................ 7-13

スレッド・セーフティと 3層アーキテクチャ .................................................................................................... 7-13

マルチスレッド開発の基本概念 ............................................................................................................................ 7-14

OCI 8.0でのスレッド・セーフティの実現 .......................................................................................................... 7-14

ランタイム・データ割当てとピース単位操作 ..................................................... 7-16

実行時の INSERTまたは UPDATEデータの提供 ............................................................................................. 7-17

PL/SQLでのピース単位操作 ................................................................................................................................ 7-20

実行時の FETCH情報の提供 ................................................................................................................................. 7-20

コールバックなしのピース単位操作に関する追加情報 .................................................................................... 7-22

LOBおよび FILE操作 ......................................................................... 7-23

LOBおよび LOBロケータ ..................................................................................................................................... 7-23

FILE............................................................................................................................................................................ 7-25

内部 LOBの作成と変更 .......................................................................................................................................... 7-25

表内の FILEと OSファイルの関連付け............................................................................................................... 7-25

オブジェクトの LOB属性への書込み .................................................................................................................. 7-26

LOB属性を持つ一時オブジェクト ....................................................................................................................... 7-26

LOBバッファリング ............................................................................................................................................... 7-27

LOB/FILE関数 ........................................................................................................................................................ 7-27

LOB関数のサーバー往復 ....................................................................................................................................... 7-30

LOBの読込み /書込みコールバック ................................................................................................................... 7-30

ストリーム転送のコールバック・インタフェース ............................................................................................ 7-30

コールバックを使用して LOBを読込む .............................................................................................................. 7-31

コールバックを使用して LOBを書込む .............................................................................................................. 7-32

外部プロシージャからの OCIコールバック ...................................................... 7-34

アプリケーション・フェイルオーバー・コールバック ............................................. 7-35

フェイルオーバー・コールバックの概要 ............................................................................................................ 7-35

フェイルオーバー・コールバック構造およびパラメータ ................................................................................ 7-35

フェイルオーバー・コールバックの登録 ............................................................................................................ 7-36

フェイルオーバー・コールバックの例 ................................................................................................................ 7-37

OCIおよびアドバンスト・キューイング......................................................... 7-39

OCIアドバンスト・キューイング関数 ................................................................................................................ 7-39

OCIアドバンスト・キューイングの説明 ............................................................................................................ 7-39

OCIのアドバンスト・キューイング対 PL/SQL ................................................................................................ 7-40

Oracle Security Servicesアプリケーションの作成................................................. 7-42

Page 10: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

x

第 2部 OCIオブジェクトの概念

8 OCIオブジェクト・リレーショナル・プログラミング章の概要 ...................................................................................... 8-2

OCIオブジェクトの概要 ........................................................................ 8-2

OCIでのオブジェクトの操作 .................................................................... 8-4

基本的なオブジェクト・プログラム構造体......................................................................................................... 8-4

永続オブジェクトおよび一時オブジェクト、値.................................................................................................. 8-5

OCIオブジェクト・アプリケーションの開発 ...................................................... 8-7

オブジェクトの Cアプリケーションでの表現 ..................................................................................................... 8-7

環境およびオブジェクト・キャッシュの初期化.................................................................................................. 8-9

データベース接続の実行 .......................................................................................................................................... 8-9

サーバーからのオブジェクト参照の取得 ............................................................................................................ 8-10

オブジェクトの確保 ................................................................................................................................................ 8-11

オブジェクト属性の操作 ........................................................................................................................................ 8-12

オブジェクトのマークおよび変更のフラッシュ................................................................................................ 8-13

埋込みオブジェクトのフェッチ ............................................................................................................................ 8-14

オブジェクトのメタ属性 ........................................................................................................................................ 8-16

複合オブジェクト検索 ............................................................................................................................................ 8-20

CORプリフェッチ .................................................................................................................................................. 8-24

確保カウントおよび確保解除 ................................................................................................................................ 8-27

NULL ........................................................................................................................................................................ 8-27

オブジェクトの作成および開放、コピー ............................................................................................................ 8-30

オブジェクト参照と型参照 .................................................................................................................................... 8-30

オブジェクト・アプリケーションでのエラー処理 ............................................................................................ 8-30

9 オブジェクト・リレーショナル・データ型概要 .......................................................................................... 9-2

Oracle8データ型の Cへのマッピング............................................................. 9-3

OCI型マッピングの方法論 ..................................................................................................................................... 9-4

OCIでの Cデータ型の操作...................................................................... 9-5

Oracle数値操作の精度 ............................................................................................................................................. 9-7

日付 (OCIDate) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-7

日付変換関数 .............................................................................................................................................................. 9-7

日付割当ておよび日付取得関数 .............................................................................................................................. 9-7

日付算術および日付比較関数 .................................................................................................................................. 9-8

Page 11: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xi

日付情報アクセサ関数 .............................................................................................................................................. 9-8

日付の有効性チェック関数 ...................................................................................................................................... 9-8

日付の例 ...................................................................................................................................................................... 9-8

数値 (OCINumber) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-10

数値算出関数 ............................................................................................................................................................ 9-11

数値変換関数 ............................................................................................................................................................ 9-11

指数関数および対数関数 ........................................................................................................................................ 9-12

三角関数 .................................................................................................................................................................... 9-12

数値割当ておよび比較関数 .................................................................................................................................... 9-12

数値の例 .................................................................................................................................................................... 9-13

固定長または可変長文字列 (OCIString) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-15

文字列関数 ................................................................................................................................................................ 9-15

文字列の例 ................................................................................................................................................................ 9-15

ロー (OCIRaw) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-16

ロー・ファンクション ............................................................................................................................................ 9-16

ローの例 .................................................................................................................................................................... 9-16

コレクション (OCITable、OCIArray、OCIColl、OCIIter) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-17

汎用コレクション関数 ............................................................................................................................................ 9-17

コレクション・データ操作関数 ............................................................................................................................ 9-18

コレクション・スキャン・ファンクション ........................................................................................................ 9-18

Varray/コレクション反復子の例......................................................................................................................... 9-19

ネストした表の操作関数 ........................................................................................................................................ 9-20

REF (OCIRef) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-22

REF操作関数 ............................................................................................................................................................ 9-22

REFの例 .................................................................................................................................................................... 9-22

オブジェクト型情報の格納およびアクセス ....................................................... 9-23

記述子オブジェクト ................................................................................................................................................ 9-23

10 オブジェクト・アプリケーションでのバインディングおよび定義バインディング ............................................................................... 10-2

名前付きデータ型のバインド ................................................................................................................................ 10-2

REFのバインディング ............................................................................................................................................ 10-3

名前付きデータ型および REFバインドについての追加情報 ........................................................................... 10-3

問合せの定義 ................................................................................. 10-4

名前付きデータ型出力変数の定義 ........................................................................................................................ 10-4

REF出力変数の定義 ................................................................................................................................................ 10-4

名前付きデータ型と REF定義、および PL/SQL OUTバインドの追加情報 ................................................ 10-4

Page 12: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xii

Oracle8 Cデータ型のバインドおよび定義 ........................................................ 10-6

バインドおよび定義の例 ........................................................................................................................................ 10-8

給与更新の 3つの例 ................................................................................................................................................ 10-9

SQLT_NTYバインド /定義の例................................................................ 10-12

バインドの例 .......................................................................................................................................................... 10-12

定義の例 .................................................................................................................................................................. 10-13

11 オブジェクトのキャッシュおよびオブジェクト・ナビゲーション章の概要 ..................................................................................... 11-2

オブジェクト・キャッシュおよびメモリー管理 ................................................... 11-2

キャッシュの一貫性およびコヒーレンス ............................................................................................................ 11-4

オブジェクト・キャッシュ・パラメータ ............................................................................................................ 11-5

オブジェクト・キャッシュ操作 ............................................................................................................................ 11-6

オブジェクト・コピーをロードおよび削除するための操作 ............................................................................ 11-6

オブジェクト・コピーを変更するための操作 .................................................................................................... 11-9

オブジェクト・コピーをサーバーと同期化するための操作 .......................................................................... 11-10

その他の操作 .......................................................................................................................................................... 11-12

オブジェクト・アプリケーションでのコミットおよびロールバック .......................................................... 11-13

オブジェクトの継続時間 ...................................................................................................................................... 11-13

インスタンスのメモリー・レイアウト .............................................................................................................. 11-15

オブジェクト・ナビゲーション ................................................................ 11-17

単純なオブジェクト・ナビゲーション .............................................................................................................. 11-17

OCIナビゲーショナル関数 .................................................................... 11-19

確保 /確保解除 /開放関数 ................................................................................................................................. 11-19

フラッシュおよびリフレッシュ関数 .................................................................................................................. 11-19

マークおよびマーク解除関数 .............................................................................................................................. 11-20

オブジェクトのメタ属性アクセサ関数 .............................................................................................................. 11-20

その他の関数 .......................................................................................................................................................... 11-21

12 オブジェクト型トランスレータの使用OTT概要..................................................................................... 12-2

オブジェクト型トランスレータの使用方法 ....................................................... 12-2

データベースでの型の作成 .................................................................................................................................... 12-4

OTTの起動............................................................................................................................................................... 12-4

OTTのコマンド行............................................................................. 12-6

OTT............................................................................................................................................................................ 12-6

Page 13: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xiii

userid ......................................................................................................................................................................... 12-6

intype ......................................................................................................................................................................... 12-6

outtype....................................................................................................................................................................... 12-6

コード ........................................................................................................................................................................ 12-7

hfile ............................................................................................................................................................................ 12-7

initfile......................................................................................................................................................................... 12-7

initfile......................................................................................................................................................................... 12-7

Intypeファイル............................................................................... 12-8

OTTデータ型マッピング ...................................................................... 12-9

NULL標識の構造体 ............................................................................................................................................. 12-15

Outtypeファイル ............................................................................ 12-15

OCIアプリケーションでの OTTの使用方法..................................................... 12-17

OCIでのオブジェクトへのアクセスおよび操作 ............................................................................................. 12-18

初期化関数のコール ............................................................................................................................................. 12-19

初期化関数の作業 ................................................................................................................................................. 12-20

OTTの参照 ................................................................................. 12-21

OTTコマンド行の構文 ........................................................................................................................................ 12-22

OTTパラメータ .................................................................................................................................................... 12-23

OTTパラメータの指定可能な場所 .................................................................................................................... 12-26

Intypeファイルの構造体 ..................................................................................................................................... 12-27

ネストされた #includeファイルの生成 ............................................................................................................ 12-29

SCHEMA_NAMESの使用方法 .......................................................................................................................... 12-31

デフォルトの名前のマッピング ......................................................................................................................... 12-33

制限 ......................................................................................................................................................................... 12-34

第 3部 OCI参照

13 OCIリレーショナル関数概要 ..................................................................................................................................................................................... 13-2

OCIクイック・リファレンス ........................................................................................................................................ 13-3

OCI関数のコール ............................................................................................................................................................ 13-6

LOB関数のサーバー往復 ....................................................................................................................................... 13-6

OCIリレーショナル関数 ................................................................................................................................................ 13-7

OCIAQDeq() .................................................................................................................................................................... 13-8

OCIAQEnq().................................................................................................................................................................. 13-11

例 4.................................................................................................................................................................. 13-19

OCIAttrGet() ................................................................................................................................................................. 13-23

Page 14: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xiv

OCIAttrSet()................................................................................................................................................................... 13-25

OCIBindArrayOfStruct()............................................................................................................................................. 13-27

OCIBindByName() ....................................................................................................................................................... 13-29

OCIBindByPos()............................................................................................................................................................ 13-33

OCIBindDynamic() ...................................................................................................................................................... 13-37

OCIBindObject()........................................................................................................................................................... 13-41

OCIBreak() ..................................................................................................................................................................... 13-43

OCIDefineArrayOfStruct() ......................................................................................................................................... 13-44

OCIDefineByPos() ........................................................................................................................................................ 13-46

OCIDefineDynamic() .................................................................................................................................................. 13-50

OCIDefineObject() ....................................................................................................................................................... 13-53

OCIDescribeAny() ........................................................................................................................................................ 13-55

OCIDescriptorAlloc()................................................................................................................................................... 13-58

OCIDescriptorFree()..................................................................................................................................................... 13-60

OCIEnvInit() .................................................................................................................................................................. 13-61

OCIErrorGet() ................................................................................................................................................................ 13-63

OCIHandleAlloc() ........................................................................................................................................................ 13-66

OCIHandleFree() .......................................................................................................................................................... 13-68

OCIInitialize() ............................................................................................................................................................... 13-70

OCILdaToSvcCtx() ........................................................................................................................................................ 13-73

OCILobAppend() .......................................................................................................................................................... 13-74

OCILobAssign() ............................................................................................................................................................ 13-76

OCILobCharSetForm() ................................................................................................................................................ 13-78

OCILobCharSetId() ...................................................................................................................................................... 13-79

OCILobCopy() ............................................................................................................................................................... 13-80

OCILobDisableBuffering() ......................................................................................................................................... 13-82

OCILobEnableBuffering() .......................................................................................................................................... 13-83

OCILobErase() ............................................................................................................................................................... 13-84

OCILobFileClose()........................................................................................................................................................ 13-86

OCILobFileCloseAll() .................................................................................................................................................. 13-87

OCILobFileExists() ....................................................................................................................................................... 13-88

OCILobFileGetName() ................................................................................................................................................ 13-89

OCILobFileIsOpen() .................................................................................................................................................... 13-91

OCILobFileOpen()........................................................................................................................................................ 13-93

OCILobFileSetName() ................................................................................................................................................. 13-94

OCILobFlushBuffer() ................................................................................................................................................... 13-96

OCILobGetLength() ..................................................................................................................................................... 13-98

OCILobIsEqual()......................................................................................................................................................... 13-100

OCILobLoadFromFile() ............................................................................................................................................. 13-101

OCILobLocatorIsInit() ............................................................................................................................................... 13-103

Page 15: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xv

OCILobRead() ............................................................................................................................................................. 13-105

OCILobTrim().............................................................................................................................................................. 13-108

OCILobWrite() ............................................................................................................................................................ 13-109

OCILogoff() ................................................................................................................................................................. 13-113

OCILogon() .................................................................................................................................................................. 13-114

OCIParamGet() ........................................................................................................................................................... 13-116

OCIParamSet() ............................................................................................................................................................ 13-118

OCIPasswordChange() .............................................................................................................................................. 13-120

OCIServerAttach()...................................................................................................................................................... 13-122

OCIServerDetach()..................................................................................................................................................... 13-124

OCIServerVersion().................................................................................................................................................... 13-125

OCISessionBegin()..................................................................................................................................................... 13-126

OCISessionEnd() ........................................................................................................................................................ 13-129

OCIStmtExecute()....................................................................................................................................................... 13-130

OCIStmtFetch() ........................................................................................................................................................... 13-133

OCIStmtGetBindInfo() ............................................................................................................................................. 13-134

OCIStmtGetPieceInfo()............................................................................................................................................. 13-136

OCIStmtPrepare()....................................................................................................................................................... 13-138

OCIStmtSetPieceInfo().............................................................................................................................................. 13-140

OCISvcCtxToLda() ..................................................................................................................................................... 13-142

OCITransCommit() .................................................................................................................................................... 13-143

OCITransDetach() ...................................................................................................................................................... 13-146

OCITransForget() ........................................................................................................................................................ 13-147

OCITransPrepare() ..................................................................................................................................................... 13-148

OCITransRollback() ................................................................................................................................................... 13-149

OCITransStart()........................................................................................................................................................... 13-150

14 OCIナビゲーショナル関数と型関数概要 ..................................................................................................................................................................................... 14-2

オブジェクト型と存続期間 ..................................................................... 14-2

用語 ......................................................................................... 14-4

ナビゲーショナル関数の戻り値 ................................................................. 14-4

ナビゲーショナル関数エラー・コード ........................................................... 14-5

キャッシュおよびオブジェクト関数のためのサーバー往復 ......................................... 14-7

OCIナビゲーショナル関数クイック・リファレンス ................................................................................................ 14-8

OCIナビゲーショナル関数 ......................................................................................................................................... 14-10

OCICacheFlush() .......................................................................................................................................................... 14-11

OCICacheFree() ............................................................................................................................................................ 14-13

OCICacheRefresh() ...................................................................................................................................................... 14-14

Page 16: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xvi

OCICacheUnmark()...................................................................................................................................................... 14-16

OCICacheUnpin() ......................................................................................................................................................... 14-17

OCIObjectArrayPin() ................................................................................................................................................... 14-18

OCIObjectCopy() .......................................................................................................................................................... 14-20

OCIObjectExists() ......................................................................................................................................................... 14-22

OCIObjectFlush() ......................................................................................................................................................... 14-23

OCIObjectFree() ............................................................................................................................................................ 14-24

OCIObjectGetAttr()...................................................................................................................................................... 14-26

OCIObjectGetInd() ...................................................................................................................................................... 14-28

OCIObjectGetObjectRef() .......................................................................................................................................... 14-29

OCIObjectGetProperty() ............................................................................................................................................. 14-30

OCIObjectGetTypeRef().............................................................................................................................................. 14-34

OCIObjectIsDirty() ...................................................................................................................................................... 14-35

OCIObjectIsLocked() ................................................................................................................................................... 14-36

OCIObjectLock()........................................................................................................................................................... 14-37

OCIObjectMarkDelete().............................................................................................................................................. 14-38

OCIObjectMarkDeleteByRef() .................................................................................................................................. 14-40

OCIObjectMarkUpdate() ............................................................................................................................................ 14-41

OCIObjectNew() ........................................................................................................................................................... 14-43

OCIObjectPin() ............................................................................................................................................................. 14-46

OCIObjectPinCountReset() ........................................................................................................................................ 14-49

OCIObjectPinTable() ................................................................................................................................................... 14-51

OCIObjectRefresh() ..................................................................................................................................................... 14-53

OCIObjectSetAttr() ...................................................................................................................................................... 14-55

OCIObjectUnmark() .................................................................................................................................................... 14-57

OCIObjectUnmarkByRef() ......................................................................................................................................... 14-58

OCIObjectUnpin() ........................................................................................................................................................ 14-59

OCITypeArrayByName()............................................................................................................................................. 14-61

OCITypeArrayByRef() ................................................................................................................................................. 14-64

OCITypeByName() ....................................................................................................................................................... 14-66

OCITypeByRef()............................................................................................................................................................ 14-68

15 OCIデータ型マッピング関数および操作関数概要 ......................................................................................... 15-2

データ型マッピング関数および操作関数の戻り値 ................................................. 15-2

その他の値を戻す関数 ......................................................................... 15-3

データ型マッピング関数および操作関数のサーバー往復............................................ 15-3

例 ........................................................................................... 15-3

OCIデータ型マッピング関数クイック・リファレンス ........................................................................................... 15-4

Page 17: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xvii

OCI データ型マッピング関数および操作関数..................................................... 15-8

OCICollAppend()............................................................................................................................................................ 15-9

OCICollAssign() ........................................................................................................................................................... 15-11

OCICollAssignElem().................................................................................................................................................. 15-13

OCICollGetElem()........................................................................................................................................................ 15-15

OCICollMax()................................................................................................................................................................ 15-18

OCICollSize() ................................................................................................................................................................ 15-19

OCICollTrim() ............................................................................................................................................................... 15-21

OCIDateAddDays() ..................................................................................................................................................... 15-22

OCIDateAddMonths() ................................................................................................................................................ 15-23

OCIDateAssign() .......................................................................................................................................................... 15-24

OCIDateCheck() ........................................................................................................................................................... 15-25

OCIDateCompare() ...................................................................................................................................................... 15-27

OCIDateDaysBetween().............................................................................................................................................. 15-28

OCIDateFromText()...................................................................................................................................................... 15-29

OCIDateGetDate() ....................................................................................................................................................... 15-31

OCIDateGetTime()....................................................................................................................................................... 15-32

OCIDateLastDay()........................................................................................................................................................ 15-33

OCIDateNextDay() ...................................................................................................................................................... 15-34

OCIDateSetDate() ........................................................................................................................................................ 15-36

OCIDateSetTime()........................................................................................................................................................ 15-37

OCIDateSysDate()........................................................................................................................................................ 15-38

OCIDateToText()........................................................................................................................................................... 15-39

OCIDateZoneToZone()................................................................................................................................................ 15-41

OCIIterCreate() ............................................................................................................................................................. 15-43

OCIIterDelete() ............................................................................................................................................................. 15-44

OCIIterGetCurrent() .................................................................................................................................................... 15-45

OCIIterInit() .................................................................................................................................................................. 15-46

OCIIterNext() ................................................................................................................................................................ 15-47

OCIIterPrev()................................................................................................................................................................. 15-49

OCINumberAbs()......................................................................................................................................................... 15-51

OCINumberAdd() ........................................................................................................................................................ 15-52

OCINumberArcCos()................................................................................................................................................... 15-53

OCINumberArcSin() ................................................................................................................................................... 15-54

OCINumberArcTan() ................................................................................................................................................... 15-55

OCINumberArcTan2() ................................................................................................................................................. 15-56

OCINumberAssign() ................................................................................................................................................... 15-57

OCINumberCeil() ........................................................................................................................................................ 15-58

OCINumberCmp() ....................................................................................................................................................... 15-59

OCINumberCos() ......................................................................................................................................................... 15-60

Page 18: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xviii

OCINumberDiv().......................................................................................................................................................... 15-61

OCINumberExp().......................................................................................................................................................... 15-62

OCINumberFloor() ....................................................................................................................................................... 15-63

OCINumberFromInt().................................................................................................................................................. 15-64

OCINumberFromReal()............................................................................................................................................... 15-66

OCINumberFromText() ............................................................................................................................................... 15-67

OCINumberHypCos().................................................................................................................................................. 15-69

OCINumberHypSin() .................................................................................................................................................. 15-70

OCINumberHypTan() .................................................................................................................................................. 15-71

OCINumberIntPower()................................................................................................................................................ 15-72

OCINumberIsZero()..................................................................................................................................................... 15-73

OCINumberLn()............................................................................................................................................................ 15-74

OCINumberLog().......................................................................................................................................................... 15-75

OCINumberMod() ........................................................................................................................................................ 15-76

OCINumberMul()......................................................................................................................................................... 15-77

OCINumberNeg() ......................................................................................................................................................... 15-78

OCINumberPower() ..................................................................................................................................................... 15-79

OCINumberRound() .................................................................................................................................................... 15-80

OCINumberSetZero() .................................................................................................................................................. 15-81

OCINumberSign() ........................................................................................................................................................ 15-82

OCINumberSin() .......................................................................................................................................................... 15-83

OCINumberSqrt()......................................................................................................................................................... 15-84

OCINumberSub() ......................................................................................................................................................... 15-85

OCINumberTan() .......................................................................................................................................................... 15-86

OCINumberToInt()....................................................................................................................................................... 15-87

OCINumberToReal() .................................................................................................................................................... 15-89

OCINumberToText() .................................................................................................................................................... 15-90

OCINumberTrunc() ...................................................................................................................................................... 15-92

OCIRawAllocSize() ...................................................................................................................................................... 15-93

OCIRawAssignBytes() ................................................................................................................................................. 15-94

OCIRawAssignRaw()................................................................................................................................................... 15-95

OCIRawPtr() .................................................................................................................................................................. 15-96

OCIRawResize()............................................................................................................................................................ 15-97

OCIRawSize() ................................................................................................................................................................ 15-98

OCIRefAssign()............................................................................................................................................................. 15-99

OCIRefClear().............................................................................................................................................................. 15-100

OCIRefFromHex() ...................................................................................................................................................... 15-101

OCIRefHexSize() ........................................................................................................................................................ 15-103

OCIRefIsEqual() ......................................................................................................................................................... 15-104

OCIRefIsNull()............................................................................................................................................................ 15-105

Page 19: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xix

OCIRefToHex() ........................................................................................................................................................... 15-106

OCIStringAllocSize() ............................................................................................................................................... 15-108

OCIStringAssign() ..................................................................................................................................................... 15-109

OCIStringAssignText() .............................................................................................................................................. 15-110

OCIStringPtr()............................................................................................................................................................. 15-111

OCIStringResize() ...................................................................................................................................................... 15-112

OCIStringSize() .......................................................................................................................................................... 15-113

OCITableDelete() ....................................................................................................................................................... 15-114

OCITableExists() ........................................................................................................................................................ 15-115

OCITableFirst() ........................................................................................................................................................... 15-116

OCITableLast() ............................................................................................................................................................ 15-117

OCITableNext()........................................................................................................................................................... 15-118

OCITablePrev() ........................................................................................................................................................... 15-120

OCITableSize()............................................................................................................................................................ 15-122

16 OCI外部プロシージャ関数概要 ......................................................................................... 16-2

リターン・コード .................................................................................................................................................... 16-2

With_Context型....................................................................................................................................................... 16-2

OCI外部プロシージャ関数..................................................................... 16-3

OCIExtProcAllocCallMemory().................................................................................................................................... 16-4

OCIExtProcRaiseExcp() .................................................................................................................................................. 16-5

OCIExtProcRaiseExcpWithMsg() ................................................................................................................................. 16-6

OCIExtProcGetEnv() ....................................................................................................................................................... 16-8

第 4部 付録

A リリース 7.x OCIアプリケーションからリリース 8.0へのアップグレード互換性およびアップグレードの概要 .............................................................. A-2

廃止された OCIルーチン ....................................................................... A-2

廃止された OCIルーチン ....................................................................... A-4

互換性 ........................................................................................ A-4

アップグレード ................................................................................ A-6

アプリケーション・リンク発行 .................................................................. A-7

非遅延リンク ............................................................................................................................................................. A-7

シングル・タスク・リンク ..................................................................................................................................... A-9

Page 20: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xx

B ハンドルおよび記述子の属性表記法 .................................................................................................................................................................................. B-2

環境ハンドルの属性 .......................................................................................................................................................... B-3

OCI_ATTR_CACHE_MAX_SIZE ........................................................................................................................... B-3

OCI_ATTR_CACHE_OPT_SIZE............................................................................................................................. B-3

OCI_ATTR_OBJECT ................................................................................................................................................. B-3

OCI_ATTR_FNCODE............................................................................................................................................... B-4

OCI_ATTR_PINOPTION......................................................................................................................................... B-4

OCI_ATTR_ALLOC_DURATION.......................................................................................................................... B-4

OCI_ATTR_PIN_DURATION ................................................................................................................................ B-6

サービス・コンテキスト・ハンドルの属性 .................................................................................................................. B-7

OCI_ATTR_SQLCODE............................................................................................................................................. B-7

OCI_ATTR_ENV ....................................................................................................................................................... B-7

OCI_ATTR_SERVER................................................................................................................................................. B-7

OCI_ATTR_SESSION ............................................................................................................................................... B-9

OCI_ATTR_TRANS .................................................................................................................................................. B-9

OCI_ATTR_IN_V8_MODE...................................................................................................................................... B-9

サーバー・ハンドルの属性 ............................................................................................................................................ B-11

OCI_ATTR_ENV ..................................................................................................................................................... B-11

OCI_ATTR_FNCODE............................................................................................................................................. B-11

OCI_ATTR_EXTERNAL_NAME.......................................................................................................................... B-11

OCI_ATTR_INTERNAL_NAME .......................................................................................................................... B-12

OCI_ATTR_IN_V8_MODE.................................................................................................................................... B-12

OCI_ATTR_FOCBK ................................................................................................................................................ B-12

ユーザー・セッション・ハンドルの属性 .................................................................................................................... B-13

OCI_ATTR_USERNAME....................................................................................................................................... B-13

OCI_ATTR_PASSWORD ....................................................................................................................................... B-13

トランザクション・ハンドルの属性 ............................................................................................................................ B-14

OCI_ATTR_TRANS_NAME ................................................................................................................................. B-14

OCI_ATTR_XID....................................................................................................................................................... B-14

ステートメント・ハンドルの属性 ................................................................................................................................ B-15

OCI_ATTR_FNCODE............................................................................................................................................. B-15

OCI_ATTR_ROW_COUNT ................................................................................................................................... B-15

OCI_ATTR_SQLFNCODE ..................................................................................................................................... B-15

OCI_ATTR_ENV ..................................................................................................................................................... B-16

OCI_ATTR_STMT_TYPE ....................................................................................................................................... B-16

OCI_ATTR_ROWID................................................................................................................................................ B-17

OCI_ATTR_PARAM_COUNT.............................................................................................................................. B-17

OCI_ATTR_PREFETCH_ROWS ........................................................................................................................... B-18

Page 21: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxi

OCI_ATTR_PREFETCH_MEMORY .................................................................................................................... B-18

バインド・ハンドルの属性 ............................................................................................................................................ B-19

OCI_ATTR_FNCODE ............................................................................................................................................ B-19

OCI_ATTR_CHAR_COUNT ................................................................................................................................ B-19

OCI_ATTR_CHARSET_ID .................................................................................................................................... B-19

OCI_ATTR_CHARSET_FORM............................................................................................................................. B-19

OCI_ATTR_MAXDATA_SIZE ............................................................................................................................. B-20

OCI_ATTR_PDSCL ................................................................................................................................................ B-20

OCI_ATTR_PDFMT ............................................................................................................................................... B-21

OCI_ATTR_ROWS_RETURNED ......................................................................................................................... B-21

定義ハンドルの属性 ........................................................................................................................................................ B-22

OCI_ATTR_FNCODE ............................................................................................................................................ B-22

OCI_ATTR_CHAR_COUNT ................................................................................................................................ B-22

OCI_ATTR_CHARSET_ID .................................................................................................................................... B-22

OCI_ATTR_CHARSET_FORM............................................................................................................................. B-23

OCI_ATTR_PDSCL ................................................................................................................................................ B-23

OCI_ATTR_PDFMT ............................................................................................................................................... B-23

記述ハンドルの属性 ........................................................................................................................................................ B-24

OCI_ATTR_PARAM_COUNT ............................................................................................................................. B-24

パラメータ記述子の属性 ................................................................................................................................................ B-24

LOBロケータの属性 ...................................................................................................................................................... B-25

OCI_ATTR_LOBEMPTY........................................................................................................................................ B-25

複合オブジェクトの属性 ................................................................................................................................................ B-26

複合オブジェクト検索ハンドルの属性 ............................................................................................................... B-26

OCI_ATTR_COMPLEXOBJECT_LEVEL.................................................................................................... B-26

OCI_ATTR_COMPLEXOBJECT_COLL_OUTOFLINE............................................................................ B-26

複合オブジェクト検索記述子の属性 ................................................................................................................... B-27

OCI_ATTR_COMPLEXOBJECTCOMP_TYPE .......................................................................................... B-27

OCI_ATTR_COMPLEXOBJECTCOMP_TYPE_LEVEL| ......................................................................... B-27

アドバンスト・キューイング記述子の属性 ................................................................................................................ B-28

OCIAQEnqOptions記述子の属性 ....................................................................................................................... B-28

OCI_ATTR_RELATIVE_MSGID.................................................................................................................. B-28

OCI_ATTR_SEQUENCE_DEVIATION...................................................................................................... B-28

OCI_ATTR_VISIBILITY ................................................................................................................................ B-29

OCIAQDeqOptions記述子の属性 ....................................................................................................................... B-29

OCI_ATTR_CONSUMER_NAME............................................................................................................... B-29

OCI_ATTR_CORRELATION ....................................................................................................................... B-29

OCI_ATTR_DEQ_MODE.............................................................................................................................. B-30

OCI_ATTR_DEQ_MSGID............................................................................................................................. B-31

OCI_ATTR_NAVIGATION.......................................................................................................................... B-31

Page 22: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxii

OCI_ATTR_VISIBILITY................................................................................................................................. B-31

OCI_ATTR_WAIT .......................................................................................................................................... B-32

OCIAQMsgProperties記述子の属性 ................................................................................................................... B-33

OCI_ATTR_ATTEMPTS ................................................................................................................................ B-33

OCI_ATTR_CORRELATION........................................................................................................................ B-33

OCI_ATTR_DELAY........................................................................................................................................ B-33

OCI_ATTR_ENQ_TIME ................................................................................................................................ B-34

OCI_ATTR_EXCEPTION_QUEUE .............................................................................................................. B-34

OCI_ATTR_EXPIRATION ............................................................................................................................ B-35

OCI_ATTR_MSG_STATE.............................................................................................................................. B-35

OCI_ATTR_PRIORITY................................................................................................................................... B-36

OCI_ATTR_RECIPIENT_LIST...................................................................................................................... B-36

OCIAQAgent記述子の属性 .................................................................................................................................. B-37

OCI_ATTR_AGENT_ADDRESS .................................................................................................................. B-37

OCI_ATTR_AGENT_NAME ........................................................................................................................ B-37

OCI_ATTR_AGENT_PROTOCOL............................................................................................................... B-37

C Oracle予約語およびキーワード、 名前領域Oracle予約語およびキーワード .................................................................. C-2

PL/SQL予約語................................................................................ C-11

Oracle予約名前領域 ........................................................................... C-12

D コード例例 1、SQL処理 ................................................................................ D-2

例 2、オブジェクトの取り出し .................................................................. D-11

cdemo82.h................................................................................................................................................................. D-20

cdemo82.sql.............................................................................................................................................................. D-23

例 3、RETURNING句を使う DML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-25

cdemodr1.h............................................................................................................................................................... D-52

例 4、オブジェクトの解明 ...................................................................... D-54

cdemodsc.h............................................................................................................................................................... D-72

例 5、CLOB/BLOB操作........................................................................ D-74

例 6、LOBバッファリング ..................................................................... D-94

例 7、REF確保とナビゲーション............................................................... D-115

E OCI関数のサーバーとの通信の往復概要 .......................................................................................... E-2

Page 23: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxiii

LOB関数による通信の往復...................................................................... E-2

オブジェクトおよびキャッシュ関数による通信の往復 .............................................. E-4

記述操作による通信の往復 ...................................................................... E-5

データ型のマップおよび操作関数による通信の往復 ................................................ E-6

その他のローカル機能 .......................................................................... E-7

F Oracle8 OCI新機能概要 .......................................................................................... F-2

Oracle8 OCI拡張機能 .......................................................................... F-2

カプセル化された明確でないインタフェース ...................................................................................................... F-2

簡素化されたユーザー認証とパスワード管理 ...................................................................................................... F-3

アプリケーションのパフォーマンスとスケーラビリティを向上させる拡張機能 .......................................... F-3

トランザクション管理用の一貫したインタフェース .......................................................................................... F-4

Oracle8 OCIオブジェクトのサポート ................................................................................................................... F-4

オブジェクトのランタイム環境 .............................................................................................................................. F-6

型管理関数および型マッピング関数、型操作関数 .............................................................................................. F-6

オブジェクト型トランスレータ .............................................................................................................................. F-6

Oracleアドバンスト・キューイングに対する OCIサポート ............................................................................ F-7

OCI新機能の利点.............................................................................. F-7

Oracle8オブジェクトの包括的なサポート............................................................................................................ F-8

アプリケーションのパフォーマンスの向上 .......................................................................................................... F-8

スケーラビリティの向上 .......................................................................................................................................... F-8

既存アプリケーションの容易な移行 ...................................................................................................................... F-8

アプリケーションの拡張性の向上 .......................................................................................................................... F-9

Page 24: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxiv

Page 25: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxv

はじめに

Oracleコール・インタフェース (Oracle Call Interface:OCI)は、アプリケーション・プログラミング・インタフェース (application programming interface:API)です。このインタフェースを使用すると、C言語で作成したアプリケーションで 1つ以上の Oracle Serverと交信できます。OCIでは、プログラムにおいて SQLステートメント処理、オブジェクト操作など、Oracle8 Serverに用意されているデータベース機能を最大限に活用することができます。

ここでは、次の項目について説明します。

■ このマニュアルの目的

■ このマニュアルの対象

■ サポートされている機能とその可用性

■ このマニュアルの使い方

■ このマニュアルの構成

■ このマニュアルの表記規則

Page 26: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxvi

このマニュアルの目的このマニュアルでは、OCIを利用したアプリケーションを開発するための基本について詳しく説明します。このマニュアルは、2つのボリュームで構成されています。

Vol.1では、次の内容を詳しく説明します。

■ OCIアプリケーションの構造

■ サーバーと OCIアプリケーション変数間のデータ変換

■ オブジェクトへのナビゲーショナル・アクセス、および型管理、データ型のマッピングと操作を提供するオブジェクト関数

Vol.2では、次の内容について説明します。

■ 各 OCI関数コールの説明、およびその構文情報とパラメータ説明

■ 全 OCIハンドル属性のリスト

■ Oracleの予約語、およびキーワード、名前領域のリスト

■ OCIの機能を説明するサンプル・プログラム

■ OCIの以前のリリースからリリース 8.0へのアプリケーションのアップグレード

■ 多くの OCIコールで必要なサーバー往復

このマニュアルの対象『Oracle8コール・インタフェース・プログラマーズ・ガイド』は、Oracle環境で実行するための新規アプリケーションの開発または既存のアプリケーションの変換を行うプログラマのためのものです。OCIについて包括的に説明しているので、システム・アナリストやプロジェクト・マネージャをはじめ、データベース・アプリケーションの開発に関心のある他のユーザーにも役に立ちます。

このマニュアルを効果的に活用するには、Cによるアプリケーション・プログラミングに関する実践知識、および SQLリレーショナル・データベース言語の知識が必要です。さらに、このマニュアルの一部の章では、オブジェクト指向プログラミングの基本概念の知識が必要です。

SQLの詳細は、『Oracle8 Server SQLリファレンス』 および『Oracle8 Server管理者ガイド』を参照してください。Oracle基本概念の詳細は、『Oracle8 Server概要』を参照してください。第 3世代言語 (3GL)アプリケーションへの SQLコマンドの埋込みを可能にする Oracleプリコンパイラの詳細は、『Pro*C/C++プリコンパイラ・プログラマーズ・ガイド』 および『Pro*COBOLプリコンパイラ・プログラマーズ・ガイド』を参照してください。

Page 27: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxvii

⦆サポートされている機能とその可用性『Oracle8コール・インタフェース・プログラマーズ・ガイド』には、Oracle8製品および

Oracle8 Enterprise Edition製品の機能と機能性についての情報が含まれています。Oracle8および Oracle8 Enterprise Editionは同一の基本機能を共有しています。ただし、Enterprise Editionだけに用意された拡張機能もいくつかあり、その一部はオプションとなっています。たとえば、オブジェクト機能を使用するには、Enterprise Editionおよびオブジェクト・オプションが必要です。

Oracle8と Oracle8 Enterprise Editionの相違点、および使用可能な機能とオプションの詳細は、『Oracle8と Oracle Enterprise Editionの解説』を参照してください。

このマニュアルの使い方『Oracle8コール・インタフェース・プログラマーズ・ガイド』では、OCIをはじめて取り扱うプログラマ、および OCI旧バージョンに携わった経験があるプログラマを対象に、OCIの概要が説明されています。

Vol.1

第 1部⦆⦆

第 1部(第 1~ 7章)では、Oracleデータベースのリレーショナル・データにアクセスするOCIプログラムの作成方法およびその概念について説明します。ここでは OCIプログラミングの基本について説明し、第 2部で説明するオブジェクト・リレーショナル機能を理解するための基礎を固めます。

第 2部⦆⦆

第 2部(第 8~ 12章)では、OCIを使用してオブジェクト・リレーショナル・データにアクセスするための OCI機能について説明します。第 2部の各章では、Oracle8 Serverを介したオブジェクトの取り出しおよび操作について説明します。

Vol.2

第 3部⦆⦆

第 3部(第 13~ 16章)では、Oracle8 OCIライブラリにあるすべてのファンクション・コールをリストします。

第 4部⦆⦆

第 4部 (付録 A~ F)では、完全なコード例とともに、OCIプログラミングについての追加情報について説明します。

Page 28: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxviii

このマニュアルの読み方リリース 8.0には大幅な OCI機能拡張が行われたため、OCIプログラミングの経験の有無にかかわらず基本概念について説明している第 1部を読んでください。基本概念の大部分(バインディング、定義など)はリリース 7.3と変わりませんが、リリース 8.0ではこれが新しい方法で実現されています。

OCIの現バージョンに慣れている方、およびオブジェクト機能に興味のある方は、第 1部は軽く目を通して、第 2部から読み始めることもできます。

リファレンス情報 (OCI関数の構文、ハンドル属性の記述など )は、Vol.2を参照してください。

このマニュアルの構成『Oracle8コール・インタフェース・プログラマーズ・ガイド』は 4部からなり、これらが 2つのボリュームに分けられています。各章および付録の内容は、次のとおりです。

Vol.1

第 1 部 :⦆OCI の基本概念

第 1章 :⦆概要および新機能この章では、Oracleコール・インタフェースの概要を説明し、このインタフェースを説明する上での特別な用語や表記上の規則を示します。現行のリリースから新たに追加された機能についても説明します。

第 2章 :⦆OCI プログラミングの基本この章では、OCIプログラムを開発する上で必要な基本概念について説明します。OCIプログラムに組み込まなくてはならない必須のステップと、エラー・メッセージを検索し解読する方法について説明します。

第 3章 :⦆データ型OCIインタフェースを利用する際には、Oracleの表とホスト・プログラムの変数の間でデータが変換される仕組みを理解する必要があります。この章では、Oracle内部と外部のデータ型、およびデータ変換について説明します。

第 4章 :⦆SQL 文の処理この章では、Oracle8 OCIを使用する SQL文のステップについて説明します。

第 5章 :⦆バインディングと定義この章では、OCIバインド操作および定義操作について詳しく説明します。さらに、拡張バインド操作および拡張定義操作についても説明します。

Page 29: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxix

第 6章 :⦆スキーマ・メタデータの記述この章では、OCIDescribeAny()コールを使用して、スキーマ・オブジェクトとそれに対応する要素の情報を取得する方法を説明します。

第 7章 :⦆OCI プログラミングの応用この章ではトランザクション管理、LOBサポート、拡張バインド機能性、拡張定義機能性、および他の機能性の説明を含む、より洗練された OCIプログラミングのトピックを説明します。

第 2部 :⦆OCI オブジェクトの概念

第 8章 :⦆OCI オブジェクト・リレーショナル・⦆プログラミングこの章では、OCIを利用して Oracle8 Server内のオブジェクトにアクセスするための基本概念を紹介します。基本的なオブジェクト概念とオブジェクト確保、およびオブジェクト・リレーショナル・アプリケーションの基本構造についても説明します。

第 9章 :⦆オブジェクト・リレーショナル・データ型この章では、OCIプログラミングで使用するオブジェクト・データ型の概要を説明します。

第 10 章 :⦆オブジェクト・アプリケーションでのバインディングおよび定義この章では、Oracle8データベース内のユーザー定義データ型と Cのデータ型のマッピング、およびこのようなデータを操作する関数について説明します。また、これらの Cマッピングを使用したバインドと定義についても説明します。

第 11 章 :⦆オブジェクトのキャッシュおよびオブジェクト・ナビゲーションこの章では、OCIを利用して Oracle8 Server内のオブジェクトにアクセスするための基本概念を紹介します。また、オブジェクト・キャッシュについて、およびサーバーから取り出されたオブジェクトを操作する OCIナビゲーショナル・コールの使用方法についても説明します。

第 12 章 :⦆オブジェクト型トランスレータの使用この章では、オブジェクト型トランスレータを使用してデータベース・オブジェクト定義をC構造体の表現に変換し、OCIアプリケーションで使用する方法を説明します。

Vol.2

第 3 部 :⦆OCI リファレンス

第 13章 :⦆OCI リレーショナル関数この章では、OCIのリレーショナル関数のリストを示し、構文およびコメント、パラメータ記述、その他の有用な情報について説明します。

Page 30: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxx

第 14 章 :⦆OCI ナビゲーショナル関数と型関数この章では、OCIのナビゲーショナル関数のリストを示し、構文およびコメント、パラメータ記述、その他の有用な情報について説明します。

第 15 章 :⦆OCI データ型マッピング関数および操作関数この章では、OCIのデータ型マッピング関数とデータ型操作関数のリストを示し、構文およびコメント、パラメータ記述、その他の有用な情報について説明します。

第 16 章 :⦆OCI 外部プロシージャ関数この章では、外部プロシージャで使用する特別な OCI関数について説明します。

第 4部 :⦆付録

付録 A:⦆リリース 7.x⦆OCI アプリケーションからリリース 8.0 へのアップグレードこの付録では、新しい Oracle8 OCIを使用するために、既存の OCIアプリケーションをアップグレードするときの問題点について説明します。廃止された、または使用されなくなったOCIコールのリストも含みます。

付録 B:⦆ハンドルおよび記述子の属性この付録では、OCIコールによって設定や読取りができる OCIアプリケーション・ハンドルの属性について説明します。

付録 C:⦆Oracle 予約語およびキーワード、⦆名前領域この付録では、Oracleの特別な用語と Oracle製品によって予約されている名前領域のリストを示します。

付録 D:⦆コード例この付録では、完全な OCIアプリケーションのコード例を示します。

付録 E:⦆OCI 関数のサーバー往復この付録では、さまざまな OCIアプリケーションで必要なサーバー往復の回数の表を示します。

付録 F:⦆Oracle8⦆OCI 新機能この付録では、Oracle8 OCIで利用できる機能および拡張機能の詳細を説明します。

このマニュアルの表記規則このマニュアルで使用する表記上の規則とテキスト書式は、次のとおりです。

[⦆]大カッコ内は、オプション項目を示します。大カッコは入力しません。

{⦆}中カッコは、項目を 1つだけ選択することが必要である選択肢を囲みます。

Page 31: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxxi

|縦線は、中カッコ内の項目を区切ります。また、関数パラメータに複数の値を渡すことを示す場合もあります。

...コード例が省略されている部分は、省略符号で表記されます。

font changeSQLまたは Cのコード例は、クーリエ・フォントで表記されます。

イタリックイタリック体は、OCIパラメータ、OCIルーチン名、ファイル名、データ・フィールドを参照する場合に使用されます。

大文字大文字は、SELECTや UPDATEといった SQLのキーワードを参照する場合に使用されます。

太字太字は、ub4、sword、OCINumberなどの Cデータ型のデータ名を識別する場合に使用します。

このマニュアルでは、読者の注意を促すため一部の情報に特殊なテキスト書式を使用しています。インデントされて太字のテキスト・ラベルで始まる段落は、特別な内容です。このように表記される情報は、次のとおりです。

注意 : この「注意」フラグは、一般的な問題を回避するため、または概念を理解する上で読者にとって特に重要な情報であることを示しています。

7.x アップグレードの注意 : 「7.xアップグレードの注意」と記された項目は、一般にリリース 8.0 OCIとリリース 7.x OCIに大きな違いがある場合にプログラマの注意を促します。

警告 : 「警告」と記された項目は、アプリケーションが正常に動作するよう、OCIプログラマが細心の注意を払うべき事項です。

関連項目 : 「関連項目」と記されたテキストは、現在の説明内容に関する追加情報が説明されている、このマニュアル内の他の節または他のドキュメンテーションを示しています。

Page 32: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

xxxii

Page 33: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

第 1部OCIの基本概念

このガイドの第 1部には、OCIプログラミングの基本概念を説明した章が含まれています。

■ 第 1章の「概要および新機能」では、OCIを簡単に紹介し、リリース 8.0の新機能について説明します。

■ 第 2章の「OCIプログラミングの基本」では、OCIプログラミングの基本概念を説明します。

■ 第 3章の「データ型」では、OCIアプリケーションおよび Oracle8 Server内で使用されるデータ型について説明します。

■ 第 4章の「SQL文の処理」では、Oracle8 OCIを使った SQL文の処理方法を説明します。

■ 第 5章の「バインディングと定義」では、バインド操作および定義操作について詳しく説明します。

■ 第 6章の「スキーマ・メタデータの記述」では、OCIDescribeAny()関数について説明します。

■ 第 7章の「OCIプログラミングの応用」では、OCIプログラミングのより高度なトピックに触れます。

Page 34: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

概要および新機能 1-1

1概要および新機能

この章では、Oracleコール・インタフェース (OCI)のリリース 8.0の概要、および OCIを使ったアプリケーションの開発に必要な基礎について説明します。また、OCIの説明で使用されている特別な用語について解説します。

この章では、リリース 7.3以降の OCIの変更点についても説明します。

この章は、次のトピックで構成されています。

■ Oracleコール・インタフェース

■ SQL文

■ OCI/SQLの特殊用語

■ OCIでのオブジェクト・サポート

■ OCIの分類

■ リリース 8.0の新機能

■ 使用されなくなった、または廃止された OCIコール

■ コンパイルおよびリンク

Page 35: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracleコール・インタフェース

1-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

Oracleコール・インタフェース標準問い合わせ言語 (Structured Query Language:SQL)は非プロシージャ型言語です。非プロシージャ型言語のプログラムでは、操作対象となるデータの集合を指定しますが、実行する操作の種類や操作の方法を正確に指定することはしません。SQLは、非プロシージャ型という性質上、習得しやすく、データベース・トランザクションを実行しやすい言語です。また、SQLは、先進のリレーショナル・データベース・システムおよびオブジェクト・リレーショナル・データベース・システムのデータに対するアクセスや操作に使用する標準言語となっています。

これに対して、Cや C++などのほとんどのプログラミング言語は、プロシージャ型言語です。大部分の文の実行は、前または後続の文、およびループや条件ブランチなど SQLで利用できない制御構造に依存しています。プロシージャ型という性質によって、こうした言語は SQLよりも複雑ですが、柔軟性に富み、非常に強力です。

Oracleコール •インタフェース (OCI)は、SQLの非プロシージャ型データ・アクセス機能と、Cのプロシージャ型機能を併せ持つアプリケーションの開発を可能にします。OCIでは、Oracle8 Serverを通じて使用することができる、SQLのデータ定義機能およびデータ操作機能、問合せ機能、トランザクション制御機能をすべてサポートしています。

また、Oracleが開発した SQLのプロシージャ型拡張要素である PL/SQLも利用することができます。これにより、SQLだけで作成されたアプリケーションよりも、さらに強力で柔軟性のあるアプリケーションを開発できます。OCIは、Oracle8 Server内のオブジェクトに対するアクセスおよび操作のための機能も提供します。

OCIは、Oracleデータベース内のデータおよびスキーマの操作を可能にするアプリケーション・プログラミング・インタフェース (application programming interface:API)です。図 1–1に示すように、OCIプログラムは非データベース・アプリケーションと同様な方法でコンパイルおよびリンクすることができます。処理前のステップやプリコンパイル・ステップを別に行う必要はありません。

Page 36: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracleコール・インタフェース

概要および新機能 1-3

図 1–1 OCIの開発プロセス

注意 : 一部のプラットフォームでは、OCIプログラムを正常にリンクさせるため、OCIライブラリの別のライブラリを組み込まなければならない場合があります。必要となる可能性のある追加ライブラリの詳細は、使用しているシステム固有の Oracleマニュアルを参照してください。

Page 37: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQL文

1-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

SQL文OCIアプリケーションの主なタスクの 1つは、SQL文を処理することです。SQL文の種類が異なると、プログラムでは異なる処理ステップが必要になります。OCIアプリケーションをコーディングする際には、それを考慮に入れることが重要です。

Oracle8では、以下の 8種類の SQL文を認識します。

■ データ定義言語 (DDL)

■ 制御文 (3種類 )

– トランザクション制御

– セッション制御

– システム制御

■ データ操作言語 (DML)

■ 問合せ

注意 : 多くの場合、問合せは DML文として分類されますが、OCIアプリケーションでは異なる方法で問合せを処理するため、ここでは両者を別個に考慮しています。

■ PL/SQL

■ 埋込み SQL

データ定義言語 (DDL)データ定義言語 (Data Definition Language:DDL)文は、データベース内のスキーマ・オブジェクトを管理します。DDL文は、新規の表を作成したり、古い表を削除したり、他のスキーマ・オブジェクトを設定したりします。また、スキーマ・オブジェクトに対するアクセスを制御します。たとえば、次のとおりです。

CREATE TABLE employees (name VARCHAR2(20),

ssn VARCHAR2(12),empno NUMBER(6),mgr NUMBER(6),salary NUMBER(6))

GRANT UPDATE, INSERT, DELETE ON employees TO donnaREVOKE UPDATE ON employees FROM jamie

また、オブジェクト表を作成する次の一連の文のように、DDL文では Oracle8 Server内のオブジェクトを操作できます。

CREATE TYPE person_t AS OBJECT (name VARCHAR2(30),

Page 38: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQL文

概要および新機能 1-5

ssn VARCHAR2(12),address VARCHAR2(50))

CREATE TABLE person_tab OF person_t

制御文OCIアプリケーションは、トランザクション制御文およびセッション制御文、システム制御文を DML文のように処理します。これらの種類の文の詳細は、『Oracle8 Server SQLリファレンス』 を参照してください。

データ操作言語 (DML)データ操作言語 (DML)文は、データベース表にあるデータを変更できます。たとえば、DML文を使用して次のことができます。

■ INSERTで表に新しい行を挿入する。

■ UPDATEで既存の行の列値を更新する。

■ DELETEで表から行を削除する。

■ LOCKでデータベース内の表をロックする。

■ EXPLAINで SQL文の実行計画を説明する。

DML文では、入力(バインド)変数を使用して、データベースへデータを渡すよう、アプリケーションに指示できます。入力バインド変数の詳細は、4-5ページの「バインディング」 を参照してください。

person_t型のインスタンスをオブジェクト表 person_tabに挿入する次の例のように、DML文では Oracle8 Server内のオブジェクトを操作できます。

INSERT INTO person_tabVALUES (person_t(’Steve May’,’123-45-6789’,’146 Winfield Street’))

問合せ問合せは、データベースからデータを検索するための文です。問合せは、0または 1行、複数行のデータを戻します。すべての問合せは、次の例のように、SQLキーワード SELECTで始まります。

SELECT dname FROM deptWHERE deptno = 42

問合せは、表の中のデータにアクセスするため、多くの場合 DML文として分類されます。ただし、OCIアプリケーションでは問合せの処理方法が異なるため、このマニュアルでは問合せを別個のものとして扱います。

Page 39: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQL文

1-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

問合せ文では、次の例のように、入力(バインド)変数を使用して、プログラムでデータベースにデータを供給するように要求できます。

SELECT name FROM employeesWHERE empno = :empnumber

前述の SQL文で、:empnumber は、アプリケーションが供給する値に対するプレースホルダです。

問合せを処理する際、OCIアプリケーションでは、戻される結果を受け取るための出力変数も定義する必要があります。上の文では、問合せから戻される nameの値を受け取るために出力変数を定義する必要があります。

関連項目 : 入力バインド変数の詳細は、5-2ページの「バインディング」 を参照してください。

出力変数の詳細は、5-12ページの「定義」を参照してください。

OCIプログラム内での SQL文の処理方法の詳細は、 第 4章の「SQL文の処理」を参照してください。

PL/SQLPL/SQLは、Oracleが開発した SQL言語のプロシージャ型拡張要素です。PL/SQLは、単純な問合せや SQLデータ操作言語 (DML)文よりも複雑な作業を処理します。PL/SQLを使用すると、多数の構成体を単一のブロックにグループ化し、1つの単位として実行できます。これらの単位には次の部分が含まれます。

■ 1つまたは複数の SQL文

■ 変数宣言

■ 代入文

■ プロシージャ型制御文 (IF...THEN...ELSE文とループ )

■ 例外処理

Page 40: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCI/SQLの特殊用語

概要および新機能 1-7

OCIプログラムで PL/SQLブロックを使用すると、次のことができます。

■ Oracleストアド・プロシージャおよびストアド・ファンクションのコール

■ 複数の SQL文を指定したプロシージャ型制御文を結合し、1つの単位として実行

■ レコード、表、カーソル FORループ、例外処理などの特殊な PL/SQL機能へのアクセス

■ カーソル変数の使用

■ Oracle8 Server内のオブジェクトへのアクセスおよび操作

次の PL/SQL例では、特定の従業員番号をキーにして、従業員表から値を取り出す SQL文が発行されます。この例は、PL/SQL文でのプレースホルダの使用方法を示しています。

BEGINSELECT ename, sal, comm INTO :emp_name, :salary, :commissionFROM empWHERE ename = :emp_number;

END;

この文のプレースホルダは、PL/SQL変数ではないことに注意してください。これらは、文の処理時に、Oracleに渡される入力値を示します。これらのプレースホルダは、プログラム内で C言語変数にバインドする必要があります。

関連項目 : PL/SQLブロックのコーディングの詳細は、『PL/SQLユーザーガイド・ リファレンス』 を参照してください。

PL/SQLでのプレースホルダ取扱い方法の詳細は、5-5ページの「PL/SQLのプレースホルダのバインディング」を参照してください。

埋込み SQLOCIは、アプリケーションが実行時に Oracleに渡すテキスト文字列として SQL文を処理します。Oracleプリコンパイラ (Pro*C/C++、Pro*COBOL、Pro*FORTRAN)を使用することによって、プログラマは SQL文をアプリケーション・コードに直接埋め込むことができます。その後、実行可能なアプリケーションを生成するために別個のプリコンパイル・ステップが必要です。

OCIコールと埋込み SQLはプリコンパイラ・プログラムでは混在できます。詳細は『Pro*COBOLプリコンパイラー・プログラマーズ・ガイド』を参照してください。

OCI/SQLの特殊用語このマニュアルでは、SQL文のさまざまな部分を参照するために特殊な用語を使用しています。たとえば次のような SQL文があります。

SELECT customer, addressFROM customersWHERE bus_type = ’SOFTWARE’

Page 41: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでのオブジェクト・サポート

1-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

AND sales_volume = :sales

この SQL文には、次が含まれています。

■ SQLコマンド - SELECT

■ 選択リスト項目 - customerおよび address

■ FROM句内に表名 - customers

■ WHERE句内に列名 - bus_typeおよび sales_volume

■ WHERE句内にリテラル入力値 - ’SOFTWARE’

■ WHERE句第 2部分の入力値用にプレースホルダ - :sales

OCIアプリケーションを開発する際は、プログラム中の入出力変数のアドレス(位置)をOracle8 Serverに指定しているルーチンをコールします。このマニュアルでは、データ入力用のプレースホルダ変数のアドレスを指定することをバインド操作と呼びます。また、選択リスト項目を受け取る変数のアドレスを指定することを定義操作と呼びます。

PL/SQLでは、入力の指定も出力の指定もバインド操作と呼びます。

これらの用語と操作については、第 4章で説明しています。

OCIでのオブジェクト・サポートリリース 8.0の Oracle Serverにはオブジェクト型およびオブジェクトを操作するための機能が備わっています。オブジェクト型は、ユーザー定義のデータ構造体で、実社会に実在するものを抽象的に表します。たとえば、データベースに person(個人 )というオブジェクトの定義が含まれているとします。このオブジェクトは、個人を識別するための特徴を表した属性 (first_nameおよび last_name、age)を持つものとします。

オブジェクト型の定義は、オブジェクト型のインスタンスを表し、オブジェクトの作成の基礎となります。オブジェクト型を構造的な定義として使うと、たとえばある personオブジェクトを属性 ’John’、 および ’Bonivento’、 ’30’から作成することができます。

オブジェクト型にはメソッド-そのオブジェクト型の振舞いを表現する関数を含めることもできます。

関連項目 : オブジェクト型およびオブジェクトの詳細は、『Oracle8 Server概要』を参照してください。

Oracle8 OCIには、Oracle8 Server内のオブジェクト処理用に OCIの機能を拡張した関数が組み込まれています。具体的には、次の機能が OCIに追加されました。

■ オブジェクト・データとスキーマ情報を操作する SQL文を実行するためのサポート

■ SQL文の入力変数としてオブジェクト参照およびオブジェクト・インスタンスを渡すためのサポート

Page 42: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでのオブジェクト・サポート

概要および新機能 1-9

■ SQL文の出力を受け取る変数として、オブジェクト参照およびオブジェクト・インスタンスを宣言するためのサポート

■ データベースからオブジェクト参照およびオブジェクト・インスタンスをフェッチするためのサポート

■ オブジェクトのインスタンスと参照を戻す SQL文のプロパティを記述(ディスクライブ)するためのサポート

■ オブジェクト・パラメータまたは結果を指定した PL/SQLプロシージャまたはファンクションを記述(ディスクライブ)するためのサポート

■ オブジェクト機能およびリレーショナル機能を同期化するための、コミット・コールとロールバック・コールの拡張

その他の OCIコールは、SQL文を通してアクセスされた後、オブジェクトの操作をサポートするために提供されます。

注意 : 拡張機能および新機能の詳細は、 付録 Fの「Oracle8 OCI新機能」を参照してください。

Page 43: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIの分類

1-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCIの分類OCIの関数は、その機能から主に次の 4つに分類されます。

■ データベース・アクセスを管理し SQL文を処理する、OCIリレーショナル関数

■ Oracle8 Serverから検索したオブジェクトを操作する、OCIナビゲーショナル関数

■ Oracle8の型のデータ属性を操作する、OCIデータ型マッピングおよび操作関数

■ PL/SQLから C言語のコールバックを書き込むために使用する、OCI外部プロシージャ関数

これらの用語は、このマニュアル全体で使用します。

リリース 8.0の新機能Oracle8 OCIは、広範囲にわたる新しい機能と関数を提供します。リリース 7.3のすべてのコールがリリース 8.0でもサポートされていますが、リリース 7.3のコールでは Oracle8の新機能を完全に利用することはできません。

注意 : 拡張機能および新機能の詳細は、 付録 Fの「Oracle8 OCI新機能」を参照してください。

リリース 8.0の新機能とパフォーマンス上の利点を次に示します。

■ クライアント側の処理の増加、およびサーバー側の処理の削減

■ SELECT文結果セット行の暗黙的なプリフェッチ

■ オブジェクトおよびリレーショナル・データの両方に対する APIアクセス

■ ネットワークの往復通信の削減

■ LOB列を処理する機能

■ LOBおよび FILEに対する操作を実行するための一連の APIコール

■ 各国語サポート (national language support:NLS)機能の改善

■ 既存の OCIアプリケーション用の移行パス、および新旧コールを単一アプリケーションに混在させるための機能

■ マルチスレッド環境に対するサポートの改善

■ ナビゲーションによる Oracle8 Server内のオブジェクトへのアクセスを可能にする追加機能

これらの機能については、このガイドの後の章で詳しく説明しています。

OCIのリリース 8.0では、以前のリリースで使用していた APIコールは、すべて完全に新しい APIコールのセットで置き換えられています。さらに、前のリリースでは利用できなかった機能を提供する新しいコールが組み込まれています。

Page 44: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コンパイルおよびリンク

概要および新機能 1-11

関連項目 : 既存のルーチンを置き換えるための新しいコールの詳細は、 A-2ページの「廃止された OCIルーチン」を参照してください。

OCIコールの全リストは、第 13章および第 14章、第 15章、第 16章を参照してください。

使用されなくなった、または廃止された OCIコール使用されなくなったまたは廃止された OCIコールのリストは、付録 Aを参照してください。

コンパイルおよびリンクオラクル社では、一般に普及しているほとんどのサード・パーティのコンパイラをサポートしています。OCIプログラムのリンクの詳細は、システムによって異なります。特定のプラットフォームでの OCIアプリケーションのコンパイルとリンクの詳細は、使用中のシステムに関する Oracleマニュアルとインストレーション・ガイドを参照してください。

Page 45: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コンパイルおよびリンク

1-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

Page 46: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラミングの基本 2-1

2OCIプログラミングの基本

この章では、Oracleコール・インタフェースを使用してプログラムを作成する際に必要となる基本概念の概要を説明します。

この章では、次のトピックで構成されています。

■ 概要

■ OCIプログラム構造

■ OCIデータ構造

■ ハンドル

■ 記述子およびロケータ

■ OCIプログラミング・ステップ

■ 初期化および接続、セッション作成

■ SQL文の処理

■ コミットまたはロールバック

■ アプリケーションの終了

■ エラー処理

■ その他のコーディング・ガイドライン

■ OCIプログラムでの PL/SQL使用

Page 47: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

概要

2-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

概要この章では、OCIアプリケーションの開発における基本的な概念とプロシージャについて説明します。この章を読み終えると、基本的な OCIアプリケーションの理解と作成に必要な手段をほとんど獲得したことになります。

新規ユーザーは、この章に示す情報に対して特に注意する必要があります。なぜならこの章は、このガイドで説明する残りの項目を理解するための基本となるからです。

この章で紹介している情報は、後半の章の情報で補足されています。具体的には、この章を読んだ後、引き続き次のいずれかの章またはすべての章に進むことができます。

■ 第 3章 : OCI内部データ型および外部データ型の詳細

■ 第 4章 : SQL文の処理

■ 第 5章 : バインディングおよび定義の詳細

■ 第 6章 : OCIDescribe()コール

■ 第 7章 : OCIの拡張概念および拡張テクニック

■ 第 8~ 12章 : Oracle8 Serverのオブジェクト能力を有効に利用するための OCIアプリケーションの書き方

■ 第 13章 : 記述および構文、パラメータを含む、OCIリレーショナル関数コールの完全なリスト

■ 付録 D: コード例

この章は、以下の項目に大きく分けられています。

■ OCIプログラム構造 - OCIアプリケーションの基本構造と作成の大まかなステップを説明。

■ OCIデータ構造 - ハンドルおよび記述子、ロケータについて説明。

■ OCIプログラミング・ステップ - OCIアプリケーションのコーディングに必要な各ステップを詳しく説明。

■ エラー処理 - OCIアプリケーションでのエラー処理を説明。

■ その他のコーディング・ガイドライン - OCIアプリケーションのコーディング時に役立つその他の注意事項を説明。

■ OCIプログラムでの PL/SQL使用 - OCIアプリケーションで PL/SQLを扱う際の重要事項を説明。

OCIプログラム構造OCIアプリケーションの一般的な目的は、Oracle Serverに接続して何らかのデータ交換を行い、必要なデータ処理を行うことです。特定の作業を柔軟な順序で実行できる一方、すべての OCIアプリケーションは、特定のステップに従う必要があります。

Page 48: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラム構造

OCIプログラミングの基本 2-3

OCIでは以下のプログラム基本構造を採用しています。

1. OCIプログラミング環境およびプロセスの初期化

2. 必要なハンドラの割当ておよびサーバー接続とユーザー・セッションの確立

3. サーバーへの SQL文の発行、および必要なアプリケーション・データ処理の実行

4. 再利用しない文とハンドルの解放、準備済みの文の再実行、または新しい文の準備

5. ユーザー・セッションおよびユーザー接続の終了

図 2-1は、OCIアプリケーションのステップの流れを示しています。各ステップの詳細は2-14ページの「OCIプログラミング・ステップ」を参照してください。

図 2-1基本的な OCIプログラムの流れ

図 2-1および 2-3ページのプログラム基本構造 1~ 5のステップ・リストは、OCIプログラミングを簡潔に一般化したものであることに注意してください。これらには、プログラムの機能性に応じてさまざまなバリエーションが考えられます。実際には、より洗練された機能(複数トランザクションの管理、オブジェクトの使用など)を装備している OCIアプリケーションには、その他のステップが必要になります。

いったん OCIプロセスが初期化されると、次の図のように複数の環境を作成するかどうかをアプリケーションから選択できます。

Page 49: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIデータ構造

2-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

図 2–2 OCIプロセスでの複数環境

注意 : OCIアプリケーションには、アクティブな接続および文を 1つ以上含むことができます。

関連項目 : オブジェクトのアクセスおよび操作の詳細は第 8章を参照してください。

OCIデータ構造ハンドルと記述子は、OCIアプリケーション内で定義される明確でないデータ構造であり、明示的な割当てコールによって直接割り当てるか、その他の OCI関数を使用して暗黙的に割り当てることができます。

7.x アップグレードの注意 : 7.x OCIアプリケーションを作成した経験のあるプログラマは、大部分の OCIコールに使用されるこれらの新しいデータ構造に慣れる必要があります。

ハンドルおよび記述子を使用して、データまたは接続、アプリケーション動作に関係する情報を格納します。ハンドルについては、次のページで詳しく定義します。記述子の詳細は、2-11ページの「記述子およびロケータ」を参照してください。

Page 50: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ハンドル

OCIプログラミングの基本 2-5

ハンドルほとんどの場合、Oracle8 OCIコールのパラメータ・リストにはハンドルが1つ以上含まれています。ハンドルとは、OCIライブラリによって割り当てられる記憶域を指す明確でないポインタです。ハンドルを使用すると、コンテキストや接続に関する情報を格納できます(環境コンテキスト・ハンドルやサービス・コンテキスト・ハンドルなど)。また、他の OCI関数やデータに関する情報も格納できます(エラー・ハンドルや記述ハンドルなど)。つまり、ハンドルを使用するとアプリケーションではなくライブラリでこのデータを維持できるため、プログラミングが簡単になります。

ほとんどの OCIアプリケーションでは、ハンドルに格納されている情報へのアクセスが必要となります。この情報へは、属性の入手および設定のための OCIコールである、OCIAttrGet()および OCIAttrSet()を使ってアクセスします。

関連項目 : ハンドル属性の詳細は、2-9ページの「ハンドル属性」を参照してください。

次の表は、OCI用に定義されているハンドルを示しています。各々のハンドル型については、OCIコールでハンドル型を識別するために使用される、Cデータ型およびハンドル型定数をリストしています。

ハンドルの割当てと解放アプリケーションでは、すべてのハンドル(バインド・ハンドルと定義ハンドルは除く)が、特定の環境ハンドルに対して割り当てられます。環境ハンドルをパラメータの 1つとし

表 2–1 OCIハンドル型

C型 説明 ハンドル型

OCIEnv OCI環境ハンドル OCI_HTYPE_ENV

OCIError OCIエラー・ハンドル OCI_HTYPE_ERROR

OCISvcCtx OCIサービス・コンテキスト・ハンドル OCI_HTYPE_SVCCTX

OCIStmt OCI文ハンドル OCI_HTYPE_STMT

OCIBind OCIバインド・ハンドル OCI_HTYPE_BIND

OCIDefine OCI定義ハンドル OCI_HTYPE_DEFINE

OCIDescribe OCI記述ハンドル OCI_HTYPE_DESCRIBE

OCIServer OCIサーバー・ハンドル OCI_HTYPE_SERVER

OCISession OCIユーザー・セッション・ハンドル OCI_HTYPE_SESSION

OCITrans OCIトランザクション・ハンドル OCI_HTYPE_TRANS

OCIComplexObject OCI複合オブジェクト検索 (COR)ハンドル OCI_HTYPE_COMPLEXOBJECT

OCISecurity OCIセキュリティ・サービス・ハンドル OCI_HTYPE_SECURITY

Page 51: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ハンドル

2-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

て、ハンドル割当てコールに渡します。こうして、割り当てられたハンドルは、その特定の環境に固有のものとなります。

バインド・ハンドルおよび定義ハンドルは、文ハンドルを親として割り当てられ、そのハンドルによって表される文についての情報を含みます。

注意 : バインド・ハンドルおよび定義ハンドルは、OCIライブラリにより暗黙的に割り当てられるため、ユーザーからの割当ては不要です。

図 2-3は、さまざまなハンドル型間の関係を示しています。

図 2-3ハンドルの階層 :

ユーザーが割り当てるすべてのハンドルは、環境ハンドルを除いて、OCIハンドル割当てコールである OCIHandleAlloc()を使用して割り当てられる必要があります。環境ハンドルは、OCIEnvInit()のコールによって割り当てられ、初期化されます。このコールはすべてのOCIアプリケーションで必要です。

アプリケーションは、ハンドルが不要になった時点で全ハンドルを解放する必要があります。ハンドルは OCIHandleFree()関数によって解放されます。

注意 : 親ハンドルが解放されると、それに対応付けられた子ハンドルもすべて解放され、それ以降使用できなくなります。たとえば、文ハンドルが解放されると、それに対応付けられたバインド・ハンドルおよび定義ハンドルも解放されます。

ハンドルを使うことにより、グローバル変数は不要になります。また、エラー報告が簡単になります。エラー・ハンドルは、エラーと診断情報を戻すために使用します。

Page 52: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ハンドル

OCIプログラミングの基本 2-7

関連項目 : OCIハンドルの割当てと使用方法を説明するコード例は、付録 Dの最初のプログラム例を参照してください。

以降の項では、各種のハンドルについて詳しく説明します。

環境ハンドル環境ハンドルは、すべての OCI関数を呼び出すコンテキストを定義します。各環境ハンドルには、メモリー・キャッシュがあり、これによって、それぞれ独自の環境を持つ各スレッドで迅速なメモリー管理ができます。複数のスレッドで単一の環境を共有する場合、スレッドはキャッシュへのアクセスをブロックする場合があります。

環境ハンドルは、parenthパラメータとして OCIHandleAlloc()コールに渡されます。このコールは、バインド・ハンドルと定義ハンドルを除くすべてのハンドル型を割り当てます。

エラー・ハンドルエラー・ハンドルは、ほとんどの OCIコールにパラメータとして渡されます。エラー・ハンドルは、OCI操作中に発生したエラーについての情報をメンテナンスします。コールでエラーが発生した場合、エラー・ハンドルを OCIErrorGet()に渡して、発生したエラーに関する追加情報を取得することができます。

エラー・ハンドルの割当ては、OCIアプリケーションの最初のステップの 1つです。

サービス・コンテキスト・ハンドルとそれに対応付けられたハンドルサービス・コンテキスト・ハンドルは、サーバーに対する OCIコールの操作コンテキストを決定する属性を定義します。サービス・コンテキスト・ハンドルを使用する際は、その前にOCIHandleAlloc()または OCILogon()によって、割当てと初期化を行う必要があります。

サービス・コンテキストには、次の図のように、サーバー接続およびユーザー・セッション、トランザクションを表す 3つの追加ハンドルが含まれています。

図 2–4 サービス・コンテキストのコンポーネント

■ サーバー・ハンドルは、データ・ソースを識別します。これは、接続指向のトランスポート・メカニズムによって物理接続に変換されます。

Page 53: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ハンドル

2-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

■ ユーザー・セッション・ハンドルは、ユーザーのロールおよび権限(ユーザーのセキュリティ・ドメインとも呼ばれる)、コールを実行するための操作コンテキストを定義します。

■ トランザクション・ハンドルは、SQL操作を実行するためのトランザクションを定義します。トランザクション・コンテキストには、フェッチ状態やパッケージのインスタンス化などの、ユーザー・セッション状態の情報が含まれています。

この方法によるサービス・コンテキストの分析は、拡張性を提供し、プログラマは、洗練された 3層アプリケーションとトランザクション処理 (TP)モニターを作成して、複数のアプリケーション・サーバーと異なるトランザクション・コンテキスト上の複数のユーザーの要求を実行できます。

データベース接続ごとに常時単一ユーザー・セッションだけを維持するアプリケーションでは、OCILogon()をコールして、サービス・コンテキストとそれに対応付けられたハンドルを割り当てることができます。

より複雑なセッション管理を必要とするアプリケーションでは、サービス・コンテキストを明示的に割り当てる必要があります。また、サーバー・ハンドルおよびユーザー・セッション・ハンドルは、それぞれ OCIServerAttach()および OCISessionBegin()をコールして、サービス・コンテキストへ明示的に設定する必要があります。アプリケーションは、トランザクションの明示的な定義を必要とするか、または、そのアプリケーションがデータベースに変更を行ったときに作成された暗黙のトランザクションで処理できる場合もあります。

関連項目 : トランザクションの詳細は、7-3ページの「トランザクション」を参照してください。

サーバー接続およびユーザー・セッションの確立の詳細は、2-16ページの「初期化および接続、セッション作成」および 7-11ページの「ユーザー認証およびパスワードの管理」を参照してください。

Page 54: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ハンドル

OCIプログラミングの基本 2-9

文ハンドルおよびバインド・ハンドル、定義ハンドル文ハンドルは、SQL文または PL/SQL文と、それぞれに対応付けられた属性を識別するコンテキストです。

入力変数に関する情報は、バインド・ハンドルに格納されます。OCIライブラリでは、OCIBindByName()または OCIBindByPos()関数でバインドされた各プレースホルダのバインド・ハンドルが割り当てられます。ユーザーがバインド・ハンドルを割り当てる必要はありません。バインド・ハンドルは、バインド・コールによって暗黙的に割り当てられます。

問合せでフェッチされ戻されたデータは、定義ハンドルの指定に従って変換され、格納されます。また OCIライブラリによって、OCIDefineByPos()で定義された各出力変数の定義ハンドルが割り当てられます。ユーザーが定義ハンドルを割り当てる必要はありません。定義ハンドルは、定義コールによって暗黙的に割り当てられます。

記述ハンドル記述ハンドルは、OCI記述コールである OCIDescribeAny()によって使用されます。このコールは、関数やプロシージャなどデータベース内のスキーマ・オブジェクトに関する情報を取得します。このコールでは、記述されているオブジェクトに関する情報とともに、パラメータの 1つとして記述ハンドルが使用されます。コールが完了すると、記述ハンドルには、そのオブジェクトに関する情報が含まれています。OCIアプリケーションでは、パラメータ記述子の属性を通して記述情報を取得します。

関連項目 :OCIDescribeAny()関数の使用方法の詳細は、 第 2章の「OCIプログラミングの基本」を参照してください。

複合オブジェクト検索ハンドル複合オブジェクト検索 (complex object retrieval:COR)ハンドルは、Oracle8 Server内のオブジェクトを操作する一部の OCIアプリケーションによって使用されます。このハンドルには、他のオブジェクトによって参照されるオブジェクトの検索について OCIに指示するCOR記述子が含まれています。

関連項目 : 複合オブジェクト検索および複合オブジェクト検索ハンドルの詳細は、8-20ページの「複合オブジェクト検索」を参照してください。

セキュリティ・ハンドルセキュリティ・ハンドルおよび OCIコールを使った Oracle セキュリティサービス アプリケーションのプログラミングの詳細は、『Oracle Security Serverガイド』を参照してください。

ハンドル属性すべての OCIハンドルには、それに対応する属性があります。属性は、ハンドルに格納されているデータを表します。ハンドル属性は、属性取得コール OCIAttrGet()を使用して読み込

Page 55: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ハンドル

2-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

むことができます。また、属性設定コール OCIAttrSet()を使用して、変更することもできます。

たとえば、次の文では OCI_ATTR_USERNAME属性に書き込むことでトランザクション・ハンドルにユーザー名を設定しています。

text username[] = "scott";err = OCIAttrSet ((dvoid*) mysessp, OCI_HTYPE_SESSION, (dvoid*) username, (ub4) strlen(username), OCI_ATTR_USERNAME, (OCIError *) myerrhp);

次の一連の文では、ハンドルで処理された最後の OCI関数の関数コード(この場合はバインド・ハンドル)を、OCIAttrGet()を使用して読み込んでいます。

ub4 fcode = 0;OCIBind *mybndp;err = OCIAttrGet( (dvoid*) mybndp, OCI_HTYPE_BIND, (dvoid*) &fcode, (ub4) 0, OCI_ATTR_FNCODE,(OCIError *) myerrhp);

コールの前に特定のハンドル属性を設定することが必要な OCI関数もあります。たとえば、ユーザーのログイン・セッションを確立するために OCISessionBegin()をコールする場合は、コールの実行前にユーザー名とパスワードをユーザー・セッション・ハンドルに設定する必要があります。

完了後、ハンドル属性に有用なデータを戻す OCI関数もあります。たとえば、OCIStmtExecute()をコールして SQL問合せを実行した場合は、選択リスト項目に関する記述情報が文ハンドルに戻されます。

全ハンドル属性のリストは、 付録 Bの「ハンドルおよび記述子の属性」を参照してください。

関連項目 : 設定中のユーザー名とパスワードのハンドル属性を示した例は、13-11ページの OCIAttrGet()を参照してください。

Page 56: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

記述子およびロケータ

OCIプログラミングの基本 2-11

ユーザー・メモリの割当て環境ハンドルを初期化する OCIEnvInit()コール、および汎用ハンドル割当てコール(OCIHandleAlloc())、記述子 /ロケータ割当てコール (OCIDescriptorAlloc())のパラメータ・リストには、xtramem_szパラメータが含まれます。このパラメータは、そのハンドルとともに割り当てるユーザー・メモリー量を指定するのに使用します。

通常、アプリケーションは、このパラメータを使用して、そのハンドルと同じ存続期間をもつアプリケーション定義の構造体を割り当てます。この構造はアプリケーション「bookkeeping」 またはコンテキスト情報の保存に使用できます。

xtramem_szパラメータを使用すると、アプリケーションは、各ハンドルの割当てや割当て解除にあわせて、メモリーを明示的に割当てたり解除したりする必要はありません。メモリーはハンドルとともに割り当てられるため、ハンドルを解放するとユーザーのデータ構造も解放されます。

記述子およびロケータOCIの記述子とロケータは、特定のデータ情報を維持する不明確なデータ構造です。OCIには、6種類の記述子とロケータがあります。これらの記述子とロケータ、および Cデータ型、その型の記述子を OCIDescriptorAlloc()のコール内で割り当てるために使用する OCI型定数を次の表に示します。OCIDescriptorFree()関数は、記述子とロケータを解放します。

表 2–2 記述子の種類

C型 説明 OCI型定数

OCISnapshot スナップショット記述子 OCI_DTYPE_SNAP

OCILobLocator LOBデータ型ロケータ OCI_DTYPE_LOB

OCILobLocator FILEデータ型ロケータ OCI_DTYPE_FILE

OCIParam 読込み専用パラメータ記述子 OCI_DTYPE_PARAM

OCIRowid ROWID記述子 OCI_DTYPE_ROWID

OCIComplexObjectComp 複合オブジェクト記述子 OCI_DTYPE_COMPLEXOBJECTCOMP

OCIAQEnqOptions アドバンスト・キューイング・エンキュー・オプション

OCI_DTYPE_AQENQ_OPTIONS

OCIAQDeqOptions アドバンスト・キューイング・デキュー・オプション

OCI_DTYPE_AQDEQ_OPTIONS

OCIAQMsgProperties アドバンスト・キューイング・メッセージ・プロパティ

OCI_DTYPE_AQMSG_PROPERTIES

OCIAQAgent アドバンスト・キューイング・エージェント

OCI_DTYPE_AQAGENT

Page 57: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

記述子およびロケータ

2-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

注意 : OCILobLocatorは単精度浮動小数点数 C型ですが、このロケータは内部 LOBおよび外部 LOB用には異なる OCI型定数で割り当てられます。後述の LOBロケータの項で、この違いについて説明します。

各記述子型の主な用途は次のとおりです。各記述子型については、後述の項で説明します。

■ OCISnapshot - 文の実行時に使用。

■ OCILOBLocator - LOBコール (OCI_DTYPE_LOB)または FILEコール(OCI_DTYPE_FILE)で使用。

■ OCIParam - 記述コールで使用。

■ OCIRowid - ROWID値のバインドまたは定義で使用。

■ OCIComplexObjectComp - 複合オブジェクト検索で使用。

■ OCIAQEnqOptions、OCIAQDeqOptions、OCIAQMsgProperties、OCIAQAgent - アドバンスト・キューイングで使用。

スナップショット記述子スナップショット記述子は、コール実行関数 OCIStmtExecute()のオプション・パラメータです。この記述子は、特定のデータベース・スナップショットに対する問合せが実行されることを示します。データベース・スナップショットは、ある特定の時点におけるデータベースの状態を表します。

スナップショット記述子は、OCIDescriptorAlloc()のコールで、OCI_DTYPE_SNAPを typeパラメータとして渡すことによって割り当てられます。

関連項目 : OCIStmtExecute()およびデータベース・スナップショットの詳細は、4-6ページの「実行スナップショット」を参照してください。

LOB/FILEデータ型ロケータLOB(ラージ・オブジェクト )は、最大 4GB(ギガバイト )のバイナリ (BLOB)または文字(CLOB)データを保持できる Oracleデータ型です。データベース内では、LOBロケータと呼ばれる明確でないデータ構造が、データベース行の LOB列、またはオブジェクトの LOB属性の位置に格納されます。このロケータは、別の位置に格納されている実際の LOB値を指すポインタとして機能します。

OCI LOBロケータは、LOB(BLOBまたは CLOB)または FILE(BFILE)に対する OCI操作の実行に使われます。OCI関数は、実際の LOB値をパラメータとして受け取りません。すべての OCIコールは、LOBロケータに対して作用します。この記述子 OCILobLocatorは、FILEへの操作にも使われます。

LOBロケータは、OCIDescriptorAlloc()のコールで、BLOBまたは CLOBの typeパラメータとしての OCI_DTYPE_LOB、および BFILEの OCI_DTYPE_FILEを渡すことによって割り当てられます。

Page 58: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

記述子およびロケータ

OCIプログラミングの基本 2-13

警告 : これらの 2つの LOBロケータ型を互いに交換することはできません。BLOBかCLOBをバインドまたは定義するとき、アプリケーションは、OCI_DTYPE_LOBを使用してロケータが適切に割り当てられているか注意してください。同様に、BFILEをバインドまたは定義するとき、アプリケーションは、OCI_DTYPE_FILEを使用してロケータが割り当てられていることを確認してください。

OCIアプリケーションでは、選択リストの要素として LOB列または属性を含む SQL文を発行することによって、サーバーから LOBロケータを検索できます。この例では、アプリケーションは最初に LOBロケータを割り当て、次にそれを使用して出力変数を定義します。

同じように、LOBロケータは、SQL文で LOBとプレースホルダとの間の関連付けを行うバインド操作の一部として使用できます。

LOBロケータのデータ型 (OCILobLocator)は、Oracle7 Serverに接続している場合にはデータ型として無効です。

関連項目 : OCI LOB操作の詳細は、7-23ページの「LOBおよび FILE操作」を参照してください。

パラメータ記述子OCIアプリケーションは、パラメータ記述子を使用して、選択リスト列またはスキーマ・オブジェクトについての情報を取得します。この情報は、記述操作を通して取得されます。

パラメータ記述子の割当てが、OCIDescriptorAlloc()を使用して行われることはありません。パラメータ記述子は、OCIParamGet()コールを使用してパラメータの位置を指定することによって、記述ハンドルまたは文ハンドル、複合オブジェクト検索ハンドルの属性としてのみ取得できます。

関連項目 : パラメータ記述子の取得と使用方法の詳細は、第 2章の「OCIプログラミングの基本」および 4-8ページの「選択リスト項目の記述」を参照してください。

ROWID記述子ROWID記述子は、Oracle ROWIDを検索して使用する必要があるアプリケーションが使用します。ROWIDのサイズと構造は、Oracle7から Oracle8になって変更されており、ユーザーに対して不明確です。Oracle8 OCIを使用して ROWIDを操作するために、アプリケーションでは SQL選択リスト内の位置に対応する ROWID記述子を定義し、ROWIDを検索してその記述子に格納できます。この同じ記述子を、後で INSERT文またはWHERE句の入力変数にバインドできます。

複合オブジェクト記述子複合オブジェクト記述子およびその使用方法の詳細は、8-20ページの「複合オブジェクト検索」を参照してください。

Page 59: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラミング・ステップ

2-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

アドバンスト・キューイング記述子アドバンスト・キューイングおよびそれに関連する記述子の詳細は、7-39ページの「OCIおよびアドバンスト・キューイング」を参照してください。

ユーザー・メモリーの割当てOCIDescriptorAlloc()コールには、そのパラメータ・リストに xtramem_szパラメータが含まれています。このパラメータは、記述子またはロケータとともに割り当てるユーザー・メモリー量を指定するのに使用します。

通常、アプリケーションは、このパラメータを使用して、記述子またはロケータと同じ存続期間を持つアプリケーション定義の構造体を割り当てます。この構造はアプリケーション「bookkeeping」 またはコンテキスト情報の保存に使用できます。

xtramem_szパラメータを使用すると、アプリケーションでは、各記述子またはロケータを割り当てたり割当て解除するたびに、メモリーを明示的に割り当てたり、割当て解除する必要はありません。メモリーは記述子またはロケータとともに割り当てられるため、記述子またはロケータを解放すると (OCIDescriptorFree()により )、ユーザーのデータ構造も解放されます。

OCIHandleAlloc()コールには、ハンドルと同じ存続期間を持つユーザー・メモリーを割り当てるための同様のパラメータがあります。

OCIEnvInit()コールには、環境ハンドルと同じ存続期間を持つユーザー・メモリーを割り当てるための同様のパラメータがあります。

OCIプログラミング・ステップこの後の各項では、OCIアプリケーションで実行する各ステップについて詳しく説明します。いくつかのステップは、オプションです。たとえば、文が問合せでない場合には、選択リスト項目を記述または定義する必要はありません。

注意 : SQL文処理のための OCIコールの使用方法を説明するコード例は、付録 Dの最初のプログラム例を参照してください。

実行時に動的にデータを供給する特殊なケースの詳細は、7-16ページの「ランタイム・データ割当てとピース単位操作」を参照してください。

構造の配列を伴う操作に必要な特別な配慮の詳細は、5-16ページの「構造体の配列」を参照してください。

OCIプログラム内での SQL文の処理に伴うステップのアウトラインの詳細は、2-24ページの「エラー処理」を参照してください。

OCIを使ったマルチスレッド・アプリケーションのプログラミングの詳細は、7-13ページの「スレッド・セーフティ」を参照してください。

SQL文の種類の詳細は、1-4ページの「SQL文」を参照してください。

Page 60: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラミング・ステップ

OCIプログラミングの基本 2-15

次の各項では、リリース 8.0 OCIアプリケーションで必要なステップについて説明します。

■ 初期化および接続、セッション作成

■ SQL文の処理

■ コミットまたはロールバック

■ アプリケーションの終了

■ エラー処理

また、OCI関数のいずれか、またはすべてのステップ間で、アプリケーション固有の処理も発生します。

7.x アップグレードの注意 : OCIのプログラマは、明示的な解析ステップが OCIプログラムで不要になったことに注意してください。これは、8.0のアプリケーションでは、DML文と DDL文の両方に対して実行コマンドを発行する必要があるということです。

Page 61: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

初期化および接続、セッション作成

2-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

初期化および接続、セッション作成この項では、Oracle8 OCI環境を初期化し、サーバーとの接続を確立して、ユーザーがデータベースに対してアクションを実行できるように許可する方法を説明します。

この項では、OCI環境を初期化するための 3つの主要なステップについて説明します。

1. OCIプロセスの初期化

2. ハンドルおよび記述子の割当て

3. アプリケーションの初期化および接続、許可

さらに、この項では OCIアプリケーションの接続モードについても説明します。

OCIプロセスの初期化プロセス初期化コールである OCIInitialize()は、どの OCIコールよりも先に呼び出す必要があります。このコールの modeパラメータは、アプリケーションがスレッド環境で実行されるか (mode = OCI_THREADED)、およびオブジェクトを使用するかどうか (mode = OCI_OBJECT)を指定します。アプリケーションがバインディング・オブジェクトおよび定義オブジェクトになる場合、もしくはアプリケーションが OCIのオブジェクト・ナビゲーション・コールを使用する場合には、オブジェクト・モードでの初期化が必要です。

プログラムでは、これらの機能のどちらも使用しない (mode = OCI_DEFAULT)か、またはオプションを縦線で区切って両方を使用するか (mode = (OCI_THREADED | OCI_OBJECT))のどちらかを選択できます。

また、OCIInitialize()コールでは、ユーザー定義のメモリー管理関数を指定できます。

関連項目 : コールの詳細は、13-70ページのの OCIInitialize()を参照してください。

OCIを使ったマルチスレッド・アプリケーションの書き方の詳細は、7-13ページの「スレッド・セーフティ」を参照してください。

Page 62: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

初期化および接続、セッション作成

OCIプログラミングの基本 2-17

ハンドルおよび記述子の割当てOracleは、ハンドルと記述子を割り当てたり割当解除するために、OCI関数を提供します。ハンドルは、OCIHandleAlloc()を使用して割り当てた後、OCIコールに渡す必要があります(OCIBindByPos()のように、OCIコールがユーザーに代わってハンドルを割り当てる場合は除く )。

OCIHandleAlloc()を使用して、次の種類のハンドルを割り当てることができます。

■ エラー・ハンドル

■ サービス・コンテキスト・ハンドル

■ 文ハンドル

■ 記述ハンドル

■ サーバー・ハンドル

■ ユーザー・セッション・ハンドル

■ トランザクション・ハンドル

■ 複合オブジェクト検索ハンドル

アプリケーションの機能に応じて、これらのハンドルのいくつかまたはすべてを割り当てる必要があります。

関連項目 : このコールの使用方法の詳細は、13-66ページのの OCIHandleAlloc()の説明を参照してください。

アプリケーションの初期化および接続、セッション作成アプリケーションでは、OCIInitialize()をコールした後、OCIEnvInit()をコールして OCI環境ハンドルを初期化する必要があります。このステップに従ってサーバー接続を確立し、ユーザー・セッションを開始する場合、シングル・ユーザーで単一接続、あるいは複数セッションまたは複数接続という 2通りのオプションがあります。

オプション 1: シングル・ユーザー、単一接続このオプションは、単純化されたログオン方法です。

アプリケーションが各データベース接続につき常時シングル・ユーザー・セッションをメンテナンスする場合、このアプリケーションは OCIの簡易ログオン・プロシージャを利用することができます。

アプリケーションから OCILogon()をコールすると、OCIライブラリは、渡されたサービス・コンテキスト・ハンドルを初期化し、次に、関数にユーザー名とパスワードを渡したユーザー用に、指定されたサーバーとの接続を作成します。

OCILogon()のコール例を次に示します。

Page 63: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

初期化および接続、セッション作成

2-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCILogon(envhp, errhp, &svchp, "scott", nameLen, "tiger", passwdLen, "oracle8", dbnameLen)

このコールのパラメータには、サービス・コンテキスト・ハンドル(これから初期化される)およびユーザー名、ユーザーのパスワード、接続を確立するために使われるデータベースの名前を含むことができます。また、この関数によって、サーバー・ハンドルおよびユーザー・セッション・ハンドルも暗黙的に割り当てられます。

アプリケーションがこのログオン方法を使用する場合、サービス・コンテキストおよびサーバー、ユーザー・セッション・ハンドルはすべて「読込み専用」となります。これは、OCIAttrSet()でサービス・コンテキスト・ハンドルの適切な属性を変更することにより、アプリケーションからセッションまたはトランザクションを切り替えられないことを意味します。

アプリケーションで OCILogon()を使用してセッションおよび権限を作成した場合は、OCILogoff()を使用してそれらを終了する必要があります。

オプション 2: 複数のセッションまたは接続このオプションでは、明示的な連結(アタッチ)コールおよび開始セッション・コールを使用します。

アプリケーションで、データベース接続での複数のユーザー・セッションを維持する必要がある場合、アプリケーションは、別のコールのセットを使用してセッションおよび接続を設定しなければなりません。これには、サーバーおよび開始セッションに連結するための特定のコールが含まれます。

■ OCIServerAttach()では、OCI操作用のデータ・ソースにアクセスするためのアクセス・パスを作成。

■ OCISessionBegin()では、特定のサーバーに対するユーザーのセッションを確立します。ユーザーがサーバーに対する操作を実行するには、このコールが必須。

これらのコールにより、データベースに対して SQL文および PL/SQL文を実行できる操作環境が設定されます。これらのコールを実行する前に、必ずデータベースを起動して実行状態にしておく必要があります。そうしないと、これらのコールは失敗します。

これらのコールの詳細は、第 13章を参照してください。複数セッションおよびトランザクション、接続のメンテナンスの詳細は、 第 7章の「OCIプログラミングの応用」を参照してください。

例OCI初期化コールの使用例を次に示します。この例では、サーバー・コンテキストを作成し、それをサービス・ハンドルに設定します。次に、ユーザー・セッション・ハンドルを作成し、データベース・ユーザー名とパスワードを使用してそれを初期化します。簡潔な表にするため、エラー・チェックは含まれていません。

main(){

Page 64: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

初期化および接続、セッション作成

OCIプログラミングの基本 2-19

OCIEnv *myenvhp; /* the environment handle */OCIServer *mysrvhp; /* the server handle */OCIError *myerrhp; /* the error handle */OCISession *myusrhp; /* user session handle */

(void) OCIInitialize (OCI_THREADED | OCI_OBJECT, (dvoid *)0, mymalloc, myrealloc, myfree); /* initialize the mode to be the threaded and object environment */

(void) OCIEnvInit (&myenvhp, OCI_DEFAULT, 0, (dvoid **)0);

(void) OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&mysrvhp, OCI_HTYPE_SVR, 0, (dvoid **) 0);

/* allocate a server handle */

(void) OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&myerrhp, OCI_HTYPE_ERROR, 0, (dvoid **) 0);

/* allocate an error handle */

(void) OCIServerAttach (mysrvhp, myerrhp, (text *)"inst1_alias", strlen ("inst1_alias"), OCI_DEFAULT);

/* create a server context */

(void) OCIAttrSet ((dvoid *)mysvchp, OCI_HTYPE_SVCCTX, (dvoid *)mysrvhp, (ub4) 0, OCI_ATTR_SERVER, myerrhp);

/* set the server context in the service context */

(void) OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&myusrhp, OCI_HTYPE_SESSION, 0, (dvoid **), 0);

/* allocate a user session handle */

(void) OCIAttrSet ((dvoid *)myusrhp, OCI_HTYPE_SESSION, (dvoid *)"scott", (ub4)strlen("scott"), OCI_ATTR_USERNAME, myerrhp);

/* set username attribute in user session handle */

(void) OCIAttrSet ((dvoid *)myusrhp, OCI_HTYPE_SESSION, (dvoid *)"tiger", (ub4)strlen("tiger"), OCI_ATTR_PASSWORD, myerrhp);

/* set password attribute in user session handle */

Page 65: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

複数の接続とハンドルの説明

2-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

(void) OCISessionBegin ((dvoid *) mysvchp, myerrhp, myusrhp, OCI_CRED_RDBMS, OCI_DEFAULT);

(void) OCIAttrSet ( (dvoid *)mysvchp, OCI_HTYPE_SVCCTX, (dvoid *)myusrhp, (ub4) 0, OCI_ATTR_SESSION, myerrhp); /* set the user session in the service context */

複数の接続とハンドルの説明この項では、複数のユーザー、および複数のサーバー接続、マルチスレッドを管理するアプリケーションのシナリオ例を提示します。この例は、アプリケーションなどをプログラミングするときの問題についていくつかを理解できることを目的にしています。

接続の例アプリケーションが、ユーザー 1およびユーザー 2という 2人のユーザーをサポートしています。このアプリケーションは次のステップを完了しました。

■ OCIInitialize()のコールを使用して、OCI_THREADEDモードで OCIプロセスを初期化。

■ OCIEnvInit()を使用して、単一の環境ハンドルを割り当てた。

■ 2つの異なるスレッドで、同じマシン上にある 2つの異なるデータベース (DB1と DB2)に接続した。

ユーザー 1は、次のアクションを実行します。

■ DB1に連結。

■ 2つの新規トランザクション (TX1と TX2)を開始。

■ 別々のスレッドで、それぞれのトランザクションの文を同時に準備して実行 (TX1ではSTMT1、TX2では STMT2)。

■ TX1と TX2をコミット。

■ DB1から連結を解除。

ユーザー 2は、次のアクションを実行します。

■ DB2に連結。

■ 2つの新規トランザクション (TX3と TX4)を開始。

■ それぞれのトランザクションの文を同時に準備して実行 (TX3では STMT3、TX4ではSTMT4)。

■ TX3と TX4をコミット。

■ DB2から連結を解除。

Page 66: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

複数の接続とハンドルの説明

OCIプログラミングの基本 2-21

次の Q&Aは、上記のシナリオに関連しています。

Q1. サーバー・ハンドルはいくつ必要ですか ?

A1. DB1と DB2が同じサーバー・マシンにあっても、サーバー・ハンドルは 2つ必要です。それぞれのサーバー・ハンドルはデータベース接続を表し、ハンドル自体の接続文字列によって識別されます。

Q2. サービス・コンテキスト・ハンドルはいくつ必要ですか ?

A2. 4つのサービス・コンテキスト・ハンドルが必要です。各ユーザーは、2つのトランザクションを同時に実行しています。したがって、それぞれのサービス・コンテキストが必要です。2ユーザー × 2トランザクション = 4サービス・コンテキスト・ハンドルになります。各ユーザーが同じトランザクションで文を実行した場合は、1つのサービス・コンテキストだけ必要です。

Q3. ユーザー・セッション・ハンドルはいくつ必要ですか ?

A3. 4つのユーザー・セッション・ハンドルが必要です。各ユーザーは、サーバーごとにユーザー・セッション・ハンドルが必要です。各ユーザーが文を連続して実行した場合は、2つのセッションで十分です。

Q4. トランザクション・ハンドルはいくつ必要ですか ?

A4. 4つのトランザクション・ハンドルが必要です。つまり、同時トランザクションごとに 1つ必要です。ただし、アプリケーションでは、データベースが変更されたときに作成された暗黙のトランザクションを利用し、トランザクション・ハンドル全体を割り当てないですますこともできます。

Q5. この例では、複数の環境ハンドルを使用できますか ?

A5. できます。2つのデータベースが含まれているので、アプリケーションで 2つの環境ハンドルを使用して、各データベースへのアクセスが完全に同時に行われるようにできます。

Q6. 単一の環境でのシングル・ユーザーが、同じデータベースに対して、4つの異なる文を 4つのトランザクションで同時に実行する場合、サーバー・ハンドルはいくつ必要ですか ?

A6. 4つのサーバー・ハンドルが必要です。つまり、同時トランザクションごとに 1つ必要です。1つのサーバー・ハンドルには、一度に最大 1つの未解決のコールが可能です。

Page 67: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQL文の処理

2-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

SQL文の処理SQL文の処理の詳細は、 第 4章の「SQL文の処理」を参照してください。

コミットまたはロールバックアプリケーションは、OCITransCommit()をコールすることにより、データベースへの変更をコミットします。このコールは、サービス・コンテキストをパラメータの 1つとして受け取ります。サービス・コンテキストに現在関連付けられているトランザクションは、変更コミット済みのものです。このトランザクションは、アプリケーションで明示的に作成されたか、または、アプリケーションがデータベースを変更したときに暗黙的に作成されたトランザクションである場合があります。

注意 : OCIExecute()コールの OCI_COMMIT_ON_SUCCESSモードを使うことにより、アプリケーションは各文の実行終了時に選択的にトランザクションをコミットすることができます。

トランザクションをロールバックするには、OCITransRollback()コールを使用します。

通常のログオフ以外の何らかの方法でアプリケーションと Oracleの接続が切断された場合(たとえばネットワークとの接続が切れるなど)、OCITransCommit()をコールしていないと、アクティブ・トランザクションはすべて自動的にロールバックされます。

関連項目 : 暗黙のトランザクションおよびトランザクション処理の詳細は、2-7ページの「サービス・コンテキスト・ハンドルとそれに対応付けられたハンドル」および 7-3ページの「トランザクション」を参照してください。

アプリケーションの終了OCIアプリケーションは、終了する前に、次の 3つのステップを実行しなければなりません。

1. 各セッションに対して OCISessionEnd()をコールし、ユーザー・セッションを終了する。

2. 各データ・ソースに対して OCISessionEnd()をコールし、データ・ソースへのアクセスを終了する。

3. 各ハンドルに対し OCIHandleFree()をコールして明示的に全ハンドルの割当てを解除する、もしくは 4の処理を行う。

4. 環境ハンドルを削除し、環境ハンドルに関連付けられたその他すべてのハンドルの割当てを解除する。

注意 : 親ハンドルが解放されると、それに対応付けられた子ハンドルもすべて自動的に解放されます。

OCIServerDetach()および OCISessionEnd()のコールは、必須ではありません。アプリケーションが OCITransCommit()(トランザクション・コミット)をコールしないで終了すると、保留状態のトランザクションはすべて自動的にロールバックされます。 アプリケーションの

Page 68: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

アプリケーションの終了

OCIプログラミングの基本 2-23

終了時に解放されるハンドルを示す例については、付録 Dの「コード例」の最初のプログラム例を参照してください。

注意 : アプリケーションで OCILogon()による簡易ログオン方法を使用した場合は、OCILogoff()をコールするとセッションが終了し、サーバーとの接続が切断され、サービス・コンテキスト・ハンドルとそれに対応付けられたハンドルが解放されます。ただし、アプリケーションにより割り当てた他のハンドルは、そのアプリケーションから解放しなければなりません。

Page 69: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

エラー処理

2-24 Oracle8コール・インタフェース・プログラマーズ・ガイド

エラー処理OCIファンクション・コールには以下の表 2–3にリストされた一連のリターン・コードが用意されています。これらのコードにより、コールが成功したか、失敗したか(OCI_SUCCESS、OCI_ERRORなど )、もしくはアプリケーションが必要とするその他の情報 (OCI_NEED_DATA、OCI_STILL_EXECUTINGなど )が示されます。大部分の OCIコールは、これらのコードの 1つを返します。例外の詳細は、2-26ページの「他の値を戻す関数」を参照してください。

エラーが発生したことがリターン・コードに示されている場合、アプリケーションではOCIErrorGet()をコールして、Oracle固有のエラー・コードおよびメッセージを検索できます。OCIErrorGet()へのパラメータの 1つは、エラーが発生したコールに渡されたエラー・ハンドルです。

注意 : レコードがなくなるまで (OCI_NO_DATAが戻されます )繰り返し OCIErrorGet()をコールすると、複数のエラー・レコードを検索することができます。OCIErrorGet()⦆は常に最高 1個の診断レコードを戻します。

次のコード例は、付録 Dの「コード例」の最初のプログラム例から抜粋したものですが、OCIファンクション・コールから与えられたエラー・ハンドルおよびリターン・コードを持つエラー情報が戻されます。リターン・コードが OCI_ERRORの場合は、関数は診断情報を出力します。OCI_SUCCESSの場合は、出力はありません。その他のリターン・コードの場合は、リターン・コード情報が出力されます。

STATICF void checkerr(errhp, status)OCIError *errhp;sword status;

{ text errbuf[512]; ub4 buflen;

表 2–3 OCIリターン・コード

OCIリターン・コード 説明

OCI_SUCCESS 関数は正常に終了。

OCI_SUCCESS_WITH_INFO 関数は正常に終了。OCIErrorGet()をコールすると、追加診断情報が戻されます。これには、警告が含まれる場合があります。

OCI_NO_DATA 関数が終了。これ以上データはありません。

OCI_ERROR 関数が失敗。OCIErrorGet()をコールすると、エラーの追加情報が戻されます。

OCI_INVALID_HANDLE 無効なハンドルがパラメータとして渡された。追加診断情報はありません。

OCI_NEED_DATA アプリケーションで、ランタイム・データを提供する必要あり。

Page 70: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

エラー処理

OCIプログラミングの基本 2-25

ub4 errcode;

switch (status) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: (void) printf("Error - OCI_SUCCESS_WITH_INFO\n"); break; case OCI_NEED_DATA: (void) printf("Error - OCI_NEED_DATA\n"); break; case OCI_NO_DATA: (void) printf("Error - OCI_NODATA\n"); break; case OCI_ERROR: (void) OCIErrorGet (errhp, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); (void) printf("Error - %s\n", errbuf); break; case OCI_INVALID_HANDLE: (void) printf("Error - OCI_INVALID_HANDLE\n"); break; case OCI_STILL_EXECUTING: (void) printf("Error - OCI_STILL_EXECUTE\n"); break;default: break; }}

Page 71: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

その他のコーディング・ガイドライン

2-26 Oracle8コール・インタフェース・プログラマーズ・ガイド

他の値を戻す関数一部の関数は、表 2–3にリストされている OCIエラー・コード以外の値を戻します。これらの関数を使用する場合、OUTパラメータからではなく、ファンクション・コールから直接値が戻ることを必ず考慮してください。それぞれの関数と戻り値の詳細は、『ボリューム II』のリストを参照してください。

■ OCICollMax()

■ OCIRawPtr()

■ OCIRawSize()

■ OCIRefHexSize()

■ OCIRefIsEqual()

■ OCIRefIsNull()

■ OCIStringPtr()

■ OCIStringSize()

その他のコーディング・ガイドラインこの項では、Oracleコール・インタフェースを使ってアプリケーションをコーディングする際に注意すべき、その他の要因を説明します。

パラメータの型OCI関数には、整数、ハンドル、文字列など、多様なデータ型のパラメータを使うことができます。パラメータの型によっては、注意しなければならない特別な考慮事項があります。それについては、次の項で説明します。

パラメータのデータ型およびパラメータの引渡し規則の詳細は、OCI用のファンクション・コールについて説明している第 13章の「OCIリレーショナル関数」の概要の項目を参照してください。

アドレス・パラメータアドレス・パラメータでは、変数のアドレスを Oracleに渡します。Cでは、通常スカラー・パラメータを値で渡すので、Cで開発する場合は、パラメータがアドレスであることに注意が必要です。すべてのケースで、ポインタは注意して渡す必要があります。

整数パラメータ2進整数パラメータは、サイズがシステムによって異なる数値です。short型 2進整数パラメータも、サイズがシステムによって異なる数値ですが、サイズはより短くなります。ご使用のシステムでのこれらの整数のサイズについては、システム固有の Oracleマニュアルを参照してください。

Page 72: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

その他のコーディング・ガイドライン

OCIプログラミングの基本 2-27

文字列パラメータ文字列は、アドレス・パラメータの特殊な型です。この項では、文字列アドレス・パラメータに適用される追加規則について説明します。

文字列をパラメータとして渡すことができる各 OCIルーチンには、文字列長のパラメータもあります。このパラメータで文字列の長さを設定する必要があります。

7.x アップグレードの注意 : 旧バージョンの OCIと異なり、リリース 8.0では NULLで終わる文字列の文字列長パラメータ用に -1を渡すことはしないでください。

Nullデータベース列に NULLを挿入する方法はいくつかあります。1つは、INSERT文またはUPDATE文のテキスト中でリテラルNULLを使用する方法です。たとえば、次のようなSQL文があるとします。

INSERT INTO emp (ename, empno, deptno)VALUES (NULL, 8010, 20)

この文では、ENAME列がNULLになります。

別の方法として、OCIバインド・コールで標識変数を使用する方法があります。詳細は、2-28ページの「標識変数」を参照してください。

NULLを挿入するもう 1つの方法は、バッファ長パラメータと最大長パラメータの両方を、バインド・コールで 0(ゼロ )に設定する方法です。

注意 : SQL92要件に従って、定義コールで指定された対応付けられた標識変数を含まない変数に、NULL選択リスト項目をフェッチする試みがなされると Oracle8はエラーを返します。

Page 73: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

その他のコーディング・ガイドライン

2-28 Oracle8コール・インタフェース・プログラマーズ・ガイド

標識変数各バインドと定義 OCIコールには、標識変数(配列を使用する場合は標識変数の配列)を、DML文または PL/SQL文、問合せに関連付けるパラメータがあります。

ホスト言語には NULL値の概念がありません。したがって、標識変数と入力変数を関連付けることによって、関連付けられたプレースホルダが NULLであるかどうかを指定します。データが Oracleに渡されるとき、これらの標識変数の値によって、NULLがデータベース・フィールドに割り当てられているかどうかが判別されます。

出力変数では、標識変数によって、Oracleから戻された値がNULLまたは切り捨てられた値であるかどうかを判別します。NULLフェッチ (OCIStmtFetch()で )あるいは切捨て(OCIStmtExecute() または OCIStmtFetch()で )の場合は、OCIコールはOCI_SUCCESS_WITH_INFOを返します。対応する標識変数は、以降の「出力」項目にリストされている適切な値に設定されます。アプリケーションが対応する OCIDefineByPos()コールでリターン・コード変数を提供すると、OCIはそのリターン・コード変数にORA-01405(NULLフェッチ用 )または ORA-01406(切捨て用 )の値を割り当てます。

標識変数のデータ型は sb2です。標識変数の配列の場合、各配列要素の型は sb2です。

入力入力ホスト変数については、OCIアプリケーションは次の値を標識変数に割り当てることができます。

入力標識値 Oracleからのアクション

-1 Oracleは NULLを列に割り当て、入力変数の値は無視。

>=0 入力変数の値を列に割り当て。

Page 74: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

その他のコーディング・ガイドライン

OCIプログラミングの基本 2-29

出力出力については、Oracleは次の値を標識変数に割り当てます。

名前付きデータ型用および REF用の標識変数ほとんどの新しい (リリース 8.0)データ型の標識変数は、前述の説明どおりに機能します。例外は SQLT_NTY(名前付きデータ型 )です。SQLT_REF型のデータでは、他の変数型と同様に、標準のスカラー標識を使用します。SQLT_NTY型のデータの場合、標識変数は標識構造体へのポインタである必要があります。

オブジェクト型トランスレータ (OTT)を使用してデータベース型を C構造体に変換すると、各オブジェクト型について NULL標識構造体が生成されます。この構造体には、アトミックNULL標識と各オブジェクト属性の標識が含まれます。

関連項目 : NULL標識構造体の詳細は、このマニュアルの第 12章の「オブジェクト型トランスレータの使用」の OTTの部分、および 8-27ページの「NULL」 を参照してください。

名前付きデータ型および REFの標識パラメータ設定の詳細は、第 13章のOCIBindByName()および OCIBindByPos()の記述、および 10-3ページの「名前付きデータ型および REFバインドについての追加情報」と 10-4ページの「名前付きデータ型とREF定義、および PL/SQL OUTバインドの追加情報」の各項を参照してください。

コールの取消しほとんどのプラットフォームで、長時間実行されたり繰り返されている OCIコールを取り消すことができます。これを実行するには、キーボードからオペレーティング・システムの割込み文字 (一般に CTRL-C)を入力します。

注意 : これとカーソルの取消しを混同しないよう注意してください。カーソルの取消しは、nrowsパラメータを 0(ゼロ )に設定し、OCIStmtFetch()をコールして行います。

出力標識値 意味

-2 項目の長さが出力変数の長さよりも長いため、項目を切り捨て。さらに、元の長さが、sb2標識変数で戻せる最大長より長くなっています。

-1 選択された値が NULLで、出力変数の値は変更されない。

0 完全な値をホスト変数に割り当て。

>0 項目の長さが出力変数の長さよりも長いため、項目を切り捨て。標識変数に戻された正の値は、切捨て前の実際の長さです。

Page 75: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラムでの PL/SQL使用

2-30 Oracle8コール・インタフェース・プログラマーズ・ガイド

長時間実行されたり繰り返されているコールをオペレーティング・システムへの割込みにより取り消した場合は、エラー・コード ORA-01013(「ユーザーの要求による現行操作の取消し」)が戻されます。

サービス・コンテキスト・ポインタまたはサーバー・コンテキスト・ポインタを指定すると、OCIBreak()関数は、サーバーに関連付けられている現在実行中の OCI関数をすべて即時(非同期)に打ち切ります。これは通常、サーバーで処理中の長時間実行されている OCIコールを停止するために使用します。

位置づけ更新および位置づけ削除SELECT...FOR UPDATE OF...文に対応するバイナリの ROWIDを、後の UPDATE文またはDELETE文に使用できます。ROWIDは文ハンドル用に OCIAttrGet()をコールすることにより検索でき、これによりこのハンドルの OCI_ATTR_ROWID属性を検索できます。

たとえば、次のような SQL文があるとします。

SELECT ename FROM emp WHERE empno = 7499 FOR UPDATE OF sal

この場合、フェッチが実行されると、ハンドルの ROWID属性には SELECTされた行の行識別子が入ります。次のコードのように OCIAttrGet()をコールして、プログラムのバッファにROWIDを取り出すことができます。

OCIRowid *rowid; /* the rowid in opaque format *//* allocate descriptor with OCIDescriptorAlloc() */err = OCIAttrGet ((dvoid*) mystmtp, OCI_HTYPE_STMT,

(dvoid*) &rowid, (ub4 *) 0, OCI_ATTR_ROWID, (OCIError *) myerrhp);

その後、保管された ROWIDを DELETE文または UPDATE文で使用できます。たとえば、MY_ROWIDが行識別子の保管されているバッファである場合、後で次のような SQL文を処理できます。

UPDATE emp SET sal = :1 WHERE rowid = :2

これは、新しい salary(給与 )をプレースホルダ :1にバインドし、MY_ROWIDを :2に バインドして行います。MY_ROWIDを :2にバインドする場合は、必ずデータ型コード104(ROWID記述子 )を使用してください。

アプリケーションのリンクアプリケーション・リンク・モードおよび OCI各バージョンの非遅延リンクおよびシングル・タスク・リンクへの Oracleサポートの詳細は、A-7ページの「アプリケーション・リンク発行」を参照してください。

OCIプログラムでの PL/SQL使用PL/SQLは、Oracleが開発した SQLのプロシージャ型拡張要素です。PL/SQLは、単純な問合せや SQLデータ操作言語 (DML)文よりも複雑な作業を処理します。PL/SQLを使う

Page 76: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラムでの PL/SQL使用

OCIプログラミングの基本 2-31

と、複数の構成体を単一のブロックにグループ化し、それを 1単位として実行することができます。構成体には以下のものがあります。

■ 1つまたは複数の SQL文

■ 変数宣言

■ 代入文

■ IF...THEN...ELSE文やループなどのプロシージャ型制御文

■ 例外処理

OCIプログラムで PL/SQLブロックを使用して、次の操作ができます。

■ Oracleストアド・プロシージャおよびストアド・ファンクションのコール

■ 複数の SQL文を指定したプロシージャ型制御文を結合し、1つの単位として実行

■ レコード、表、CUROSR FORループ、例外処理など特殊な PL/SQL機能のアクセス

■ カーソル変数の使用

■ Oracle8 Server内のオブジェクトの操作

注意 : OCIでは直接処理できるのは無名ブロックだけで、名前付きパッケージまたは名前付きプロシージャは処理できないのに対し、ユーザーはいつでもパッケージ・コールまたはプロシージャ・コールを無名ブロック内に入れ、そのブロックを処理することができます。

警告 : PL/SQLコードを書く際に、「--」で始まるものは、キャリッジ・リターンまで解析機能によりすべてコメントとみなされることに注意してください。「--」を使ってコメントを各行に示した場合、Cコンパイラでは各行にキャリッジ・リターン「/n」が挿入されず、すべての行が PL/SQLブロックで単一行として連結されます。この特定のケースでは、ある行がコメントで終わっている場合、解析機能は次の行の PL/SQLコード抽出に失敗してしまいます。この問題を回避するには、各「--」コメントの後に「/n」を入れ、そこでコメントが必ず終了するよう注意しなければなりません。

PL/SQLブロックのコーディングの詳細は、『PL/SQLユーザーズ・ガイドおよびリファレンス』 を参照してください。

Page 77: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIプログラムでの PL/SQL使用

2-32 Oracle8コール・インタフェース・プログラマーズ・ガイド

Page 78: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

データ型 3-1

3データ型

この章は、OCIアプリケーションで使用する Oracle外部データ型についてのリファレンスです。 リリース 8.0から新しく加わった特殊なデータ型を含む、Oracleデータ型についての一般的な説明もあります。この章の情報は、独自に作成したプログラムと Oracleの間でデータを転送する際に行われるデータの内部表現と外部表現の変換を理解する上で有用です。

Oracle内部のデータ型に関する詳細は、『Oracle8 Server SQLリファレンス』を参照してください。

この章では次のトピックについて説明します。

■ Oracleデータ型

■ 内部データ型

■ 外部データ型

■ 新しい OCI 8.0外部データ型

■ データ変換

■ 型コード

■ oratypes.hの定義

Page 79: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracleデータ型

3-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

Oracleデータ型OCIプログラムの重要な機能の 1つは、Oracle Serverを介してデータベースと通信を行うことです。 OCIアプリケーションでは、SQL SELECTを使用した問合せによってデータベースの表からデータを検索するか、INSERTまたは UPDATE、DELETEを使用して表内の既存データを変更します。

データベース内では、値は表の列に格納されています。 内部的には、Oracleは内部データ型という特別な形式でデータを表しています。 内部データ型の例として、NUMBER、CHAR、DATEなどがあります。

一般的に、OCIアプリケーションではデータの内部データ型表現を処理しません。 OCIアプリケーションで操作するホスト言語のデータ型は、そのアプリケーションを作成した言語によって事前定義されています。 OCIクライアント・アプリケーションとデータベースの表の間でデータが転送されるとき、OCIライブラリによって、内部データ型と外部データ型の間でデータ変換が行われます。

外部データ型は、OCIヘッダー・ファイル内に定義されているホスト言語型です。 OCIアプリケーションで入力変数をバインドするとき、バインド・パラメータの 1つで変数の外部データ型コード(または SQLTコード)を指示します。 同様に、定義コールで出力変数を指定するとき、検索されるデータの外部表現を指定する必要があります。

外部データ型が内部データ型に類似している場合もあります。 外部型を使用すると、専用データ形式ではなくホスト言語の型を操作できるので、プログラマにとって便利です。

注意 : 一部の外部データ型は内部データ型に類似していますが、OCIアプリケーションが内部データ型にバインドすることは絶対にありません。 内部データ型をここで説明するのは、内部データ型がどのようにして外部データ型へマップされるかを理解することです。

OCIでは、Oracleと OCIアプリケーション間でデータを転送する際、広範囲のデータ型変換を行うことができます。 Oracle内部データ型より OCI外部データ型のほうが多くあります。 単一の外部型を 1つの内部型にマップする場合もあり、複数の外部型を単一の内部型にマップする場合もあります。

あるデータ型が多数対 1の関係でマッピングされることによって、OCIプログラムに柔軟性が提供されます。たとえば、次の SQL文を処理しているとします。

SELECT sal FROM emp WHERE empno = :employee_number

このとき sal(給与 )を 2進数浮動小数点形式ではなく、文字データ型として戻すには、sal列に対する OCIDefineByPos()コールの dtyパラメータに、VARCHAR2(コード = 1)やCHAR(コード = 96)などの Oracle外部文字列データ型を指定します。 また、プログラムで文字列変数を宣言し、そのアドレスを valuepパラメータで指定する必要があります。

ただし、給与情報を 2進数浮動小数点値として戻したい場合は、FLOAT(コード = 4)外部データ型を指定します。 また、valuepパラメータに適切な型の変数を定義する必要があります。

Page 80: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracleデータ型

データ型 3-3

Oracleでは、ほとんどのデータ変換が透過的に実行されます。 また、ほとんどすべての外部データ型を指定できるため、特殊なタスクを実行できます。 たとえば、DATE外部データ型 (コード = 12)を使用すると、文字変換を行わずに純粋な 2進形式で DATE値を入出力できます。 詳細は、3-14ページの DATE外部データ型の説明を参照してください。

データ変換を制御するには、適切な外部データ型コードをバインド・ルーチンおよび定義ルーチンで使用する必要があります。 OCIプログラム内の入力変数または出力変数の位置、および変数のデータ型と長さを Oracleに対して指定する必要があります。

その他の Oracle8 OCIでは、オブジェクト型属性のデータ型を表すために Oracle8の型管理システムで使われる一連の OCI型コードも用意されています。 これらの型コードを表すために使用する、一連の事前定義済みの定数があります。 各定数には接頭辞「OCI_TYPECODE」が含まれます。

要約すると、OCIプログラマは、次の各種のデータ型またはデータ表現について認識する必要があります。

■ 内部 Oracleデータ型。Oracleデータベースの表の列で使用されます。 これは、PL/SQLで使用され、Oracle列では使用されないデータ型も含まれます(たとえば、索引付き表、ブール、レコード)。 詳細は、3-4ページの「内部データ型」および 3-4ページの「内部のデータ型コード」を参照してください。

■ 外部 OCIデータ型。Oracleデータのホスト言語表現を指定するために使用します。 詳細は、3-7ページの「外部データ型」および 3-4ページの「外部データ型コード」を参照してください。

■ OCI_TYPECODE値。Oracleでオブジェクト型属性の型情報を表現するために使用されます。 詳細は、3-23ページの「型コード」および 3-24ページの「SQLT値およびOCI_TYPECODE値の関係」を参照してください。

Page 81: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

内部データ型

3-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

内部のデータ型コードOCIアプリケーションで Oracleデータの内部表現を知る場合があります。 たとえば、フェッチしたデータを受け取る出力変数を定義するには、動的 SQL問合せにおける列のデータ型がわかっている必要があります。 問合せの実行後、OCIParamGet()関数および OCIAttrGet()関数を組み合せて使用し、文ハンドルから選択リスト項目についての記述情報を取得できます。 文を実行しなくても、OCIDescribeAny()をコールし、次に OCIParamGet()とOCIAttrGet()を組み合せることによって、同じ情報を記述ハンドルから入手できます。

列の内部データ型についての情報は、内部データ型コード書式でアプリケーションへ送られます。 アプリケーション側では、どの型のデータが戻されるのかがわかると、出力データの変換方法と書式設定の方法について適切な判断ができます。 Oracle内部のデータ型コードのリストは、3-4ページの「内部データ型」を参照してください。

関連項目 :⦆Oracle内部データ型の詳細は、『Oracle8 Server SQLリファレンス』を参照してください。 問合せでの選択リスト項目記述の詳細は、4-8ページの「選択リスト項目の記述」を参照してください。

外部データ型コードOracleでは、外部データ型コードによって、プログラムでのホスト変数のデータ表現方法が指定されます。 これによって、プログラムの出力変数にデータが戻されるときの変換方法、または入力(バインド)変数から Oracleの列値へのデータ変換方法が決まります。 たとえば、Oracle列のNUMBERを可変長文字配列に変換したい場合は、出力変数を定義するOCIDefineByPos()コールで VARCHAR2外部データ型コードを指定します。

バインド変数を Oracle列の値に変換するには、バインド変数の型に対応する外部データ型コードを指定します。 たとえば、"02-FEB-65" などの文字列を DATE列に入力するには、データ型を文字列としてデータ長パラメータを 9に設定します。

使用する値をすべて変換可能にするのは、プログラマの責任です。 文字列「MY BIRTHDAY」を DATE列へ INSERTする文を実行すると、エラーが発生します。

外部データ型およびデータ型コードの詳細は、3-7ページの表 3–2を参照してください。

内部データ型次の表は、Oracle内部データ型を各型の最大内部長およびデータ型コードとともにリストしています。

表 3–1 Oracle内部データ型

Oracle内部データ型 最大内部長 データ型コード

VARCHAR2 4000バイト 1

NUMBER 21バイト 2

LONG 2^31-1バイト 8

Page 82: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

内部データ型

データ型 3-5

これらの内部データ型の詳細は、 『Oracle8 Server SQLリファレンス』を参照してください。 次の各項では、これらのデータ型に関する OCI固有の事項を示します。

LONG、RAW、LONG RAW、VARCHAR2OCIBindByName()および OCIBindByPos()、OCIDefineByPos()、OCIStmtGetPieceInfo()、OCIStmtSetPieceInfo()によって提供されるピース単位機能を使用して、これらの型の列データを扱う挿入または更新、フェッチを実行できます。

ROWID 10バイト 11

DATE 7バイト 12

RAW 2000バイト 23

LONG RAW 2^31-1バイト 24

CHAR 2000バイト 96

MLSLABEL 255バイト 105

ユーザー定義型(オブジェクト型、VARRAY、ネステッド・テーブル)

<N/A> 108

REF <N/A> 111

CLOB <N/A> 112

BLOB <N/A> 113

表 3–1 Oracle内部データ型 (続き )

Oracle内部データ型 最大内部長 データ型コード

Page 83: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

内部データ型

3-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

文字列およびバイト配列文字またはバイト配列を含む列を指定する場合は、CHARおよび VARCHAR2、RAW、LONG、LONG RAWの 5つの Oracle内部データ型を使うことができます。

注意 : LOBおよび FILEには文字またはバイナリ・データを含めることもできます。 これらは、他の型とは異なる処理がされるので、ここでは説明しません。 これらのデータ型の詳細は、7-23ページの「LOBおよび FILE操作」を参照してください。

通常、CHARおよび VARCHAR2、LONG列には文字データが入ります。 RAWおよびLONG RAWには、文字として解釈されないバイト、たとえばビット・マップ化された画像のピクセル値などが入ります。 ネットワーク間のゲートウェイを介して文字データを渡すと、文字データが変形する可能性があります。 たとえば、1文字を表現するバイト数が異なる別々の言語を使用しているマシン間で文字データを渡すと、長さが大きく変わる能性があります。 RAWデータがこのように変換されることはありません。

表の列ごとに適切な Oracle内部データ型を選択するのは、データベースの設計者の責任です。 OCIプログラマは、文字データおよびバイト配列データの表現方法、および OCIプログラムの変数と Oracle表の間でのデータの変換方法を多数知っておく必要があります。

配列に文字が入っている場合、OCIコール内の配列の長さを示すパラメータは、常に文字単位ではなくバイト単位で渡し、バイト単位で戻されます。

Page 84: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

データ型 3-7

外部データ型表 3–2は、外部データ型のデータ型コードをリストしています。 この表ではデータ型ごとに、Oracle内部データの変換元または変換先となる、Cのプログラム変数の型をリストしています。

表 3–2 外部データ型とそのコード

外部データ型

プログラム変数のデータ型 OCI定義の定数NAME CODE

VARCHAR2 1 char[n] SQLT_CHR

NUMBER 2 unsigned char[21] SQLT_NUM

8ビット符号付き INTEGER 3 signed char SQLT_INT

16ビット符号付き INTEGER 3 signed short, signed int SQLT_INT

32ビット符号付き INTEGER 3 signed int, signed long SQLT_INT

FLOAT 4 float, double SQLT_FLT

NULL終了 STRING 5 char[n+1] SQLT_STR

VARNUM 6 char[22] SQLT_VNU

LONG 8 char[n] SQLT_LNG

VARCHAR 9 char[n+sizeof(short integer)] SQLT_VCS

ROWID 11 char[n] SQLT_RID(注意 1を参照 )

DATE 12 char[7] SQLT_DAT

VARRAW 15 unsigned char[n+sizeof(short integer)] SQLT_VBI

RAW 23 unsigned char[n] SQLT_BIN

LONG RAW 24 unsigned char[n] SQLT_LBI

UNSIGNED INT 68 unsigned SQLT_UIN

LONG VARCHAR 94 char[n+sizeof(integer)] SQLT_LVC

LONG VARRAW 95 unsigned char[n+sizeof(integer)] SQLT_LVB

CHAR 96 char[n] SQLT_AFC

CHARZ 97 char[n+1] SQLT_AVC

ROWID記述子 104 OCIRowid SQLT_RDD

MLSLABEL 106 char[n] SQLT_LAB

NAMED DATA TYPE 108 struct SQLT_NTY

Page 85: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

3-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

注意 : データ長が nとなっている場合、nは可変でプログラム (ROWIDの場合には、オペレーティング・システム )の要件に依存します。

次に、それぞれの外部データ型について説明します。 リリース 8.0から新しく加わったデータ型の詳細は、3-17ページの「新しい OCI 8.0外部データ型」を参照してください。

次の 3つの型は PL/SQLに対する内部型で、OCIでは値として戻すことができません。

■ ブール、SQLT_BOL

■ 索引付き表、SQLT_TAB

■ レコード、SQLT_REC

REF 110 OCIRef SQLT_REF

文字 LOB 112 OCILobLocator(注意 3を参照 ) SQLT_CLOB

バイナリ LOB 113 OCILobLocator(注意 3を参照 ) SQLT_BLOB

バイナリ FILE 114 OCILobLocator SQLT_FILE

OCI文字列型 155 OCIString SQLT_VST(注意 2を参照 )

OCIデータ型 156 OCIDate SQLT_ODT(注意 2を参照 )

注意 :

(1) この型はバージョン 7.xの OCIコールでのみ有効です。 Oracle8 OCIアプリケーションでは、ROWID記述子 (型104)を使用する必要があります。

(2) これらのデータ型の使用方法の詳細は、第 9章の「オブジェクト・リレーショナル・データ型」を参照してください。

(3) OTTで生成したデータ型マッピングを使用しているアプリケーションでは、CLOBは OCIClobLocatorとしてマッピングされ、BLOBは OCIBlobLocatorとしてマッピングされます。 詳細は、第 12章の「オブジェクト型トランスレータの使用」を参照してください。

表 3–2 外部データ型とそのコード (続き )

外部データ型

プログラム変数のデータ型 OCI定義の定数NAME CODE

Page 86: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

データ型 3-9

VARCHAR2VARCHAR2データ型は、最長 4000バイトの可変長文字列です。

注意 : Oracle8オブジェクトを使う場合は、一連の定義済み OCI関数を使うことにより、特殊な OCIString外部データ型を扱うことができます。 このデータ型の詳細は、第9章の「オブジェクト・リレーショナル・データ型」を参照してください。

入力OCIBindByName()または OCIBindByPos()コールでは、value_szパラメータによって長さが決定されます。

value_szパラメータが 0(ゼロ )より大きい場合、指定のバイト数だけがプログラムのバッファ・アドレスの先頭から読み取られて、バインド変数値が取得されます。 後続する空白は削除され、結果の値は SQL文または PL/SQLブロックで使用されます。 INSERT文の場合、結果の値がデータベース列の定義された長さより長いと、INSERTは失敗しエラーが戻されます。

注意 : 後続する NULLは除去されません。 変数は NULLで終了させずに、空白埋めする必要があります。

value_szパラメータが 0(ゼロ )の場合、Oracleでは実際の内容に関係なく、バインド変数をNULLとして扱います。 NULLは、SQL文のバインド変数値として使用できます。 NOT NULL整合性制約付きの列に NULLを挿入しようとすると、Oracleではエラーとなり、行は挿入されません。

Oracle内部(列)データ型がNUMBERのとき、数値の文字表現を含んでいる文字列からの入力は有効です。 入力文字列は内部数値形式に変換されます。 VARCHAR2文字列に無効な変換文字が含まれる場合、Oracleではエラーを返し、値はデータベースに挿入されません。

出力OCIDefineByPos()コールの value_szパラメータで、または、PL/SQLブロックの場合はOCIBindByName()か OCIBindByPos()の value_sz パラメータで、戻り値の希望の長さを指定します。 長さとして 0(ゼロ )を指定した場合、データは戻されません。

OCIDefineByPos()の rlenpパラメータを省略すると、値はバッファの長さに達するまで空白が埋め込まれて戻され、空白文字の文字列として NULLが戻されます。 rlenpを指定した場合、戻り値は空白埋めされません。 そのかわりに、実際の長さが rlenpパラメータに戻されます。

NULLが戻されたか、または文字の切捨てが発生したかどうかをチェックするには、OCIDefineByPos()コールに標識パラメータを指定します。 Oracleでは、NULLがフェッチされた場合に標識パラメータが -1に設定され、戻り値が切り捨てられている場合は標識パラメータが元の列長に設定されます。 それ以外の場合は、0が設定されます。 標識パラメータを指定してない場合、NULLが選択されると、フェッチ・コールで エラー・コードOCI_SUCCESS_WITH_INFOが戻されます。 エラーについての診断情報の検索では、ORA-1405が戻されます。

Page 87: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

3-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

関連項目 : 標識変数の詳細は、2-28ページの「標識変数」を参照してください。

また、内部 NUMBERデータ型から文字列への出力を要求することもできます。 数値変換は、ご使用のシステムの各国語サポートによって規定される規則に従って行われます。 たとえば、システムが、小数点としてピリオドではなくコンマを認識するように構成されている場合があります。

NUMBER通常は、NUMBERを外部データ型として使用する必要はありません。 NUMBERを使用すると、Oracleでは 21バイトの内部 2進形式で数値を戻し、入力時にこの形式が必要になります。 完全な情報が必要な場合は、次の説明を参照してください。

注意 : Oracle8でオブジェクトを使用している場合は、一連の定義済み OCI関数を使うことにより、特殊な OCINumber データ型を扱うことができます。 このデータ型の詳細は、第 9章の「オブジェクト・リレーショナル・データ型」を参照してください。

Oracleでは、NUMBERデータ型の値を可変長形式で格納します。 最初のバイトは指数であり、その後に 1~ 20個の仮数バイトが続きます。 指数バイトの高位ビットは符号ビットであり、そのビットには正数が設定されます。 下位の 7ビットは指数を表します。この指数はオフセット 65で基本 100の数字です。

各仮数バイトは基本 100で範囲 1~ 100の数字です。正数の場合は、それに 1を加えた数字となります。 したがって、値 5に対する仮数は 6となります。負数の場合、1を加える代りに、その数字が 101から差し引かれます。したがって、値 -5に対する仮数は 96 (101-5) となります。 負数は、102が入っているバイトがデータ・バイトの後に追加されています。 ただし、20個の仮数バイトを持つ負数には、102のバイトは後続しません。 仮数バイトは基本100なので、各バイトは 2桁の 10進数値を表すことができます。 仮数は正規化されます。先行する 0(ゼロ )は格納されません。

仮数を表すのに最大 20個のデータ・バイトが使用できます。 ただし、精度が保証されているのは 19個だけです。 19個のデータ・バイトは、それぞれ基本 100を表し、Oracle NUMBERに対して 38桁の最大精度をもたらします。

OCIDefineByPos()コールの dtyパラメータにデータ型コード 2を指定すると、プログラムではこの Oracle内部形式で数値データを受け取ります。 出力変数は、可能な最大の数値を格納できる 21バイトの配列である必要があります。 数値を表すバイトだけが戻されることに注意してください。 空白埋めまたは NULL終了はありません。 戻されたバイト数を知りたい場合は、NUMBERではなく VARNUM外部型を使用します。 Oracle内部数値書式の例は、3-13ページの VARNUMに関する説明を参照してください。

INTEGERINTEGERデータ型では数値を変換します。 外部 INTEGERは符号付きの 2進数です。バイト単位のサイズはシステムによって異なります。 変数内のバイトの順序は、ホスト・システム・アーキテクチャによって決まります。 長さの指定は、入力でも出力でも必須です。 Oracleから戻される数値が整数でない場合、小数部分は廃棄され、エラーやその他の情報は

Page 88: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

データ型 3-11

戻されません。 戻される数値がシステムの符号付き INTEGERで表現できない場合、「変換時にオーバーフローが発生しました (overflow on conversion)」のエラーが戻されます。

FLOATFLOATデータ型は、小数部分のある数値、または INTEGERでは表現できない数値を処理します。 数値はホスト・システムの浮動小数点書式で表されます。 通常、長さは 4バイトか 8バイトのどちらかです。 長さの指定は、入力および出力の両方について必要です。

Oracleの数値の内部形式は 10進数です。大部分の浮動小数点は 2進数で実現されます。したがって、Oracleでは、数値を浮動小数点で表現するよりもより高い精度で表現できます。

注意 : FLOATおよびNUMBER間の変換時には「四捨五入オフ (round-off)」のエラーが発生する場合もあります。 たとえば、問合せでバインド変数として FLOATを使用すると、ORA-1403エラーが戻されることがあります。 この状況を回避するには、FLOATを STRINGに変換し、データ型コード 1または 5を設定します。

Page 89: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

3-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

STRINGNULLで終了する STRING形式は、文字列に NULL終了文字が入っていなければならないことを除けば、VARCHAR2形式 (データ型コード 1)と同じような働きをします。 このデータ型は、特に Cプログラムで有用です。

入力OCIBindByName()または OCIBindByPos()コールで供給される文字列の長さによって、NULL終了文字があるかどうかの走査の範囲が制限されます。 NULL終了文字が指定された中で見つからなかった場合は、エラーとなります。

ORA-01480: trailing null missing from STR bind value

バインド・コールで長さが指定されていない場合、OCIは、文字列の暗黙の最大長の 4000を使用します。

文字列の最小の長さは 2バイトです。 最初の文字が NULL終了文字であり、長さが 2と指定されている場合、許可されていれば NULLが列に挿入されます。 コード 1および 96の型とは異なり、空白だけを含む文字列は入力時に NULLとして扱われるのではなく、そのまま挿入されます。

注意 :以前の OCIバージョンとは異なり、リリース 8.0では、NULLで終わる文字列の文字列長パラメータに -1を渡すことはできません。

出力NULL終了文字は、最後の文字が戻された後に配置されます。 文字列が指定のフィールド長より長い場合、文字列は切り捨てられ、出力変数の最後の文字の位置に NULL終了文字が入ります。

NULL選択リスト項目は、最初の文字の位置に NULL終了文字を戻します。 ORA-01405というエラーが戻される可能性があります。

Page 90: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

データ型 3-13

VARNUMVARNUMデータ型は、最初のバイトに数表現の長さが含まれることを除けば、外部NUMBERデータ型と類似しています。 この長さには、長さのバイト自体は含まれません。 可能な最長の VARNUMを受け取るために、22バイトを予約してください。 VARNUM値をOracleに送るとき、長さのバイトを設定します。

表 3-3に、Oracle表の数値に戻される VARNUM値の例をいくつか示します。

LONGLONGデータ型では、4000バイトより長い文字列を格納します。 LONG列には、最大2GB(2^31-1バイト )を格納できます。 この列の型は、長い文字列の格納およびフェッチにだけ使用します。 関数または式、WHERE句では使用できません。 一般的に、LONG列値の変換は、文字列との間で行われます。

VARCHARVARCHARデータ型では、長さが異なる文字列が格納されます。 先頭 2バイトには文字列の長さが入り、残りのバイトに文字列が入ります。 バインド・コールまたは定義コールで指定する文字列の長さはこの長さデータ 2バイトを含まなければならないため、受け渡しできる最大の VARCHAR文字列長は 65535バイトではなく、65533バイトとなります。それより長い文字列の変換には、LONG VARCHAR外部データ型を使ってください。

ROWIDROWIDデータ型は、データベースの表の特定の行を識別するのに使用されます。 ROWIDは、次のように、問合せの選択リスト項目になっている場合があります。

SELECT rowid, ename, sal FROM emp FOR UPDATE OF sal

表 3–3 VARNUMの例

10進数 長さバイト 指数バイト 仮数バイト終了文字バイト

0 1 128 該当なし 該当なし

5 2 193 6 該当なし

-5 3 62 96 102

2767 3 194 28、68 該当なし

-2767 4 61 74、34 102

100000 2 195 11 該当なし

1234567 5 196 2、24、46、68 該当なし

Page 91: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

3-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

この例では、この後の INSERT文または UPDATE文、DELETE文で、戻された ROWIDを使用します。 これは、特定の行にアクセスする最も高速な方法です。

Oracle8 OCIでは、ROWIDへのアクセスは ROWID記述子を使って行います。この記述子はバインド変数または定義変数として使用できます。 ROWID記述子の使用方法の詳細は、2-11ページの「記述子およびロケータ」および 2-30ページの「位置づけ更新および位置づけ削除」を参照してください。

DATEDATEデータ型では、Oracle内部日付 2進形式を使用して、日付の値を更新または挿入、検索できます。 バイナリ形式の日付は、表 3–4に示すように 7バイトです。

世紀および年を表すバイトの値は、100を加算した表記です。 西暦紀元前 (Dates Before Common Era:BCE)は 100未満です。西暦紀元は BCE 4712年 1月 1日、すなわちジュリアン日 1です。この日付の場合、世紀バイトは 53、年バイトは 88です。時間バイトおよび分バイト、秒バイトは 1を加算する excess-1表記法で表されます。 時間バイトの範囲は 1~ 24、分および秒バイトは 1~ 60です。データ作成時に時刻を指定しないと、時刻はデフォルトで深夜 (1, 1, 1)となります。

DATE外部データ型を使用して、2進形式で日付を入力する場合、データベースでは一貫性または範囲のチェックは行いません。 この形式になっているすべてのデータは、入力前に注意して検証する必要があります。

注意 : Oracle外部 DATEデータ型が日常のデータベース操作で必要になることはほとんどありません。 一般にプログラムでは 'DD-MON-YY' などのように文字形式でデータを扱うため、DATEは文字形式に変換した方がはるかに便利です。

DATE列はプログラム内で文字列に変換される際、使用中セッションのデフォルト書式、または INIT.ORAファイルでの指定に従って戻されます。

注意 : Oracle8でオブジェクトを使用している場合は、一連の定義済み OCI関数を使うことにより、特殊な OCIDateデータ型を扱うことができます。 このデータ型の詳細は、第 9章の「オブジェクト・リレーショナル・データ型」を参照してください。

表 3–4 DATEデータ型の書式

バイト 1 2 3 4 5 6 7

意味 世紀 年 月 日 時 分 秒

例(1992年 11月 30日、3:17 PM)

119 192 11 30 16 18 1

Page 92: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

データ型 3-15

RAWRAWデータ型は、たとえば図形文字列の格納など、Oracleで解釈されないバイナリ・データまたはバイト列で使用されます。 RAW列の最大長は 2000バイトです。 詳細は、 『Oracle8 Server SQLリファレンス』を参照してください。

Oracle表内の RAWデータ(ロー・データ)がプログラムで文字列に変換される場合、データは 16進文字コードで表されます。 RAWデータの各バイトは、それぞれの値を示す’00’~ ’FF’の 2文字で戻されます。プログラムで Oracle表内の RAW列に文字列を入力する場合は、この 16進コードを使って文字列でデータをコード化する必要があります。

OCIDefineByPos()および OCIBindByName()、OCIBindByPos()、OCIStmtGetPieceInfo()、OCIStmtSetPieceInfo() によって提供されるピース単位機能を使用して、RAW(または LONG RAW)列を扱う挿入または更新、フェッチを実行できます。

注意 : Oracle8でオブジェクトを使用している場合は、一連の定義済み OCI関数を使うことにより、特殊な OCIRawデータ型を扱うことができます。 このデータ型の詳細は、第 9章の「オブジェクト・リレーショナル・データ型」を参照してください。

VARRAWVARRAWデータ型は、RAWデータ型と類似しています。 ただし、先頭の 2バイトにはデータの長さが入ります。 バインド・コールまたは定義コールの文字列に指定する長さには、長さを表すバイトが 2個含まれている必要があります。 したがって、受け渡しできる最大のVARRAW文字列長は 65535バイトではなく、65533バイトです。それより長い文字列の変換には LONG VARRAW外部データ型を使ってください。

LONG RAWLONG RAWデータ型は、最大 2GB(2^31-1バイト )の RAWデータを格納できるということを除けば、RAWデータ型と類似しています。

UNSIGNEDUNSIGNEDデータ型は、符号なし 2進整数用に使用されます。 バイト単位のサイズはシステムによって異なります。 ワード内のバイトの順序は、ホスト・システム・アーキテクチャによって決まります。 長さの指定は、入力でも出力でも必須です。 Oracleから出力される数値が整数でない場合、小数部分は廃棄され、エラーやその他の情報は戻されません。 戻される数値がシステムの符号なし INTEGERより大きくて表現できない場合、「変換時にオーバーフローが発生しました (overflow on conversion)」のエラーが戻されます。

LONG VARCHARLONG VARCHARデータ型は、Oracleの LONG列からデータを格納する場合、またはOracleの LONG列にデータを格納する場合に使用します。 LONG VARCHARの先頭の 4バイトには項目の長さが入ります。 したがって、格納される項目の最大長は、2^31-5バイトです。

Page 93: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部データ型

3-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

LONG VARRAWLONG VARRAWデータ型は、Oracle LONG RAW列からデータを格納する場合、またはOracle LONG RAW列にデータを格納する場合に使用します。 長さは、先頭の 4バイトに入ります。 最大長は、2^31-5バイトです。

CHARCHARデータ型は最長 2000の文字列です。CHAR文字列は空白埋め比較方法(『Oracle8 Server SQLリファレンス』を参照)で比較されます。

入力長さは、OCIBindByName()または OCIBindByPos()コールの value_szパラメータによって決まります。

注意 : バッファの全内容 (value_sz chars)は、後続する空白または NULLもすべて含め、データベースへ渡されます。

value_szパラメータが 0(ゼロ )である場合、バインド変数は、実際の内容とは無関係にNULLとして処理されます。 NULLは、SQL文のバインド変数値として使用できます。 NOT NULL整合性制約付きの列に NULLを挿入しようとすると、Oracleエラーとなり、行は挿入されません。

CHARの場合、value_szパラメータには負の値を使用できません。

Oracle内部(列)データ型がNUMBERのとき、数値の文字表現を含んでいる文字列からの入力は有効です。 入力文字列は内部数値形式に変換されます。 CHAR文字列に無効な変換文字が含まれる場合、Oracleではエラーを返し、値は挿入されません。 数値変換は、使用しているシステムの各国語サポート機能によって規定される規則に従って行われます。 たとえば、システムが、ピリオドではなくカンマを小数点として認識するように構成されている場合もあります。

出力OCIDefineByPos()コールの value_szパラメータで、戻り値の希望の長さを指定します。 長さとしてゼロを指定した場合、データは戻されません。

OCIDefineByPos()の rlenpパラメータを省略すると、戻される値はバッファの長さに達するまで空白が埋め込まれ、空白文字の文字列として NULLが戻されます。 rlenpを指定した場合、戻り値は空白埋めされません。 そのかわりに、実際の長さが rlenpパラメータに戻されます。

NULLが戻されたか、または文字の切捨てが発生したかどうかをチェックするには、OCIDefineByPos() コールに標識パラメータまたは標識パラメー タの配列を指定します。 標識パラメータには、NULLがフェッチされた場合は -1が設定され、値が切り捨てられて戻された場合は元の列の長さが設定されます。 それ以外の場合は、0が設定されます。 標識パラメータを指定していない場合、NULLが選択されると、フェッチ・コールで ORA-01405エラーが戻されます。

Page 94: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

新しい OCI 8.0外部データ型

データ型 3-17

関連項目 : 標識変数の詳細は、2-28ページの「標識変数」を参照してください。

内部 NUMBERデータ型から文字列への出力を要求することもできます。 数値変換は、ご使用のシステムの各国語サポート機能によって規定される 規則に従って行われます。 たとえば、システムが、ピリオド (.)ではなくカンマ (,)を小数点として認識するように構成されている場合もあります。

CHARZCHARZ外部データ型は、入力時に文字列が NULL文字で終了していなければならないこと、および出力時に Oracleが文字列の最後に NULL終了文字を置くことを除けば、CHARデータ型と類似しています。 NULL終了文字は入出力時に文字列を区切るだけであり、表のデータの一部ではありません。

入力時に、長さのパラメータは、NULL終了文字も含めた正確な長さを示す必要があります。 たとえば、Cの配列が次のように宣言されたとします。

char my_num[] = "123.45";

この場合、my_numのバインド時の長さのパラメータは 7になっている必要があります。 この例で他の値を指定すると、エラーが戻されます。

MLSLABELTrusted OracleにはMLSLABELデータ型が用意されています。このデータ型は、複数レベルを持つ安全性の高いオペレーティング・システムにより生成されるラベルに対するTrusted Oracleの内部表現です。 Trusted Oracleは、ラベルを使用して、データベース・アクセスを制御します。

Trusted Oracleアプリケーションとの互換性を持つために、Oracle8のMLSLABELデータ型を使用して列を定義できます。しかし、Oracle8の列で有効な値は NULLだけです。

MLSLABELデータ型および Trusted Oracleの詳細は、『Trusted Oracle Server Administrator’s Guide』を参照してください。

新しい OCI 8.0外部データ型次の新外部データ型はリリース 8.0から導入されました。これらのデータ型は、Oracle7 Serverへ接続した場合にはサポートされません。

注意 : 内部データ型および外部データ型は、どちらも各々のデータ型コードに対応するOracle定義の定数値 (SQLT_NTY、SQLT_REFなど )を含んでいます。 この章に出てくるすべての型についての定数はリストしていませんが、この項では新しい Oracle8のデータ型を説明するとき、それらの定数を使用します。 また、データ型定数は、これらの新しい型を参照するとき、このマニュアルの他の章でも使用されます。

注意 : 名前付きデータ型および REFは、Oracle8 Enterprise Editionを購入した場合に限り、使用可能です。

Page 95: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

新しい OCI 8.0外部データ型

3-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

NAMED DATA TYPE名前付きデータ型は、SQLの CREATE TYPEコマンドで指定するユーザー定義の型です。 例として、オブジェクト型、varray、ネステッド・テーブルなどがあります。 OCIでは、"名前付きデータ型 (named data type)" は型のホスト言語による表現を意味します。SQLT_NTYデータ型コードは、名前付きデータ型をバインドまたは定義する際に使用します。

Cアプリケーションでは、名前付きデータ型は C構造体として表されます。 このような構造体は、データベース内に格納された型からオブジェクト型トランスレータを使用して生成されます。 これらの型は、OCI_TYPECODE_OBJECTに対応します。

関連項目 : OCIでの名前付きデータ型の取扱いについての詳細は、このマニュアルの第2部を参照してください。

名前付きデータ型の C構造体による表現方法の詳細は、第 12章の「オブジェクト型トランスレータの使用」を参照してください。

Page 96: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

新しい OCI 8.0外部データ型

データ型 3-19

REFこれは名前付きデータ型への参照です。 REFの C言語表現は、OCIRef *型として宣言された変数です。SQLT_REFデータ型コードは、REFをバインドまたは定義する際に使用します。

REFにアクセスできるのは、OCIアプリケーションをオブジェクト・モードで初期化した場合だけです。 サーバーから REFが検索されると、REFはクライアント側のオブジェクト・キャッシュに格納されます。

アプリケーションで使用する REFを割り当てるには、変数を REFへのポインタとして宣言し、OCI_TYPECODE_REFを typecodeパラメータとして渡すOCIObjectNew()をコールします。

関連項目 : OCIでの REFの取扱いについての詳細は、このマニュアルの第 2部を参照してください。

LOBLOB(ラージ・オブジェクト )には、長さが最大 4GBのバイナリ・データまたは文字データを格納できます。 バイナリ・データは BLOB(バイナリ LOB)に格納され、文字データは、CLOB(文字 LOB)または NCLOB(各国文字 LOB)に格納されます。

LOB値は、データベースの行データとともに、インラインに格納される場合とされない場合があります。 いずれの場合も、LOBは、データベース・サーバーのトランザクションを完全にサポートしています。 データベースの表には、別の記憶領域にある LOB値を指す LOBロケータが格納されます。

OCIアプリケーションで選択リストに LOB列または属性を含む SQL問合せを発行した場合、問合せ結果のフェッチでは、実際の LOB値ではなくロケータが戻されます。 OCIでは、LOBロケータは OCILobLocator型の変数にマッピングされます。

関連項目 : LOBロケータを含む記述子の詳細は、2-11ページの「記述子およびロケータ」を参照してください。

LOBの詳細は、『Oracle8 Server SQLリファレンス』 および『Oracle8 Serverアプリケーション開発者ガイド』を参照してください。

LOBに対する OCI関数は、LOBロケータを引数の 1つとして受け取ります。 LOBにデータが含まれているかどうかに関係なく、OCI関数はその LOBを指すロケータがすでに作成済みであるとみなします。

バインド操作および定義操作は、OCIDescriptorAlloc()関数で割り当てられる LOBロケータ上で実行されます。

SQLまたは OCIObjectPin()を使用して、常に最初にロケータをフェッチしてから、ロケータを使用して操作を実行します。 OCI関数が実際の LOB値をパラメータとして受け取ることはありません。

Page 97: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

新しい OCI 8.0外部データ型

3-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

関連項目 : OCI COB関数の詳細は、7-23ページの「LOBおよび FILE操作」を参照してください。

LOBをバインドまたは定義するために使用できるデータ型コードは、次のとおりです。

■ SQLT_BLOB - バイナリ LOBデータ型

■ SQLT_CLOB -キャラクタ LOBデータ型

NCLOBは、以下の用件を伴う CLOBの特殊型です。

■ NCLOBに対する書込みおよび読込みを行うには、キャラクタ・セット・フォーム(csfrm)パラメータを SQLCS_NCHARに設定する必要があります。

■ CLOBSおよびNCLOBSを含むコールの "amount" (amtp) パラメータは、バイトよりむしろ文字として常に解釈されます。

FILEFILEデータ型を使うと、Oracle8データベース外のファイル・システムに格納されているファイル LOBへのアクセスが可能になります。 Oracle8は、現在、バイナリ・ファイルまたは BFILEへのアクセスをサポートしています。

BFILEの列または属性には、サーバーのファイル・システムにあるバイナリ・ファイルへのポインタして機能するファイル LOBロケータが格納されます。 このロケータにディレクトリの別名とファイル名が維持されています。

バイナリ・ファイル LOBは、トランザクションでは使用できません。 むしろ、ベースとなるオペレーティング・システムにより、ファイルの統合と恒久性が提供されます。 サポートされるファイルの最大サイズは、4GBです。

データベース管理者は、ファイルが存在していること、および Oracle8のプロセスがそのファイルに対して読取りの権限を持っていることを確認する必要があります。

BFILEデータ型では、大きなバイナリ・ファイルの読込み専用サポートが可能です。Oracleからファイルを変更することはできません。 Oracle8には、ファイル・データにアクセスするための APIが提供されています。 ファイル・データにアクセスするのに使用する主インタフェースは、PL/SQL DBMS_LOBパッケージ、および OCIです。

FILEをバインドまたは定義するために使用できるデータ型コードは、次のとおりです。

■ SQLT_BFILE - バイナリ FILE LOBデータ型(次の項を参照)

ディレクトリ・エイリアスの詳細は、 『Oracle8 Serverアプリケーション開発者ガイド』を参照してください。

BLOBBLOBデータ型には、非構造化バイナリ・ラージ・オブジェクトが格納されます。 BLOBは、キャラクタ・セットとしての意味を持たないビットストリームであると考えることができます。 BLOBには、最大 4GBのバイナリ・データを格納できます。

Page 98: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

データ変換

データ型 3-21

BLOBは完全なトランザクション・サポートを備えています。PL/SQL DBMS_LOBパッケージ、または OCIを通して行った変更は、完全にトランザクションで使用できます。 BLOB値を操作した場合は、それをコミットまたはロールバックできます。 1つのトランザクション内で PL/SQL変数または OCI変数の BLOBロケータを保管し、次にそれを別のトランザクションまたはセッションで使用することはできません。

CLOBCLOBデータ型にはシングルバイト文字データが格納されます。 可変長幅のキャラクタ・セットはサポートされていません。 CLOBには、最大 4GBの文字データを格納できます。

CLOBは完全なトランザクション・サポートを備えています。PL/SQL DBMS_LOB パッケージ、または OCIを通して行った変更は、完全にトランザクションで使用できます。 CLOB値に対して行った操作は、コミットまたはロールバックできます。 1つのトランザクション内で PL/SQL変数または OCI変数の CLOBロケータを保管し、次にそれを別のトランザクションまたはセッションで使用することはできません。

NCLOBNCLOBは CLOBの各国文字バージョンです。 NCLOBは、固定長またはシングルバイト、マルチバイトの各国文字キャラクタ・セット (NCHAR)データを格納します。 可変長幅のキャラクタ・セットはサポートされていません。 NCLOBには、最大 4GBの文字テキスト・データを格納できます。

NCLOBは完全なトランザクション・サポートを備えています。PL/SQL DBMS_LOBパッケージ、または OCIを通して行った変更は、完全にトランザクションで使用できます。 NCLOB値に対して行った操作は、コミットまたはロールバックできます。 1つのトランザクション内で PL/SQL変数または OCI変数のNCLOBロケータを保管し、次にそれを別のトランザクションまたはセッションで使用することはできません。

NCLOB属性を指定してオブジェクトを作成することはできませんが、メソッドで NCLOBパラメータを指定することは可能です。

新しい Cデータ型マップOCIでは、ユーザー定義のデータ型および ADT属性を C表現にマッピングするために使用される、Oracle定義の Cデータ型がサポートされるようになりました (OCINumber、OCIArrayなど )。 OCIでは、これらのデータ型を操作するための一連の OCIコールが用意されています。これらのデータ型は、OCI外部データ型コードとともに、バインド操作および定義操作で使用できます。 これらの Oracle定義 Cデータ型の詳細は、第 9章の「オブジェクト・リレーショナル・データ型」を参照してください。

データ変換表 3–5は、リリース 7.3で使用可能な全データ型について、内部 Oracleデータ型から外部データ型、および外部データ型から内部列表現へのサポートされている変換を示していま

Page 99: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

データ変換

3-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

す。リリース 8.0で新しく加わったデータ型に関するデータ変換の情報は、以下にリストします。

■ データベースに格納されている REFは、出力時に SQLT_REFに変換されます。

■ SQLT_REFは、入力時に REFの内部表現に変換されます。

■ データベースに格納されている名前付きデータ型は、出力時に SQLT_NTYに変換されます(アプリケーション内では C構造体で表される)。

■ SQLT_NTY(アプリケーション内では C構造体で表される)は、入力時に対応する型の内部表現へ変換されます。

■ LOBおよび BFILEは、OCIアプリケーション内では記述子によって表されるため、出力時または入力時の変換は行われません。

■ OCIStringおよび OCINumberその他の Oracle8新データ型の詳細は、第 9章「オブジェクトリレーショナル・データ型」および第 10章の「オブジェクト・アプリケーションでのバインディングおよび定義」を参照してください。

表 3–5 データ変換

外部

データ型

内部データ型

1VARCHAR2

2NUMBER

8LONG

11ROWID

12DATE

23RAW

24LONG RAW

96CHAR

105MLSLABEL

1 VARCHAR I/O I/O I/O I/O(1) I/O(2) I/O(3) I/O(3) I/O(7)

2 NUMBER I/O(4) I/O I I/O(4)

3 INTEGER I/O(4) I/O I I/O(4)

4 FLOAT I/O(4) I/O I I/O(4)

5 STRING I/O I/O I/O I/O(1) I/O(2) I/O(3) I/O(3, 5) I/O I/O(7)

6 VARNUM I/O(4) I/O I I/O(4)

7 DECIMAL I/O(4) I/O I I/O(4)

8 LONG I/O I/O I/O I/O(1) I/O(2) I/O(3) I/O(3, 5) I/O I/O(7)

9 VARCHAR I/O I/O I/O I/O(1) I/O(2) I/O(3) I/O(3, 5) I/O I/O(7)

11 ROWID I I I/O I

12 DATE I/O I I/O I/O

15 VARRAW I/O(6) I(5,6) I/O I/O I/O(6)

23 RAW I/O(6) I(5,6) I/O I/O I/O(6)

24 LONG RAW O(6) I(5,6) I/O I/O O(6)

68 UNSIGNED I/O(4) I/O I I/O(4)

94 LONG VARCHAR I/O I/O I/O I/O(1) I/O(2) I/O(3) I/O(3, 5) I/O I/O(7)

Page 100: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

型コード

データ型 3-23

型コードOracle8の型はそれぞれ、スカラー、コレクション、参照、オブジェクト型のどれであっても、他と重複しない型コードと関連付けられています。 この型コードで型を識別します。また、この型コードはオブジェクト型属性についての情報を管理するために Oracleで使用されます。 この型コード・システムは、汎用的で拡張可能に設計されており、Oracleデータ型への 1対 1の直接マップには連結されていません。 次の SQL文で考えてみます。

CREATE TYPE my_type AS OBJECT( attr1 NUMBER,attr2 INTEGER,attr3 SMALLINT)

CREATE TABLE my_table AS TABLE OF my_type;

これらの文では、オブジェクト型とオブジェクト表を作成します。 作成された際に、my_tableには 3つの列がありますが、これらはすべて Oracle NUMBER型となります。これは、SMALLINTと INTEGERが内部的にNUMBERにマップするためです。 ただし、my_typeの属性の内部表現は、これら 3つの属性のデータ型の区別を次のように維持します。 attr1は OCI_TYPECODE_NUMBER、attr2は OCI_TYPECODE_INTEGER、そしてattr3は OCI_TYPECODE_SMALLINTです。 アプリケーションで my_typeを記述する場合、これらの型コードが戻されます。

OCITypeCodeは、型コードの Cデータ型です。 型コードは、OCIObjectNew() (どの型のオブジェクトが作成されたかを判別するのに役立つ )などの一部の OCI関数で使用されます。

95 LONG VARRAW I/O(6) I(5,6) I/O I/O I/O(6)

96 CHAR I/O I/O I/O I/O(1) I/O(2) I/O(3) I(3) I/O I/O(7)

97 CHARZ I/O I/O I/O I/O(1) I/O(2) I/O(3) I(3) I/O I/O(7)

104 ROWID DESC.

106 MLSLABEL I/O(8)

注意 :

(1) 入力時、ホスト文字列は Oracle ROWID形式であることが必要です。出力時、列値は Oracle ROWID形式で戻されます。

(2) 入力時、ホスト文字列は Oracle DATE文字形式であることが必要です。出力時、列値は Oracle DATE形式で戻されます。

(3) 入力時、ホスト文字列は 16進数形式であることが必要です。出力時、列値は 16進数形式で戻されます。

(4) 出力時、列値は有効な数値を表していることが必要です。

(5) 長さは 2000以下であることが必要です。

(6) 入力時、列値は 16進数形式で格納されます。出力時、列値は 16進数形式であることが必要です。

(7) 入力時、ホスト文字列はテキスト形式の有効な OSラベルであることが必要です。出力時、列値はテキスト形式の OSラベルで戻されます。

(8) MLSLABELの文字表現には、TO_CHAR(mlscolumn)関数を使用します。

凡例 :

I = 入力時のみ有効な変換

O = 出力時のみ有効な変換

I/O = 入力時または出力時に有効な変換

表 3–5 データ変換 (続き )

外部

データ型

内部データ型

1VARCHAR2

2NUMBER

8LONG

11ROWID

12DATE

23RAW

24LONG RAW

96CHAR

105MLSLABEL

Page 101: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

型コード

3-24 Oracle8コール・インタフェース・プログラマーズ・ガイド

また、オブジェクトが記述されるとき、いくつかの属性の値としても戻されます。たとえば、OCI_ATTR_TYPECODE属性の型の問合せを行うと、OCITypeCodeの値が戻ります。

表 3–6 は、OCITypeCodeに可能な値をリストしています。 各 Oracle8データ型があります。

SQLT値および OCI_TYPECODE値の関係Oracleでは、2種類のデータ型コード値のセットを認識します。 これらのセットは、1つは"SQLT_"型、もう 1つは "OCI_TYPECODE_"型として区別されます。

表 3–6 OCI型コード値

値 データ型

OCI_TYPECODE_REF REF

OCI_TYPECODE_DATE 日付

OCI_TYPECODE_REAL 単精度実数

OCI_TYPECODE_DOUBLE 倍精度実数

OCI_TYPECODE_FLOAT 浮動小数点

OCI_TYPECODE_NUMBER Oracle数値

OCI_TYPECODE_DECIMAL 10進数

OCI_TYPECODE_OCTET 8進数

OCI_TYPECODE_INTEGER INTEGER

OCI_TYPECODE_SMALLINT small整数

OCI_TYPECODE_RAW RAW

OCI_TYPECODE_VARCHAR2 ANSI SQLの可変文字列、すなわち VARCHAR2

OCI_TYPECODE_VARCHAR Oracle SQLの可変文字列、すなわち VARCHAR

OCI_TYPECODE_CHAR SQL内部の固定長文字列、すなわち SQL CHAR

OCI_TYPECODE_VARRAY 可変長配列 (varray)

OCI_TYPECODE_TABLE 多重集合

OCI_TYPECODE_CLOB キャラクタ・ラージ・オブジェクト (CLOB)

OCI_TYPECODE_BLOB バイナリ・ラージ・オブジェクト (BLOB)

OCI_TYPECODE_BFILE バイナリ・ラージ・オブジェクト・ファイル(BFILE)

OCI_TYPECODE_OBJECT 名前付きオブジェクト型

OCI_TYPECODE_NAMEDCOLLECTION ドメイン(名前付きプリミティブ型)

Page 102: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

型コード

データ型 3-25

SQLT型コードは、バインドまたは定義操作でデータ型を指定するために、OCIで使用されます。 このように、SQL型コードは、Oracleと OCIクライアント・アプリケーション間のデータ変換を制御するのに役立ちます。 OCI_TYPECODE型は、ユーザー定義型を操作または作成する際に、Oracle8の型システムで定義済みの型を参照または記述するために使われます。

多くの場合、SQLT値と OCI_TYPECODE値の間で、直接マッピングがあります。 ただし、1対 1の直接マッピングがない場合もあります。 たとえば、OCI_TYPECODE_SIGNED16および OCI_TYPECODE_SIGNED32、OCI_TYPECODE_INTEGER、OCI_TYPECODE_OCTET、OCI_TYPECODE_SMALLINTはすべて、SQLT_INT型にマップされます。

次の表では、SQLT型と OCI_TYPECODE型の間のマッピングを示します。

表 3–7 OCI_TYPECODEから SQLTへのマップ

Oracle型システムの型名 Oracle型システムの型 等価 SQLT型

BFILE OCI_TYPECODE_BFILE SQLT_BFILE

BLOB OCI_TYPECODE_BLOB SQLT_BLOB

CHAR OCI_TYPECODE_CHAR (n) SQLT_AFC(n) [注意 1]

CLOB OCI_TYPECODE_CLOB SQLT_CLOB

COLLECTION OCI_TYPECODE_NAMEDCOLLECTION SQLT_NCO

DATE OCI_TYPECODE_DATE SQLT_DAT

FLOAT OCI_TYPECODE_FLOAT (b) SQLT_FLT (8) [注意 2]

DECIMAL OCI_TYPECODE_DECIMAL (p) SQLT_NUM (p, 0) [注意 3]

DOUBLE OCI_TYPECODE_DOUBLE SQLT_FLT (8)

INTEGER OCI_TYPECODE_INTEGER SQLT_INT (i) [注意 4]

NUMBER OCI_TYPECODE_NUMBER (p, s) SQLT_NUM (p, s) [注意 5]

OCTECT OCI_TYPECODE_OCTECT SQLT_INT (1)

POINTER OCI_TYPECODE_PTR <NONE>

RAW OCI_TYPECODE_RAW SQLT_LVB

REAL OCI_TYPECODE_REAL SQLT_FLT (4)

REF OCI_TYPECODE_REF SQLT_REF

OBJECT OCI_TYPECODE_OBJECT SQLT_NTY

SIGNED(8) OCI_TYPECODE_SIGNED8 SQLT_INT (1)

SIGNED(16) OCI_TYPECODE_SIGNED16 SQLT_INT (2)

SIGNED(32) OCI_TYPECODE_SIGNED32 SQLT_INT (4)

SMALLINT OCI_TYPECODE_SMALLINT SQLT_INT (i) [注意 4]

TABLE [注意 6] OCI_TYPECODE_TABLE SQLT_TAB

Page 103: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

3-26 Oracle8コール・インタフェース・プログラマーズ・ガイド

oratypes.hの定義このマニュアルでは、全体を通して ub2、sb4などのデータ型、または UB4MAXVALなどの定数を参照することができます。 これらの型は、次の例でも示すように、oratypes.hヘッダー・ファイルで定義されます。 正確な内容は、使用しているプラットフォームによって異なります。

#ifndef ORASTDDEF# include <stddef.h># define ORASTDDEF#endif

#ifndef ORALIMITS# include <limits.h># define ORALIMITS#endif

#ifndef SX_ORACLE#define SX_ORACLE#define SX#define ORATYPES

#ifndef TRUE# define TRUE 1# define FALSE 0#endif

UNSIGNED(8) OCI_TYPECODE_UNSIGNED8 SQLT_UIN (1)

UNSIGNED(16) OCI_TYPECODE_UNSIGNED16 SQLT_UIN (2)

UNSIGNED(32) OCI_TYPECODE_UNSIGNED32 SQLT_UIN (4)

VARRAY [注意 6] OCI_TYPECODE_VARRAY SQLT_NAR

VARCHAR OCI_TYPECODE_VARCHAR (n) SQLT_CHR (n) [注意 1]

VARCHAR2 OCI_TYPECODE_VARCHAR2 (n) SQLT_VCS (n) [注意 1]

注意 :

1. nはバイト単位の文字列サイズです。

2. これらは浮動小数点数で、精度は 2進数で与えられます。 bは、数値の精度を 2進数の数字で表します。

3. これは小数点以下の数値を伴わない NUMBERと等価です。

4. iはバイト単位の数値サイズで、OCIコールの一部として設定されます。

5. pは 10進数での数値の精度です。sは 10進数での数値のスケールです。

6. 名前付きコレクション型の一部としてのみ可能です。

表 3–7 OCI_TYPECODEから SQLTへのマップ (続き )

Oracle型システムの型名 Oracle型システムの型 等価 SQLT型

Page 104: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

データ型 3-27

#ifdef lint# ifndef mips# define signed# endif #endif

#ifdef ENCORE_88K# ifndef signed# define signed# endif #endif

#if defined(SYSV_386) || defined(SUN_OS)# ifdef signed# undef signed# endif # define signed#endif

#ifndef linttypedef int eword;typedef unsigned int uword;typedef signed int sword;#else#define eword int#define uword unsigned int#define sword signed int#endif

#define EWORDMAXVAL ((eword) INT_MAX)#define EWORDMINVAL ((eword) 0)#define UWORDMAXVAL ((uword)UINT_MAX)#define UWORDMINVAL ((uword) 0)#define SWORDMAXVAL ((sword) INT_MAX)#define SWORDMINVAL ((sword) INT_MIN)#define MINEWORDMAXVAL ((eword) 32767)#define MAXEWORDMINVAL ((eword) 0)#define MINUWORDMAXVAL ((uword) 65535)#define MAXUWORDMINVAL ((uword) 0)#define MINSWORDMAXVAL ((sword) 32767)#define MAXSWORDMINVAL ((sword) -32767)

#ifndef lint

Page 105: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

3-28 Oracle8コール・インタフェース・プログラマーズ・ガイド

# ifdef mipstypedef signed char eb1;# elsetypedef char eb1;# endif typedef unsigned char ub1;typedef signed char sb1;#else#define eb1 char#define ub1 unsigned char#define sb1 signed char#endif

#define EB1MAXVAL ((eb1)SCHAR_MAX)#define EB1MINVAL ((eb1) 0)#if defined(mips)# ifndef lint# define UB1MAXVAL (UCHAR_MAX)# endif#endif#ifndef UB1MAXVAL# ifdef SCO_UNIX# define UB1MAXVAL(UCHAR_MAX)#else# define UB1MAXVAL ((ub1)UCHAR_MAX)# endif #endif#define UB1MINVAL ((ub1) 0)#define SB1MAXVAL ((sb1)SCHAR_MAX)#define SB1MINVAL ((sb1)SCHAR_MIN)#define MINEB1MAXVAL ((eb1) 127)#define MAXEB1MINVAL ((eb1) 0)#define MINUB1MAXVAL ((ub1) 255)#define MAXUB1MINVAL ((ub1) 0)#define MINSB1MAXVAL ((sb1) 127)#define MAXSB1MINVAL ((sb1) -127)

#define UB1BITS CHAR_BIT#define UB1MASK ((1 << ((uword)CHAR_BIT)) - 1)

typedef unsigned char OraText;

#ifndef LUSEMFC# define text OraText#endif

Page 106: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

データ型 3-29

#ifndef linttypedef short eb2;typedef unsigned short ub2;typedef signed short sb2;#else#define eb2 short#define ub2 unsigned short#define sb2 signed short#endif

#define EB2MAXVAL ((eb2) SHRT_MAX)#define EB2MINVAL ((eb2) 0)#define UB2MAXVAL ((ub2)USHRT_MAX)#define UB2MINVAL ((ub2) 0)#define SB2MAXVAL ((sb2) SHRT_MAX)#define SB2MINVAL ((sb2) SHRT_MIN)#define MINEB2MAXVAL ((eb2) 32767)#define MAXEB2MINVAL ((eb2) 0)#define MINUB2MAXVAL ((ub2) 65535)#define MAXUB2MINVAL ((ub2) 0)#define MINSB2MAXVAL ((sb2) 32767)#define MAXSB2MINVAL ((sb2)-32767)

#if defined(A_OSF)

#ifndef linttypedef int eb4;typedef unsigned int ub4;typedef signed int sb4;#else#define eb4 int#define ub4 unsigned int#define sb4 signed int#endif

#define EB4MAXVAL ((eb4) INT_MAX)#define EB4MINVAL ((eb4) 0)#define UB4MAXVAL ((ub4) UINT_MAX)#define UB4MINVAL ((ub4) 0)#define SB4MAXVAL ((sb4) INT_MAX)#define SB4MINVAL ((sb4) INT_MIN)#define MINEB4MAXVAL ((eb4) 2147483647)#define MAXEB4MINVAL ((eb4) 0)#define MINUB4MAXVAL ((ub4) 4294967295)#define MAXUB4MINVAL ((ub4) 0)#define MINSB4MAXVAL ((sb4) 2147483647)

Page 107: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

3-30 Oracle8コール・インタフェース・プログラマーズ・ガイド

#define MAXSB4MINVAL ((sb4)-2147483647)

#else

#ifndef linttypedef long eb4;typedef unsigned long ub4;typedef signed long sb4;#else#define eb4 long#define ub4 unsigned long#define sb4 signed long#endif

#define EB4MAXVAL ((eb4) LONG_MAX)#define EB4MINVAL ((eb4) 0)#define UB4MAXVAL ((ub4)ULONG_MAX)#define UB4MINVAL ((ub4) 0)#define SB4MAXVAL ((sb4) LONG_MAX)#define SB4MINVAL ((sb4) LONG_MIN)#define MINEB4MAXVAL ((eb4) 2147483647)#define MAXEB4MINVAL ((eb4) 0)#define MINUB4MAXVAL ((ub4) 4294967295)#define MAXUB4MINVAL ((ub4) 0)#define MINSB4MAXVAL ((sb4) 2147483647)#define MAXSB4MINVAL ((sb4)-2147483647)#endif

#ifndef linttypedef unsigned long ubig_ora;typedef signed long sbig_ora;#else#define ubig_ora unsigned long#define sbig_ora signed long#endif

#define UBIG_ORAMAXVAL ((ubig_ora)ULONG_MAX)#define UBIG_ORAMINVAL ((ubig_ora) 0)#define SBIG_ORAMAXVAL ((sbig_ora) LONG_MAX)#define SBIG_ORAMINVAL ((sbig_ora) LONG_MIN)#define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295)#define MAXUBIG_ORAMINVAL ((ubig_ora) 0)#define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647)#define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647)

Page 108: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

データ型 3-31

#define UBIGORABITS (UB1BITS * sizeof(ubig_ora))

#define SLU8NATIVE#define SLS8NATIVE #ifdef SLU8NATIVE

#ifndef linttypedef unsigned long long ub8;#else#define ub8 unsigned long long#endif #define UB8ZERO ((ub8)0) #define UB8MINVAL ((ub8)0)#define UB8MAXVAL ((ub8)18446744073709551615) #define MAXUB8MINVAL ((ub8)0)#define MINUB8MAXVAL ((ub8)18446744073709551615) #endif #ifdef SLS8NATIVE

#ifndef linttypedef signed long long sb8;#else#define sb8 signed long long#endif

#define SB8ZERO ((sb8)0)

#define SB8MINVAL ((sb8)-9223372036854775808)#define SB8MAXVAL ((sb8) 9223372036854775807)

#define MAXSB8MINVAL ((sb8)-9223372036854775807)#define MINSB8MAXVAL ((sb8) 9223372036854775807)

#endif

Page 109: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

3-32 Oracle8コール・インタフェース・プログラマーズ・ガイド

#undef CONST

#ifdef _olint# define CONST const#else#if defined(PMAX) && defined(__STDC__)# define CONST const#else# ifdef M88OPEN# define CONST const# else # if defined(SEQ_PSX) && defined(__STDC__)# define CONST const# else # ifdef A_OSF# if defined(__STDC__)# define CONST const# else# define CONST# endif# else# define CONST# endif # endif # endif #endif #endif

#ifdef lint# define dvoid void#else

# ifdef UTS2# define dvoid char# else# define dvoid void# endif

#endif

typedef void (*lgenfp_t)( void );

#ifndef ORASYSTYPES# include <sys/types.h># define ORASYSTYPES

Page 110: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

データ型 3-33

#endif #define boolean int

#ifdef sparc# define SIZE_TMAXVAL SB4MAXVAL#else# define SIZE_TMAXVAL UB4MAXVAL#endif

#define MINSIZE_TMAXVAL (size_t)65535

#endif

Page 111: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

oratypes.hの定義

3-34 Oracle8コール・インタフェース・プログラマーズ・ガイド

Page 112: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQL文の処理 4-1

4SQL文の処理

この章では、Oracleコール・インタフェースを使った SQL文の処理に関する概念およびステップを説明します。

この章では、次のトピックで構成されています。

■ 概要

■ SQL文の処理

■ 文の準備

■ バインディング

■ 文の実行

■ 選択リスト項目の記述

■ 定義

■ 結果のフェッチ

Page 113: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

概要

4-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

概要第 2章では、OCIアプリケーションに含まれる基本ステップについて説明しました。この章では、OCIプログラムで SQL文を処理するときの特定の作業について、さらに詳細に説明します。

SQL文の処理OCIプログラムの最も一般的なタスクの 1つは、SQL文の受入れと処理です。この項では、SQL処理に含まれる特定のステップの概要を説明します。

いったん必要なハンドルを割り当ててサーバーへ連結した後は、図 4–1に示した以下の基本ステップで SQL文の処理を行います。

1. 準備。 OCIStmtPrepare()を使用してアプリケーション要求を定義します。

2. バインド。 入力変数を伴う DML文および問合せの場合、OCIBindByPos()またはOCIBindByName()、OCIBindObject()、OCIBindDynamic()、OCIBindArrayOfStruct()を使ってバインドコールを 1つ以上実行し、各入力変数(または PL/SQL出力変数)または各配列のアドレスを文中の各プレースホルダへバインドします。

3. 実行。 OCIStmtExecute()をコールして文を実行します。DDL文の場合は、これ以降のステップは必要ありません。

4. 記述。 必要な場合は、OCIParamGet()および OCIAttrGet()を使用して、選択リスト項目を記述します。このステップはオプションです。選択リスト項目の数および各項目の属性(長さやデータ型など)がコンパイル時にわかっている場合には、このステップは必要ありません。

5. 定義。 問合せの場合には、OCIDefineByPos()または OCIDefineObject()、OCIDefineDynamic()、OCIDefineArrayOfStruct()の定義コールを 1つ以上実行して、SQL文の各選択リスト項目に対して出力変数を定義します。無名 PL/SQLブロックの出力変数の定義には定義コールを使用しないことに注意してください。その定義は、データをバインドする時点ですでに行われています。

6. フェッチ。問合せの場合は、OCIStmtFetch()をコールして問合せの結果をフェッチします。

これらのステップの後、アプリケーションでは割り当てたハンドルを解放し、次にサーバーから接続解除するか、追加の文を処理できます。

7.x⦆アップグレードの注意 : 明示的解析ステップは OCIプログラムでは不要になりました。文の解析が必要な場合、解析のステップは実行時に行われます。これは、8.0のアプリケーションでは、DML文と DDL文の両方に対して実行コマンドを発行する必要があるということです。

Page 114: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQL文の処理

SQL文の処理 4-3

図 4–1 SQL文の処理におけるステップ

この図では、各ステップについて、対応する OCI関数コールを示しています。複数のコールが必要な場合もあります。

上記のステップの詳細は、次の項を参照してください。

注意 : ステップの順序には、いくつかのバリエーションがあります。たとえば、コンパイル時にデータ型と戻される値の長さがわかっている場合には、実行前に定義ステップを処理できます。また、アスタリスク (*)で示しているように、アプリケーションによってはいくつかのステップは不要です。

アプリケーションで次のことを行う場合には、図に示したステップの他に追加ステップが必要です。

– 複数トランザクションの開始および管理

– 実行の複数スレッドの管理

– ピース単位の挿入または更新、フェッチの実行

これらのトピックの詳細は、第 7章を参照してください。

*

OCIStmtPrepare()

OCIStmtExecute()

OCIStmtFetch()

OCIDefineByPos()OCIDefineObject()OCIDefineArrayOfStruct()OCIDefineDynamic()

OCIParamGet()OCIAttrGet()

OCIBindByName() or OCIBindByPos()OCIBindObject()OCIBindArrayOfStruct()OCIBindDynamic()

Page 115: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

文の準備

4-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

文の準備SQL文および PL/SQL文は、文の準備コールおよびバインド・コール(必要な場合)を使用して、実行の準備をする必要があります。このフェーズでは、アプリケーションは SQL文または PL/SQL文を指定し、文中の関連付けられたプレースホルダをデータにバインドして実行できるようにします。クライアント側ライブラリによって、実行準備の済んだ文を保持するための記憶域が割り当てられます。

アプリケーションでは、OCIStmtPrepare()コールを使用し、事前に割り当てられている文ハンドルに SQL文または PL/SQL文を渡すことによって、文の実行準備を要求します。これは、完全なローカル・コールであるため、サーバーとの往復は必要ありません。この時点では、文と特定のサーバーとの関連付けは行われません。

要求コールの後、アプリケーションから文ハンドルで OCIAttrGet()をコールし、attrtypeパラメータへ OCI_ATTR_STMT_TYPEを渡すことにより、準備されている SQL文の種類を調べることができます。可能な属性値とそれに対応する文の種類は、表 4–1にリストされています。

関連項目 : OCIアプリケーションでの PL/SQL使用方法の詳細は、2-30ページの「OCIプログラムでの PL/SQL使用」を参照してください。

OCIStmtPrepare()コールの詳細は、第 13章の「OCIリレーショナル関数」を参照してください。

複数サーバーでの準備済みの文使用方法文ハンドルとサーバーの個々のサービス・コンテキスト・ハンドルの再関連付けによって、準備済みのアプリケーション要求を実行時に複数のサーバーに対して実行できます。新たな

表 4–1 OCI_ATTR_STMT_TYPE値および文の種類

属性値 文の種類

OCI_STMT_SELECT SELECT文

OCI_STMT_UPDATE UPDATE文

OCI_STMT_DELETE DELETE文

OCI_STMT_INSERT INSERT文

OCI_STMT_CREATE CREATE文

OCI_STMT_DROP DROP文

OCI_STMT_ALTER ALTER文

OCI_STMT_BEGIN BEGIN... (PL/SQL)

OCI_STMT_DECLARE DECLARE... (PL/SQL)

Page 116: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

SQL文の処理 4-5

関連付けが行われると、現行のサービス・コンテキスト・ハンドルと文ハンドル間の関連付けについてキャッシュされている情報はすべて失われます。

たとえば、複数のサーバーを管理するネットワーク・マネージャのようなアプリケーションを考えてみます。多くの場合、情報を検索して表示するために、同一の SELECT文を 複数のサーバーに対して実行する必要があります。OCIによって、サーバー・マネージャ・アプリケーションでは SELECT文を一度準備するだけで、それを複数のサーバーに対して実行できます。準備済みの文を次のサーバーに再関連付けする前に、各サーバーから必要なすべての行をフェッチしておく必要があります。

注意 : 準備済みの文を同じサーバーで頻繁に再実行する必要がある場合は、別のサービス・コンテキスト用に新しい文を準備すると効率的です。

バインディング大部分の DML文と一部の問合せ (WHERE句を使用した問合せなど )では、プログラムで、データを SQLまたは PL/SQL文の一部として Oracleに渡す必要があります。このようなデータは、プログラムのコンパイル時にわかっている定数またはリテラル・データです。たとえば、SQL文は従業員をデータベースへ追加するものですが、これには ’BESTRY’および2365などのリテラルがいくつか含まれています。

INSERT INTO emp VALUES (2365, ’BESTRY’, ’PROGRAMMER’, 2000, 20)

このように、文をアプリケーション内にハード・コーディングすることは、非常に非効率的です。データベースに新しい従業員を追加するたびに、文を変更してプログラムを再コンパイルする必要があります。ユーザーが実行時に入力データを指定できるようにすれば、プログラムにもっと柔軟性を持たせることができます。

入力データが実行時に指定される SQL文または PL/SQLブロックを準備する場合は、SQL文または PL/SQLブロックのプレースホルダによって、どの位置にデータが入力されるのかをマークします。たとえば、次の SQL文には、5つのプレースホルダが含まれています。プレースホルダは先頭にコロンが付き (:enameなど )、プログラムにより入力データが供給される必要があることを示しています。

INSERT INTO emp VALUES (:empno, :ename, :job, :sal, :deptno)

入力変数のプレースホルダは、DELETE文、INSERT文、SELECT文、UPDATE文、PL/SQLブロックで、式またはリテラル値を使用できる位置であれば文中のどの位置でも使用できます。PL/SQLでは、出力変数にもプレースホルダを使用できます。

注意 : プレースホルダを、表などの他の Oracleオブジェクトを表すために使用することはできません。たとえば、次の例は :empプレースホルダの有効な使用方法ではありません。

INSERT INTO :emp VALUES (12345, ’OERTEL’, ’ WRITER’, 50000, 30)

Page 117: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

文の実行

4-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

SQL文または PL/SQLブロックの各プレースホルダに対して、プログラム内の変数のアドレスをプレースホルダにバインドする OCIルーチンをコールする必要があります。Oracleでは、文を実行すると、プログラムで入力変数またはバインド変数に入れたデータが読み取られ、それが SQL文でサーバーに渡されます。

バインド操作のインプリメンテーションの詳細は 第 5章の「バインディングと定義」を参照してください。

文の実行OCIアプリケーションは、OCIStmtExecute()を使用して、準備済みの文を個別に実行します。

OCIアプリケーションで問合せを実行すると、問合せ指定に合致するデータを Oracleから受け取ります。データベース内では、データは Oracle独自の形式で格納されています。戻された結果に対して、OCIアプリケーションでは、データを特定のホスト言語形式に変換し、それを特定の出力変数またはバッファ内に格納することを要求できます。

問合せの選択リスト各項目に対し、問合せの結果を受け取るため、OCIアプリケーションは出力変数を定義しなければなりません。定義ステップでは、バッファのアドレスおよび検索対象データの型を指示します。

注意 : OCIStmtExecute()コール前に出力変数が SELECT文に対して定義されている場合、itersパラメータで指定した行数が定義済みの出力バッファへ直接フェッチされ、プリフェッチ・カウントと等価な追加行がプリフェッチされます。追加行がない場合、フェッチは OCIStmtFetch()をコールしないで完了します。

問合せ以外では、OCIStmtExecute()コールの itersパラメータは、配列操作中の文の実行回数を制御します。たとえば、10項目の配列が INSERT文の 1個のプレースホルダにバインドされていて、itersが 10と設定されている場合、10項目すべてが 1回の実行コールで挿入されます。

関連項目 : 出力変数定義の詳細は、4-11ページの「定義」を参照してください。

実行スナップショットOCIStmtExecute()コールを使うと、データベースのコミット済みデータの一貫した同一スナップショット上で、複数のサービス・コンテキストが確実に動作します。これは、特定のOCIStmtExecute()コールの snap_outパラメータの内容を読み取り、その値を次のOCIStmtExecute()コールの snap_inパラメータに渡すことによって実現されます。

注意 : 特定のサービス・コンテキストにコミットされていないデータがある場合、同じスナップショットを使っていても、そのデータは他のコンテキストには認識されません。

snap_outパラメータおよび snap_inパラメータのデータ型は、どちらも OCIスナップショット記述子のデータ型 OCISnapshotです。この記述子は OCIDescAlloc()関数で割り当てられます。

Page 118: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

文の実行

SQL文の処理 4-7

関連項目 : 記述子の詳細は、2-11ページの「記述子およびロケータ」を参照してください。

OCIStmtExecute()をコールする場合には、スナップショットを指定する必要はありません。次のサンプル・コードは、スナップショット・パラメータが NULLとして渡される基本的な実行例を示しています。

checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (OCISnapshot *)NULL, (OCISnapshot *) NULL, OCI_DEFAULT))

注意 : checkerr()機能によって、OCIアプリケーションからのリターン・コードが評価されます。この関数用のコードの詳細は、2-24ページの「エラー処理」を参照してください。

実行モードユーザーは、OCIStmtExecute()コールの 3つのモードから 1つを指定できます。

■ OCI_DEFAULT。このモードで OCIStmtExecute()をコールすると、文が実行されます。また、選択リストに関する記述情報が暗黙的に戻されます。

■ OCI_DESCRIBE_ONLY。このモードは、実行の前に問合せを記述したいユーザー用です。OCIStmtExecute()をこのモードでコールすると、文は実行されませんが、選択リスト記述は戻されます。

■ OCI_COMMIT_ON_SUCCESS。このモードで文を実行した場合、実行が正常に終了すると、実行後に現行のトランザクションがコミットされます。

Page 119: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

選択リスト項目の記述

4-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

選択リスト項目の記述OCIアプリケーションで問合せを処理する場合には、選択リストの項目に関して詳細な情報を取得する必要があります。実行時まで問合せの内容がわからない動的問合せの場合は、特にそうです。そのような場合、プログラムでは、選択リスト項目のデータ型および列の長さに関する情報を取得する必要があります。この情報は、問合せの結果を受け取る出力変数を定義するために必要です。

たとえば、ユーザーが次の問合せを入力したとします。

SELECT * FROM employees

プログラムには、employees表の列についての事前情報はありません。

リリース 8.0で使用可能な記述の種類には、暗黙的および明示的の 2つがあります。暗黙的な記述は、サーバーから記述情報を取り出すのに特別なコールを要求しない記述です(ただし、情報にアクセスするには特別なコールが必要です)。明示的な記述は、サーバーから記述情報を得るために、アプリケーションから特定の関数をコールする必要がある記述です。

アプリケーションでは、選択リスト(問合せ)を暗黙的にも明示的にも記述できます。その他のスキーマ要素は、明示的に記述する必要があります。

暗黙的な記述の場合、アプリケーションでは、文の実行が終わった後に文ハンドルの属性として選択リストの情報を取得できます。特定の記述コールは必要ありません。記述コールが不要なため、これは「暗黙的」と呼ばれます。記述情報は何もしなくとも実行時に供給されます。

ユーザーは、実行前に、問合せを明示的に記述することを選択できます。そのためには、OCIStmtExecute()のモードとして OCI_DESCRIBE_ONLYを指定します。OCIStmtExecute()をこのモードでコールすると、文は実行されませんが、選択リスト記述は戻されます。ただしパフォーマンスを向上させるには、標準な文を実行時に何もしなくても得られる暗黙的記述をアプリケーションで活用することを推奨します。

OCIDescribeAny()コールを使用した明示的な記述では、選択リストではなく、スキーマ・オブジェクトに関する情報を取得します。

すべての場合において、列およびデータ型に関する特定の情報は、ハンドル属性を読み取ることによって検索されます。

関連項目 : スキーマ・オブジェクトに関するメタデータの OCIDescribeAny()による取得の詳細は、 第 6章の「スキーマ・メタデータの記述」を参照してください。

暗黙的記述SQL文を実行した後、文ハンドルの属性として選択リストに関する情報を取得できます。明示的な記述コールは必要ありません。

アプリケーションで文ハンドルから選択リストに関する情報を検索するには、選択リストの各位置に対して OCIParamGet()を 1回ずつコールし、その位置のパラメータ記述子を割り当

Page 120: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

選択リスト項目の記述

SQL文の処理 4-9

てる必要があります。選択リスト位置は 1-が基準となります。これは選択リストの最初の項目が位置数値 1であることを意味しています。

複数の選択リストに関する情報を検索するには、最初に posパラメータを 1と設定したOCIParamGet()をコールし、次に posの値を反復して、OCI_NO_DATAが戻されるまでOCIParamGet()コールを繰り返します。また、アプリケーションでは、列をランダムに取得するために、位置 nを指定できます。

アプリケーションでは、選択リストの位置のパラメータ記述子を割り当てた後、パラメータ記述子について OCIAttrGet()をコールすることによって、特定の情報を検索できます。パラメータ記述子から取得できる情報として、データ型とパラメータの最大サイズがあります。

次のサンプル・コードでは、問合せ実行に続く問合せに対応した列名やデータ型を取り出すループを示しています。この問合せは、事前に OCIStmtPrepare()のコールによって文ハンドルと関連付けられています。

OCIParam *mypard;ub4 counter;ub2 dtype;text *col_name;ub4 col_name_len;sb4 parm_status;

...

/* Request a parameter descriptor for position 1 in the select-list */counter = 1;parm_status = OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, &mypard,

(ub4) counter);

/* Loop only if a descriptor was successfully retrieved forcurrent position, starting at 1 */

while (parm_status==OCI_SUCCESS) {

/* Retrieve the data type attribute */checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM, (dvoid*) &dtype,(ub4 *) 0, (ub4) OCI_ATTR_DATA_TYPE, (OCIError *) errhp ));

/* Retrieve the column name attribute */checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM,

(dvoid**) &col_name,(ub4 *) &col_name_len, (ub4) OCI_ATTR_NAME, (OCIError *) errhp ));

printf("column=%s datatype=%d\n\n", col_name, dtype);fflush(stdout);

/* increment counter and get next descriptor, if there is one */

Page 121: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

選択リスト項目の記述

4-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

counter++;parm_status = OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, &mypard,

(ub4) counter);}

注意 : 最初の OCIParamGet()コールのエラー処理は、この例に含まれていません。省略記号 (...)は、この例で部分的にコードを省略した箇所を示しています。

checkerr()関数は、エラー処理に使用します。完全なリストは、付録 Dの「コード例」の最初のアプリケーション例を参照してください。

OCIAttrGet()および OCIParamGet()のコールは、ネットワーク往復を必要としないローカル・コールです。これは、文の実行後すべての選択リスト情報がクライアント側にキャッシュされるためです。

関連項目 : これらのコールの詳細は、 第 13章の「OCIリレーショナル関数」のOCIParamGet()および OCIAttrGet()の説明を参照してください。

OCIAttrGet()で読み込めるパラメータ記述子の特定の属性のリストは、6-5ページの「パラメータ属性」を参照してください。

問合せの明示的記述ユーザーは、実行前に、問合せを明示的に記述することを選択できます。そのためには、OCIStmtExecute()のモードとして OCI_DESCRIBE_ONLYを指定します。OCIStmtExecute()をこのモードでコールすると、文は実行されませんが、選択リスト記述は戻されます。

注意 :パフォーマンスを向上させるには、アプリケーションではデフォルト・モードで文を実行し、実行に伴う暗黙的な記述を使用することを推奨します。

次の短い例では、このメカニズムを使用して、選択リストの明示的な記述を実行し、選択リストの列に関する情報を戻しています。この疑似コードでは、列情報(たとえばデータ型)を取り出す方法を示します。

/* initialize svchp, stmhp, errhp, rowoff, iters, snap_in, snap_out *//* set the execution mode to OCI_DESCRIBE_ONLY. Note that setting the mode to OCI_DEFAULT does an implicit describe of the statement in addition to executing the statement */

OCIParam *colhd; /* column handle */checkerr(errhp, OCIStmtExecute(svchp, stmhp, errhp, iters, rowoff,

snap_in, snap_out, OCI_DESCRIBE_ONLY);

/* Get the number of columns in the query */checkerr(errhp, OCIAttrGet(stmhp, OCI_HTYPE_STMT, &numcols, 0, OCI_ATTR_PARAM_COUNT, errh));

/* go through the column list and retrieve the data type of each column. We start from pos = 1 */for (i = 1; i <= numcols; i++)

Page 122: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

結果のフェッチ

SQL文の処理 4-11

{/* get parameter for column i */checkerr(errhp, OCIParamGet(stmhp, OCI_HTYPE_STMT, errh, &colhd, i));

/* get data-type of column i */checkerr(errhp, OCIAttrGet(colhd, OCI_DTYPE_PARAM,

&type[i-1], 0, OCI_ATTR_DATA_TYPE, errh));}

定義問合せ文は、データベースのデータをアプリケーションに戻します。問合せを処理するときには、データを検索する選択リストの各項目について、出力変数または出力変数の配列を定義する必要があります。定義ステップでは、戻される結果の格納場所と格納形式を決定する関連付けを行います。

たとえば、OCI文で次の文を処理するとします。

SELECT name, ssn FROM employeesWHERE empno = :empnum

この場合、通常は 2つの出力変数を定義する必要があります。1つは、name列から戻される値を受け取るための変数、もう 1つは ssn列から戻される値を受け取るための変数です。

定義操作のインプリメンテーションの詳細は、第 5章の「バインディングと定義」を参照してください。

結果のフェッチOCIアプリケーションで問合せを実行した場合、通常は、文の実行後に OCIStmtFetch()を使用して、結果をフェッチする必要があります。

フェッチされたデータは、定義操作で指定した出力変数に格納されます。

注意 : OCIStmtExecute()のコール前に SELECT文用の出力変数が定義されている場合は、itersパラメータにより指定した行数が直接定義済み出力バッファへフェッチされます。

関連項目 : これらの文により、5-13ページの「定義に使用するステップ」のコード例に対応付けられたデータがフェッチされます。詳細は、そのサンプル・コードを参照してください。

出力変数の定義の詳細は、5-12ページの「定義」を参照してください。

Page 123: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

結果のフェッチ

4-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

LOBデータのフェッチLOB列または属性が選択リストの一部である場合、問合せの結果として LOBロケータが戻されます。実際の LOB値は、フェッチでは戻されません。アプリケーションでは、LOBロケータに対してさらに操作を実行できます。

関連項目 : OCIでの LOBロケータ取扱いの詳細は、7-23ページの「LOBおよび FILE操作」を参照してください。

プリフェッチ・カウントの設定サーバーとの往復を最小限にし、アプリケーションのパフォーマンスを最大化するために、OCIでは問合せの実行時に結果行セットをプリフェッチできます。OCIのプログラマは、OCIAttrSet()関数を使用して、文ハンドルの OCI_ATTR_PREFETCH_ROWS属性、またはOCI_ATTR_PREFETCH_MEMORY属性を設定することにより、このプリフェッチをカスタマイズできます。

OCI_ATTR_PREFETCH_ROWSは、プリフェッチする行数を設定します。

OCI_ATTR_PREFETCH_MEMORYは、プリフェッチする行に割り当てられたメモリーを設定します。その後、アプリケーションではメモリーの容量が許すかぎり、行数をフェッチします。

これらの属性を設定すると、OCIでは、OCI_ATTR_PREFETCH_MEMORYで設定した最大メモリーを超えない限り、OCI_ATTR_PREFETCH_ROWSで設定した行数まで行をプリフェッチします。この場合、OCIは、OCI_ATTR_PREFETCH_MEMORYのバッファ・サイズに適応した行数を戻します。

デフォルトでは、プリフェッチはオンになっており、OCIでは、常に 1行余分にフェッチします。プリフェッチをオフにするには、OCI_ATTR_PREFETCH_ROWS属性およびOCI_ATTR_PREFETCH_MEMORY属性の両方に 0(ゼロ )を設定します。

注意 : LONG列が問合せの一部である場合、プリフェッチは無効になります。問合せによってデータではなく LOBロケータが戻されるので、LOB列を含む問合せはプリフェッチできます。

関連項目 : これらのハンドル属性の詳細は、B-15ページの「ステートメント・ハンドルの属性」を参照してください。

Page 124: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディングと定義 5-1

5バインディングと定義

第 2章の「OCIプログラミングの基本」では、COI アプリケーションでのバインディングと定義の概念を紹介しました。この章では、基本概念をもう一度取り上げ、OCIアプリケーションで使用できるさまざまな型のバインドと定義の詳細を説明します。 また、この章では、短いコード例をあげて、OCIアプリケーションで使用できるさまざまなバインドと定義の使用方法を説明します。

さらに、この章では、構造体配列の使用方法およびバインディング、定義、文字変換における諸問題についても説明します。

注意 : オブジェクト・アプリケーション用の新規 Oracle8データ型のバインディングおよび定義については、第 10章を参照してください。

この章は、次のトピックで構成されています。

■ バインディング

■ 拡張バインド操作

■ 定義

■ 拡張バインド操作

■ 構造体の配列

■ RETURNING句を使用した DML

■ NCHARおよび文字変換問題

■ PL/SQL REF CURSORおよびネステッド・テーブル

Page 125: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

5-2 Oarcle8コール・インタフェース・プログラマーズ・ガイド

バインディング大部分の DML文と一部の問合せ (WHERE句を使用した問合せなど )では、プログラムで、データを SQLまたは PL/SQL文の一部として Oracleに渡す必要があります。 これらのデータは、プログラムのコンパイル時にわかっている定数またはリテラル・データなどです。 たとえば、以下のような従業員をデータベースに追加する SQL文には、‘BESTRY’や 2365などのリテラルがいくつか含まれます。

INSERT INTO emp VALUES (2365, ‘BESTRY’, ‘PROGRAMMER’, 2000, 20)

このように、文をアプリケーション内にハード・コーディングすることは、非常に非効率的です。 データベースに新しい従業員を追加するたびに、文を変更してプログラムを再コンパイルする必要があります。 ユーザーが実行時に入力データを指定できるようにプログラムを書くと、プログラムにもっと柔軟性を持たせることができます。

入力データが実行時に指定される SQL文または PL/SQLブロックを準備する場合は、SQL文または PL/SQLブロックのプレースホルダによって、どの位置にデータが入力されるのかがマークされます。 たとえば、次の SQL文には、5つのプレースホルダが含まれています。プレースホルダは先頭にコロンが付き (たとえば :ename)、プログラムで入力データが供給される必要があることを示しています。

INSERT INTO emp VALUES (:empno, :ename, :job, :sal, :deptno)

入力変数のプレースホルダは、DELETE文、INSERT文、SELECT文、UPDATE文、PL/SQLブロックで、式またはリテラル値を使用できる位置であれば文中のどの位置でも使用できます。 PL/SQLでは、出力変数にもプレースホルダを使用できます。

注意 : プレースホルダを使用して表や列などの他の Oracleオブジェクトの名前は指定できません。

SQL文または PL/SQLブロックの各プレースホルダに対して、プログラム内の変数のアドレスをプレースホルダにバインドする OCIルーチンをコールする必要があります。 Oracleでは、文を実行すると、プログラムで入力変数またはバインド変数に入れたデータが読み取られ、それが SQL文でサーバーに渡されます。 バインド・ステップを実行する際、必ずしもバインド変数にデータが入っている必要はありません。 バインド・ステップでは、変数のアドレスおよびデータ型、長さを指定するだけです。

注意 : バインド時にプログラム変数にデータが含まれていない場合には、OCIStmtExecute()を使用して SQL文または PL/SQLブロックを実行する時点で、必ず有効なデータが含まれているようにする必要があります。

たとえば、次のような INSERT文があるとします。

INSERT INTO emp VALUES (:empno, :ename, :job, :sal, :deptno)

次のように変数を宣言したとします。

Page 126: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

バインディングと定義 5-3

text *ename, *jobsword empno, sal, deptno

バインド・ステップでは、プレースホルダ名とプログラム変数のアドレス間の関連付けを行います。 また、図 5–1に示すように、バインドでは、プログラム変数のデータ型と長さを指定します。 この例をインプリメントするコードは、5-5ページの「バインディングで使うステップ」にあります。

図 5–1 OCIBindByName() を使ってプレースホルダとプログラム変数を関連づける

バインド変数の値だけを変更した場合は、文を再実行するために再バインドする必要はありません。 バインドは参照による結合なので、バインド変数のアドレスおよびバインド・ハンドルが有効である限り、再バインドせずに、変数を参照する文を再実行できます。

注意 : インタフェース・レベルでは、すべてのバインド変数は少なくとも INであるとみなされるため、正しく初期化する必要があります(純 OUTバインド変数である場合は 0(ゼロ )になります)。

リリース 8.0では、名前付きデータ型である REFおよび LOB用の新しいデータ型が組み込まれています。新しいデータ型は、SQL文中でプレースホルダとしてバインドできます。

注意 :⦆記述子やロケータなど、ユーザーにサイズがわからない不明確なデータ型の場合は、記述子またはロケータ・ポインタのアドレスを渡す必要があります。 サイズ・パラメータ・セットに、適切なデータ構造のサイズを設定します (たとえば、sizeof(structure))。

名前付きバインドおよび定位置バインド前述の項の SQL文は、「名前付きバインド」の例です。 文の各プレースホルダに名前が関連付けられています (例 : ’ename’または ‘sal’)。 この文を準備し、プレースホルダをアプリケーションの値に関連付けるときは、OCIBindByName()コールの placeholderパラメータでプレースホルダの名前を渡し、プレースホルダの名前による関連付けを行います。

INSERT INTO emp

OCIBindByName ( )

(empno, ename, job, sal, deptno)

VALUES (:empno, :ename, :job, :sal, :deptno)

Address &empno ename job sal &deptno

Data Type integer string string integer integer

Length sizeof(empno) strlen(ename)+1 strlen(job)+1 sizeof(sal) sizeof(deptno)

Page 127: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

5-4 Oarcle8コール・インタフェース・プログラマーズ・ガイド

もう 1つの型のバインドは、定位置バインドです。 定位置バインドでは、プレースホルダは名前ではなく文中の位置によって参照されます。 このバインドでは、OCIBindByPos()コールを使用して、入力値とプレースホルダの位置との間の関連付けを行います。

前の項に示した例は、定位置バインドにも使用できます。

INSERT INTO emp VALUES (:empno, :ename, :job, :sal, :deptno)

5つのプレースホルダは、OCIBindByPos()をコールし、positionパラメータでプレースホルダの位置番号を渡すことによって、それぞれバインドされます。 たとえば、OCIBindByPos()をコールすることによって、:empnoプレースホルダは位置 1に、:enameは位置 2に、というようにバインドされます。

重複バインドの場合、1つのバインド・コールだけが必要です。 次の SQL文について考えてみます。この SQL文は、コミッションと給料の両方が指定の金額よりも大きい従業員をデータベースで問い合せます。

SELECT empno FROM emp WHERE sal > :some_value AND comm > :some_value

OCIアプリケーションでは、OCIBindByName()を 1回コールするだけで、:some_valueプレースホルダを名前によってバインドし、この文のバインドを完了できます。 この場合、2番目のプレースホルダは、最初のプレースホルダからのバインド情報を継承します。

OCI配列インタフェースOracleにデータを渡すには、様々な方法があります。 OCIStmtExecute()ルーチンを使用してSQL文を繰り返し実行し、反復のたびに異なる入力値を指定することもできます。 別の方法として、Oracle配列インタフェースを使用すると、単一の文と OCIStmtExecute()のコール 1回だけで、多数の値を入力できます。 その場合、配列を入力プレースホルダにバインドし、itersパラメータで制御して配列全体を同時に渡すことができます。

配列インタフェースを使用すると、大量のデータを更新したり挿入したりする必要がある場合に、Oracleとのやりとりを大幅に削減できます。 この削減により、通信量の多いクライアント /サーバー環境では、大きなパフォーマンスの向上につながります。 たとえば、データベースに 10行挿入するアプリケーションを考えてみます。 OCIStmtExecute()を 10回、それぞれ 1個の値を指定してコールすると、すべてのデータを挿入するにはネットワーク往復が10回必要です。 入力配列を使用すると、OCIStmtExecute()を 1回コールするだけで同じことができ、ネットワーク往復は 1回だけで済みます。

注意 : OCI配列インタフェースを使って挿入を行う際には、各挿入行が挿入されるごとに、データベース内の行トリガーが起動します。

Page 128: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

バインディングと定義 5-5

PL/SQLのプレースホルダのバインディングPL/SQLブロックの処理は、単一の SQL文の場合と同じようにそのブロックを文字列変数に入れて、任意の変数をバインドし、ブロックを含む文を実行して行います。

PL/SQLブロックのプレースホルダをプログラム変数にバインドする場合は、OCIBindByName()か OCIBindByPos()を使って基本バインドを行います。 OCIBindByName() か OCIBindByPos() を使うと、スカラーか配列のどちらかのホスト変数をバインドできます。

次の短い PL/SQLブロックには 2つのプレースホルダが含まれ、従業員番号と新規給与額に基づき、従業員の給与を更新するプロシージャへの INパラメータを表わします。

char plsql_statement[] = "BEGIN\ RAISE_SALARY(:emp_number, :new_sal);\ END;";

これらのプレースホルダは、SQL文のプレースホルダと同じ方法で入力変数にバインドできます。

PL/SQL文を処理するとき、出力変数もまたバインド・コールを使用してプログラム変数に関連付けられます。

たとえば、次のような PL/SQLブロックがあるとします。

BEGINSELECT ename, sal, comm INTO :emp_name,:salary,:commissionFROM empWHERE ename = :emp_number;

END;

OCIBindByName()を使用して、変数を :emp_nameおよび :salary、:commission出力プレースホルダにバインドし、入力プレースホルダ :emp_numberにも変数をバインドします。

7.x⦆アップグレードの注意 :⦆Oracle7 OCIでは、INバインド・バッファだけをアプリケーションで初期化すれば十分でした。 Oracle8では、バインド・コールでバッファ長を 0(ゼロ )に設定するか、または対応する標識に -1を設定して、純 OUTバッファの場合も含め、すべてのバッファを初期化する必要があります。

関連項目 : PL/SQLプレースホルダのバインディングに関する詳細は、10-3ページの「名前付きデータ型および REFバインドについての追加情報」を参照してください。

バインディングで使うステッププレースホルダをバインドするには、1つ以上のステップがあります。 単純なスカラー・バインドまたは配列バインドの場合は、プレースホルダとデータとの関連付けを指定するだけです。 これは、名前 (OCIBindByName())による OCIバインド、または定位置(OCIBindByPos())コールによる OCIバインドを使用して行います。

注意 : バインド型の違いについては、5-3ページの「名前付きバインドおよび定位置バインド」を参照してください。

Page 129: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

5-6 Oarcle8コール・インタフェース・プログラマーズ・ガイド

バインドが完了すると、SQL文の実行時には、入力データの位置や PL/SQL出力データを入れる位置が OCIライブラリに対して明らかになります。 5-2ページの「バインディング」で説明したとおり、プレースホルダにバインドする際に、プログラム入力データがプログラム変数内に存在する必要はありませんが、文を実行する際にはデータが存在しなければなりません。

次のコード例は、SQL文の 5つのプレースホルダそれぞれのハンドル割当てとバインドを示しています。

注意 : checkerr()機能によって、OCIアプリケーションからのリターン・コードが評価されます。 機能のコードは、2-24ページの「エラー処理」にリストされています。

.../* The SQL statement, associated with stmthp (the statement handle)by calling OCIStmtPrepare() */text *insert = (text *) "INSERT INTO emp(empno, ename, job, sal, deptno)\ VALUES (:empno, :ename, :job, :sal, :deptno)";...

/* Bind the placeholders in the SQL statement, one per bind handle. */checkerr(errhp, OCIBindByName(stmthp, &bnd1p, errhp, (text *) ":ENAME", strlen(":ENAME"), (ub1 *) ename, enamelen+1, STRING_TYPE, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))checkerr(errhp, OCIBindByName(stmthp, &bnd2p, errhp, (text *) ":JOB", strlen(":JOB"), (ub1 *) job, joblen+1, STRING_TYPE, (dvoid *) &job_ind, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))checkerr(errhp, OCIBindByName(stmthp, &bnd3p, errhp, (text *) ":SAL", strlen(":SAL"), (ub1 *) &sal, (sword) sizeof(sal), INT_TYPE, (dvoid *) &sal_ind, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))checkerr(errhp, OCIBindByName(stmthp, &bnd4p, errhp, (text *) ":DEPTNO", strlen(":DEPTNO"), (ub1 *) &deptno,(sword) sizeof(deptno), INT_TYPE, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))checkerr(errhp, OCIBindByName(stmthp, &bnd5p, errhp, (text *) ":EMPNO", strlen(":EMPNO"), (ub1 *) &empno, (sword) sizeof(empno), INT_TYPE, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0,OCI_DEFAULT))

PL/SQLの例OCIプログラム中の PL/SQLブロックで最もよく使用されるのは、おそらくストアド・プロシージャまたはストアド・ファンクションのコールです。 たとえば、データベース中にRAISE_SALARYというプロシージャが格納されており、これをOCIプログラムからコールするとします。 そのためには、そのプロシージャに対するコールを無名の PL/SQLブロックに埋め込み、OCIプログラムの PL/SQLブロックを処理します。

次に示すプログラムの一部分は、ストアド・プロシージャ・コールを OCIアプリケーションに埋め込む方法の例です。 簡潔にするために、ここではプログラムに関連する部分だけを示しています。

Page 130: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

バインディングと定義 5-7

このプログラムでは、これらのパラメータを受け取る raise_salaryというストアド・プロシージャへの入力として、従業員番号と新しい給与が渡されます。

raise_salary (employee_num IN, sal_increase IN, new_salary OUT);

このプロシージャでは、一定の従業員給与に一定額が上乗せされます。 増額された給与はストアド・プロシージャの OUT変数 new_salaryに復帰し、この値がプログラムに表示されます。

/* Define PL/SQL statement to be used in program. */text *give_raise = (text *) "BEGIN\ RAISE_SALARY(:emp_number,:sal_increase, :new_salary);\ end;";OCIBind *bnd1p = NULL; /* the first bind handle */OCIBind *bnd2p = NULL; /* the second bind handle */OCIBind *bnd3p = NULL; /* the third bind handle */

static void checkerr();sb4 status;

main(){ sword empno, raise, new_sal; dvoid *tmp; OCISession *usrhp = (OCISession *)NULL; .../* attach to database server, and perform necessary initializationsand authorizations */... /* allocate a statement handle */ checkerr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp, OCI_HTYPE_STMT, 100, (dvoid **) &tmp));

/* prepare the statement request, passing the PL/SQL text block as the statement to be prepared */checkerr(errhp, OCIStmtPrepare(stmthp, errhp, (text *) give_raise, (ub4) strlen(give_raise), OCI_NTV_SYNTAX, OCI_DEFAULT));

/* bind each of the placeholders to a program variable */ checkerr( errhp, OCIBindByName(stmthp, &bnd1p, errhp, (text *) ":emp_number", -1, (ub1 *) &empno, (sword) sizeof(empno), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT));

checkerr( errhp, OCIBindByName(stmthp, &bnd2p, errhp, (text *) ":sal_increase", -1, (ub1 *) &raise, (sword) sizeof(raise), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT));

Page 131: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

5-8 Oarcle8コール・インタフェース・プログラマーズ・ガイド

/* remember that PL/SQL OUT variable are bound, not defined */

checkerr( OCIBindByName(stmthp, &bnd3p, errhp, (text *) ":new_salary", -1, (ub1 *) &new_sal, (sword) sizeof(new_sal), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT));

/* prompt the user for input values */printf("Enter the employee number: ");scanf("%d", &empno); /* flush the input buffer */myfflush();

printf("Enter employee’s raise: ");scanf("%d", &raise); /* flush the input buffer */myfflush();

/* execute PL/SQL block */ checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT));

/* display the new salary, following the raise */printf("The new salary is %d\n", new_sal);}

このプログラムの出力例を次に示します。 実行前の従業員 7954番の給与は 2000です。

Enter the employee number: 7954Enter employee’s raise: 1000

新規の給与は 3000です。

拡張バインド前項では、単純なスカラー・バインドを実行する方法を例で示しました。 その例では、必要なバインド・コールは 1回だけでした。 場合によっては、特定のバインド・データ型または実行モードについて特定の属性を定義するために、追加のバインド・コールが必要です。 このような高度なバインド操作については、次の項で説明しています。

Oracle8には、ADT属性をマップする事前定義済みの Cデータ型もあります。 これらデータ型について (例 : OCIDate, OCINumber)は、第 10章を参照してください。

Page 132: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

拡張バインド操作

バインディングと定義 5-9

拡張バインド操作4-5ページの「バインディング」では、OCIBindByName()または OCIBindByPos()を使って、SQL文とプログラム変数のプレースホルダ間の関連付けを行うための基本バインド操作の方法について説明しました。

この項では、マルチステップ・バインドおよび名前付きデータ型バインド、REFのバインドなどの拡張バインド操作について説明します。

場合によっては、特定のバインド・データ型または特定の実行モードについて特定の属性を定義するために、追加のバインド・コールが必要です。

次からの項ではこの特別なケースについて説明します。バインドに関する情報については、5-11ページの表 5–1にまとめてあります。

静的配列バインド静的配列バインドの属性は、OCIの構造体の配列バインド・コール OCIBindArrayOfStruct()を使用して設定します。 このコールは、OCIBindByName()または OCIBindByPos()コールに従って作成します。

注意 : 静的配列バインドは、スカラー配列型または名前付きデータ型の列のバインドのことではなく、PL/SQL表のバインドまたは SQL(INSERTまたは UPDATE)での複数行操作のバインドのことを指します。

また、OCIBindArrayOfStruct()コールは、アプリケーションで、構造体の配列機能を使用する場合に必要なスキップ・パラメータを定義するのに使用します。

関連項目 : 構造体配列の使用方法に関する詳細は、5-16ページの「構造体の配列」の項を参照してください。

名前付きデータ型のバインド名前付きデータ型 (オブジェクト)のバインディングについては、10-2ページの「名前付きデータ型のバインド」を参照してください。

REFのバインディングREFのバインディングについては、10-3ページの「REFのバインディング」を参照してください。

LOBのバインディングLOBを操作する場合、実際の LOB値ではなく、LOBロケータがバインドされます。 LOB値は、LOBロケータを PL/SQL DBMS_LOBパッケージまたは OCI LOB関数に渡して読み書きされます。

Page 133: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

拡張バインド操作

5-10 Oarcle8コール・インタフェース・プログラマーズ・ガイド

単一のバインド・コール内で、単一のロケータをバインドすることも、 ロケータの配列をバインドすることもできます。 どちらのケースでも、アプリケーションは、ロケータそのものではなく、「LOBロケータのアドレス」を渡す必要があります。

たとえば、アプリケーションで、次のような SQL文を用意したとします。

INSERT INTO some_table VALUES (:one_lob)

この SQL文では、:one_lobが、1つの LOB列に対応するバインド変数です。このとき、次のような宣言をしたとします。

OCILobLocator * one_lob;

次のようなステップを使用して、プレースホルダをバインドし、文を実行します。

/* initialize single locator */one_lob = OCIDescriptorAlloc(...OCI_DTYPE_LOB...);.../* pass the address of the locator */OCIBindByName(...,(dvoid *) &one_lob,...);OCIStmtExecute(...,1,...) /* 1 is the iters parameter */

注意 : ここでは、例を簡潔にするために、ほとんどのパラメータを省略しています。

また、同一の SQL INSERT文を使用して、配列の挿入ができます。 このケースでは、アプリケーション内に次のコードが組み込まれている必要があります。

OCILobLocator * lob_array[10];...for (i=0; i<10, i++)lob_array[i] = OCIDescriptorAlloc(...OCI_DTYPE_LOB...); /* initialize array of locators */...OCIBindByName(...,(dvoid *) lob_array,...);OCIStmtExecute(...,10,...); /* 10 is the iters parameter */

記述子は、使用する前に OCIDescriptorAlloc()ルーチンによって割り当てる必要があることに注意してください。 ロケータの配列の場合は、OCIDescriptorAlloc()を使用して、各配列要素を初期化する必要があります。 BLOBおよび CLOB、NCLOBを割り当てる場合は、OCI_DTYPE_LOBを typeパラメータとして使用します。 BFILEを割り当てる場合は、OCI_DTYPE_FILEを使用します。

関連項目 : OCI LOB機能に関する詳細は、7-23ページの「LOBおよび FILE操作」を参照してください。

OCI_DATA_AT_EXECモードでのバインドOCIBindByName()または OCIBindByPos()コールの modeパラメータがOCI_DATA_AT_EXECに設定されているとき、アプリケーションで実行時にデータを提供す

Page 134: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

拡張バインド操作

バインディングと定義 5-11

るコールバック・メソッドを使用する場合は、追加の OCIBindDynamic()コールが必要です。 OCIBindDynamic()のコールは、提供されたデータまたはその一部を示すために、必要に応じてコールバック・ルーチンを設定します。

OCI_DATA_AT_EXECモードを選択した場合でも、コールバックのかわりに標準の OCIのピース単位ポーリング・メソッドを使用する場合は、OCIBindDynamic()コールは必要ありません。

RETURN句の変数をバインドするとき、アプリケーションでは、OCI_DATA_AT_EXECモードを使用し、コールバックを提供する必要があります。

関連項目 : ピース単位操作に関する詳細は、7-16ページの「ランタイム・データ割当てとピース単位操作」を参照してください。

Refカーソル変数のバインディングREFカーソルは、バインド・データ型の SQLT_RSETを使用して、文ハンドルにバインドされます。 5-25ページの「PL/SQL REF CURSORおよびネステッド・テーブル」を参照してください。

バインド情報のまとめ次の表は、バインドの型別に必要なバインド・コールをまとめたものです。 この表では、各タイプの (OCIBindByName()または OCIBindByPos()の dtyパラメータで渡す )バインドのデータ型と、そのバインドを使用するときの注意事項を一覧にしています。

表 5–1 バインド型の違いについて

バインドのタイプ バインドのデータ型 注意

スカラー 任意のスカラー・データ型

OCIBindByName()または OCIBindByPos()を使用して、単一のスカラーをバインドする。

スカラーの配列 任意のスカラー・データ型

OCIBindByName()または OCIBindByPos()を使用してスカラーの配列をバインドする。

名前付きデータ型 SQLT_NTY 2つのバインド・コールが必要。

■ OCIBindByName()または OCIBindByPos()

■ OCIBindObject()

REF SQLT_REF 2つのバインド・コールが必要。

■ OCIBindByName()または OCIBindByPos()

■ OCIBindObject()

LOB SQLT_BLOB

SQLT_CLOB

OCIDescriptorAlloc()を使用して LOBロケータを割り当て、次に、LOBデータ型の 1つを使用して、そのアドレス (OCILobLocator **)を OCIBindByName()または OCIBindByPos()とバインドする。

Page 135: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

定義

5-12 Oarcle8コール・インタフェース・プログラマーズ・ガイド

関連項目 : データ型およびデータ型コードに関する詳細は、第 3章の「データ型」を参照してください。

定義問合せ文は、データベースのデータをアプリケーションに戻します。 問合せを処理するときには、データを検索する選択リストの各項目について、出力変数または出力変数の配列を定義する必要があります。 定義ステップでは、戻される結果の格納場所と格納形式を決定する関連付けを行います。

たとえば、OCI文で次の文を処理するとします。

SELECT name, ssn FROM employees WHERE empno = :empnum

この場合、通常は 2つの出力変数を定義する必要があります。1つは、name列から戻される値を受け取るための変数、もう 1つは ssn列から戻される値を受け取るための変数です。

定義操作のインプリメントについては、第 5章の「バインディングと定義」を参照してください。

注意 : name列の値だけを検索する場合は、ssn用の出力変数を定義する必要はありません。

処理される SELECT文が、問合せに対して 1つ以上の値を戻す場合は、出力変数は、スカラー値のかわりに配列を定義することができます。

注意 : アプリケーションによって、定義ステップが実行前になったり実行後になったりします。 アプリケーションをコーディングする時点で選択リスト項目のデータ型がわかっている場合には、文を実行する前に定義を行うことができます。 これに対し、アプリケーションで動的 SQL文を処理する場合があります。実行時にユーザーが入力する文や、次のように、明確に定義された選択リストがない文を処理する場合です。

構造体の配列または静的配列

可変 2つのバインド・コールが必要。

■ OCIBindByName()または OCIBindByPos()

■ OCIBindArrayOfStruct()

ピース単位挿入 可変 OCIBindByName()または OCIBindByPos()が必要。 また、ピース単位コールバックを登録するために、アプリケーションでOCIBindDynamic()コールが必要な場合もある。

REFカーソル変数 SQLT_RSET 文ハンドル、OCIStmtを割り当ててから、SQLT_RSETデータ型を使用して、その文ハンドルのアドレス (OCIStmt **)をバインドする。

表 5–1 バインド型の違いについて (続き )

バインドのタイプ バインドのデータ型 注意

Page 136: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

定義

バインディングと定義 5-13

SELECT * FROM employees

このような場合、アプリケーションでは出力変数を定義する前に文を実行し、記述情報を検索する必要があります。 詳細は、4-8ページの「選択リスト項目の記述」を参照してください。

OCIでは、クライアント側で定義コールをローカルに処理します。 定義ステップでは、結果を格納するバッファの位置を指示し、さらに、データがアプリケーションに戻されるときに必要に応じて行うデータ変換の種類を決定します。

OCIDefineByPos()コールの dtyパラメータでは、出力変数のデータ型を指定します。 OCIでは、データを出力変数にフェッチするときに広範囲のデータ変換を行うことができます。 たとえば、Oracle DATE形式の内部データは、出力時に、自動的に文字列データ型に変換できます。

関連項目 : データ型および変換についての詳細は、第 3章の「データ型」を参照してください。

定義に使用するステップ出力変数を定義するには、1つ以上のステップを実行します。 基本的な定義は、定位置コールの OCIDefineByPos()により、OCI定義を使用して完了します。 このステップでは、選択リスト項目と出力変数との間の関連付けを行います。 特定のデータ型またはフェッチ・モードには追加の定義コールが必要です。

定義ステップが完了すると、OCIライブラリでは、データベースからデータをフェッチした後にそのデータを入れる位置が明らかになります。

注意 : SQL文の準備や実行を再びやり直すことなく、定義コールを再度行って再定義できます。

次のコード例では、実行と記述の後にスカラー出力変数を定義しています。

/* The following statement was prepared, and associated with statementhandle stmthp1.

SELECT dname FROM dept WHERE deptno = :dept_input

The input placeholder was bound earlier, and the data comes from theuser input below */

printf("Enter employee dept: "); scanf("%d", &deptno); myfflush();

/* Execute the statement. If OCIStmtExecute() returns OCI_NO_DATA, meaning that no data matches the query, then the department number is invalid. */

if ((status = OCIStmtExecute(svchp, stmthp1, errhp, 1, 0, 0, 0, OCI_DEFAULT))

Page 137: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

定義

5-14 Oarcle8コール・インタフェース・プログラマーズ・ガイド

&& (status != OCI_NO_DATA)) { checkerr(errhp, status); do_exit(EXIT_FAILURE); } if (status == OCI_NO_DATA) { printf("The dept you entered doesn’t exist.\n");

return 0; }/* The next two statements describe the select-list item, dept, and

return its length */checkerr(errhp, OCIParamGet(stmthp1, errhp, &parmdp, (ub4) 1));checkerr(errhp, OCIAttrGet((dvoid*) parmdp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &deptlen, (ub4 *) 0, (ub4) OCI_ATTR_DATA_SIZE, (OCIError *) errhp ));

/* Use the retrieved length of dept to allocate an output buffer, andthen define the output variable. If the define call returns an error,exit the application */dept = (text *) malloc((int) deptlen + 1);

if (status = OCIDefineByPos(stmthp1, &defnp, errhp, 1, (ub1 *) dept, deptlen+1, SQLT_STRING, (dvoid *) 0, (ub2 *) 0, OCI_DEFAULT)) { checkerr(errhp, status); do_exit(EXIT_FAILURE); }記述ステップの説明は、4-8ページの「選択リスト項目の記述」を参照してください。

拡張定義場合によっては、定義ステップで OCIDefineByPos()のコールだけでなく、他のコールも必要です。 配列のフェッチ (OCIDefineArrayOfStruct())または 名前付きデータ型のフェッチ(OCIDefineObject())の属性を定義する追加コールがあります。 たとえば、1つの名前付きデータ型列を指定して複数の行をフェッチするには、列に対して 3つのコールすべてを呼び出す必要がありますが、スカラー列の複数の行をフェッチするには、OCIDefineArrayOfStruct()と OCIDefineByPos()で済みます。

より洗練された定義操作は、5-15ページの「拡張バインド操作」で説明します。

また、Oracle8には、オブジェクト型の属性をマップするための 事前定義済みデータ型が用意されています。 これらデータ型について (例 : OCIDate、OCINumber)は、第 10章を参照してください。

Page 138: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

拡張バインド操作

バインディングと定義 5-15

拡張バインド操作4-11ページの「定義」では、アプリケーションで SQL選択リスト項目と出力バッファ間を関連付けるための基本バインド操作の方法について説明しました。

この項では、マルチステップ定義および名前付きデータ型定義、REF定義などの拡張定義操作について説明します。

場合によっては、定義ステップで OCIDefineByPos()のコールだけでなく、他のコールも必要です。 配列のフェッチ (OCIDefineArrayOfStruct())または 名前付きデータ型のフェッチ(OCIDefineObject())の属性を定義する追加コールがあります。 たとえば、1つの名前付きデータ型列を指定して複数の行をフェッチするには、列に対して 3つのコールすべてを呼び出す必要がありますが、スカラー列の複数の行をフェッチするには、OCIDefineArrayOfStruct()と OCIDefineByPos()だけで済みます。

次の項では、さまざまなタイプの定義に関する特定の情報を説明します。

名前付きデータ型出力変数の定義名前付きデータ型(オブジェクト)出力変数については、10-4ページの「名前付きデータ型出力変数の定義」を参照してください。

REF出力変数の定義REF出力変数の定義については、10-4ページの「REF出力変数の定義」を参照してください。

LOB出力変数の定義LOBを使用する場合、バッファ・ポインタは、OCIDescriptorAlloc()コールで割り当てられた OCILobLocator型のロケータでなければなりません。 LOB列には、LOBの値ではなく、常に LOBロケータが戻ります。 LOB値は、フェッチしたロケータに対して OCI LOBコールを使用するとフェッチできます。

PL/SQL出力変数の定義PL/SQLブロック内の SQL SELECT文の選択リスト項目については、出力変数を定義するのに定義コールは使用しません。 かわりに、OCIバインド・コールを使用する必要があります。

関連項目 : PL/SQL出力変数の定義に関する詳細は、10-4ページの「名前付きデータ型と REF定義、および PL/SQL OUTバインドの追加情報」を参照してください。

ピース単位フェッチの定義ピース単位フェッチを実行する場合は、最初に OCIDefineByPos()をコールする必要があります。 アプリケーションで、データをフェッチするときの標準のポーリング・メカニズムではなくコールバックを使用する場合は、追加の OCIDefineDynamic()コールが必要です。

Page 139: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

構造体の配列

5-16 Oarcle8コール・インタフェース・プログラマーズ・ガイド

関連項目 : 詳細は、7-16ページの「ランタイム・データ割当てとピース単位操作」を参照してください。

構造体配列の定義構造体の配列を使用する場合は、最初に OCIDefineByPos()をコールする必要があります。 構造体の配列操作に必要なスキップ・パラメータなどの追加パラメータを設定するには、追加の OCIDefineArrayOfStruct()コールが必要です。

関連項目 : 詳細は、5-16ページの「構造体の配列」を参照してください。

構造体の配列Oracle8 OCIの「構造体の配列」の機能性は、複数行と複数列操作の処理を簡潔化できることです。OCIのプログラミングでは、関連したスカラー・データ項目の構造体を作成し、データベースの値を構造体の配列へフェッチしたり、これらの構造体の配列の値をデータベースに挿入したりできます。

たとえば、あるアプリケーションで NAMEおよび AGE、SALARYという名前の 3つの列から、複数列のデータをフェッチする必要があるとします。 OCIアプリケーションでは、個別のフィールド(それぞれが、データベース表で 1行に含まれている NAMEおよび AGE、SALARYのデータを保持する)を含む構造体の定義を組み込むことができます。 アプリケーションでは、次に、これらの構造体の配列へデータをフェッチします。

構造体の配列を使用して、複数行、複数列の操作を実行するには、その操作に関連する各列を、構造体の中の 1フィールドと関連付けておく必要があります。 この関連付けは、OCIDefineArrayOfStruct()コールと OCIBindArrayOfStruct()コールの一部で、これにより、フェッチされたデータの格納場所や、挿入済みまたは更新済みのデータの位置を指定します。

図 5–2は、この処理をグラフィック形式で示しています。 この図では、アプリケーションがデータベース行からさまざまなフィールドをフェッチし、構造体の配列の中の 1つの構造体に挿入しています。 フェッチされた各列は、構造体内のフィールドの 1つと対応しています。

Page 140: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

構造体の配列

バインディングと定義 5-17

図 5–2 構造体の配列へのデータをフェッチする

スキップ・パラメータ構造体の配列間で列データを分割すると、それは連続した列データではなくなります。 単一の構造体の配列は、いくつかのインターリーブされたスカラー配列で構成されているかのようにデータを格納します。 このため、開発者はバインディングまたは定義を行う各フィールドに「スキップ・パラメータ」を指定する必要があります。 スキップ・パラメータでは、構造体の配列の中にある同じフィールドまでスキップするために、必要なバイト数を指定します。 通常は、1つの構造体のバイト数と等しい値です。

次の図では、スキップ・パラメータをどのように決定すればよいかを示しています。 このケースでは、スキップ・パラメータは、フィールド 1およびフィールド 2、フィールド 3のサイズの合計です。それぞれのフィールドのサイズは、8バイトです。 このサイズは、1つの構造体のサイズと同じです。

Page 141: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

構造体の配列

5-18 Oarcle8コール・インタフェース・プログラマーズ・ガイド

図 5–3 スキップ・パラメータの決定

システムによっては、スキップ・パラメータを sizeof(struct)ではなく 、sizeof(one array element)にする必要がある場合もあります。 これは、コンパイラによっては、構造体に埋込みを挿入する場合があるからです。 たとえば、ub4と ub1という 2つのフィールドで構成された C構造体の配列のケースを考えてみます。

struct demo { ub4 field1; ub1 field2;};struct demo demo_array[MAXSIZE];

コンパイラによっては、この配列内の次の構造体を開始する ub4の位置を正しくするために、ub1の後に 3バイトの埋込みを挿入することがあります。 このようなコンパイラでは、次の文を使用すると、誤った値が戻される可能性があります。

skip_parameter = sizeof(struct demo);

この文を使用した場合、スキップ・パラメータとして正しい値である 8バイトを得るシステムもありますが、 skip_parameterが 5バイトを得るシステムもあります。 この場合は、次の文を使用すると、スキップ・パラメータの正しい値を得られます。

skip_parameter = sizeof(demo_array[0]);

標準配列のスキップ・パラメータ構造体の配列を処理する機能は、プログラム変数の配列をバインドおよび定義する機能を拡張した機能です。 プログラマは、(構造体の配列に対立するものとして)標準の配列も使用できます。 標準の配列操作を指定する場合、関連したスキップ・パラメータは、その配列のデータ型のサイズと等しくなります。 たとえば、配列を次のように宣言したとします。

text emp_names[4][20]

バインドまたは定義操作のスキップ・パラメータは 20になります。配列の各データ要素は、このため構造体の一部としてでなく別個の単位として認識されます。

Page 142: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

RETURNING句を使用した DML

バインディングと定義 5-19

構造体の配列で使用される OCIコール構造体配列が関係する操作を行う際には、 OCIBindArrayOfStruct()(入力変数に対する構造体配列のフィールドをバインディング )および OCIDefineArrayOfStruct()(出力変数に対する構造体配列を定義 )の 2つの OCIコールを必ず使います。

注意 : 構造体の配列をバインドまたは定義する際は、複数のコールが必要です。 OCIBindByName()または OCIBindByPos() へのコールは、OCIBindArrayOfStruct()へのコールに先行し、OCIDefineByPos()へのコールは OCIDefineArrayOfStruct()に先行する必要があります。

関連項目 : 構文およびパラメータ記述については、 第 13章の OCIBindArrayOfStruct()および OCIDefineArrayOfStruct()の説明を参照してください。

構造体の配列と標識変数構造体の配列をインプリメントすることによって、標識変数とリターン・コードの使用が可能になります。 OCIアプリケーションの開発者は、フェッチまたは挿入、更新された情報の配列に対応して、列レベルの標識変数とリターン・コードのパラレル配列を宣言できます。 これらの配列では、OCIBindArrayOfStruct()または OCIDefineArrayOfStruct()コールで指定する独自のスキップ・パラメータを持つことができます。

プログラム値および標識変数の構造体の配列は、多数の方法で設定できます。 たとえば、データベースの 3列から、構造体の配列の 3フィールドへデータをフェッチするアプリケーションを考えてみます。 この場合、3フィールドに対応する標識変数の構造体の配列を設定できます。それぞれの配列は、データベースからフェッチした列の中の 1列に対する列レベルの標識変数です。

注意 : 標識構造体のフィールドと選択リスト項目の数を 1対 1に関連付ける必要はありません。

関連項目 : 標識変数に関する詳細は、2-28ページの「標識変数」を参照してください。

RETURNING句を使用した DMLOCIでは、SQL INSERT文および UPDATE文、DELETE文での RETURNING句の使用をサポートします。 この項では、RETURNING句を使用して DML文を正しく実行するために、OCIアプリケーションが従う必要があるルールについて、概要を説明します。

注意 : INSERT文または UPDATE文、DELETE文での RETURNING句の使用の詳細は、『Oracle8 Serve SQLリファレンス』にあるこれらのコマンドの説明を参照してください。

完全なコード例は、D-25ページの「例 3、RETURNING句を使う DML」を参照してください。

Page 143: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

RETURNING句を使用した DML

5-20 Oarcle8コール・インタフェース・プログラマーズ・ガイド

RETURNING句を使用した DMLの使用方法DML文で RETURNING句を使用することにより、2つの SQL文を本質的に 1つに結合でき、サーバーの往復をできるだけ減らすことができます。 これは、追加の句を従来のUPDATEおよび INSERT、DELETE文に追加して行います。 追加の句では、問合せを DML文に効果的に追加します。

OCIでは、OUTバインド変数を通して値がアプリケーションに戻されます。 この変数をバインドするルールについては、次の項で説明しています。 次の例では、バインド変数の前にコロンが付いています (たとえば :out1)。 これらの例では、 col1および col2、col3の 3つの列を含む table1という表があると仮定しています。

たとえば、次の文では、新しい値をデータベースに挿入して、影響を受ける行の列値をデータベースから取り出します。これにより、挿入された行をアプリケーションで操作できます。

INSERT INTO table1 VALUES (:1, :2, :3,) RETURNING col1, col2, col3 INTO :out1, :out2, :out3

次の例では、UPDATE文を使用しています。 この文は、col1の値がある範囲内にあるすべての列の値を更新し、影響を受けた行をアプリケーションへ戻します。これにより、アプリケーションは、どの行が変更されたかを判別できます。

UPDATE table1 SET col1 = col1 + :1, col2 = :2, col3 = :3 WHERE col1 >= :low AND col1 <= :high RETURNING col1, col2, col3 INTO :out1, :out2, :out3

次の DELETE文では、col1の値がある範囲内にある行を削除し、それらの行からデータを戻します。これにより、アプリケーションではそのデータをチェックできます。

DELETE FROM table1 WHERE col1 >= :low AND col2 <= :high RETURNING col1, col2, col3 INTO :out1, :out2, :out3

ここで説明した UPDATE文と DELETE文の例は、文が表内の複数行に影響を与える可能性があることを示しています。 さらに、1つの DML文は、1つの OCIExecute()文の中で複数回数実行できます。 このように、複数の値が戻ってくる可能性があるため、OCIアプリケーションでは、実行時にどれだけのデータが戻ってくるのかを判断できない場合があります。 結果として、RETURNING...INTOプレースホルダに対応する変数は、OCI_DATA_AT_EXECモードでバインドする必要があります。 その他の要件として、アプリケーションでは、それ自体の動的なデータ処理コールバックを (OCI_DATA_AT_EXECポーリング・メカニズムを使用するのではなく )定義する必要があります。

注意 : アプリケーションが、RETURNING句で 1つの値しか戻らないことを確認できる場合でも、OCI_DATA_AT_EXECモードで、コールバックを使用してバインドする必要があります。

Page 144: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

RETURNING句を使用した DML

バインディングと定義 5-21

RETURNING句は、LOBを操作するときに特に役立ちます。 通常、アプリケーションでは、空の LOBロケータをデータベースに挿入し、再度選択し直して操作を行います。 RETURNING句を使用すると、アプリケーションは、これら 2つのステップを 1つの文に結合できます。

INSERT INTO some_table VALUES (:in_locator)RETURNING lob_columnINTO :out_locator

RETURNING...INTO変数のバインディング前項で説明したように、OCIアプリケーションは、RETURNING句のプレースホルダを、単なる OUTバインド変数として使用します。 アプリケーションでは、これらのバインド変数を操作するとき、次のルールに従う必要があります。

1. 各プレースホルダに対する OCIBindDynamic()のコールの後に、OCIBindByName()または OCIBindByPos()を使用して、OCI_DATA_AT_EXECモードで RETURNING句のプレースホルダをバインドする。

注意 : OCIでは、RETURNING句のバインドのコールバック・メカニズムだけをサポートします。 ポーリング・メカニズムはサポートされていません。

2. RETURNING句のプレースホルダをバインドする場合、OCIBindDynamic()コールのocbfpパラメータとして、有効な OUTバインド関数を供給する。 この関数では、戻されたデータを保持するための記憶域を提供しなければなりません。

3. OCIBindDynamic()コールの icbfp パラメータで、コールすると NULL値を戻す"dummy"機能を提供する。

4. OCIBindDynamic()の piecepパラメータを、OCI_ONE_PIECEに設定する。

5. RETURNING句を使用した DML文では、重複バインドは使用できない(つまり、DMLセクションのバインド変数と、その文の RETURNINGセクションの間には、重複バインドはありません)。

エラー処理OCIBindDynamic()に提供された OUTバインド関数を、エラーのイベントで、文の結果の一部を受け取るために、準備する必要があります。 たとえば、10回実行される DML文をアプリケーションで発行し、エラーが 5回目の実行中に発生した場合、サーバーは、1回目から4回目までのデータを戻します。コールバック関数は、最初の 4つの文のデータ受け取るためにデータをコールします。

RETURNING REF...INTO句を使用した DMLRETURNING句は、データベースで挿入または更新されたオブジェクトに、REFを戻すためにも使用します。 次の SQL文で、その方法を示します。

Page 145: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

RETURNING句を使用した DML

5-22 Oarcle8コール・インタフェース・プログラマーズ・ガイド

UPDATE EXTADDR E SET E.ZIP = ’12345’, E.STATE=’AZ’ WHERE E.STATE = ’CA’ AND E.ZIP=’95117’ RETURNING REF(E), ZIP INTO :addref, :zip

この文では、オブジェクト表内のオブジェクトの属性をいくつか更新し、RETURNING句でオブジェクトに (スカラー ZIPコードとともに )REFを戻します。

OCIアプリケーションで REF出力変数をバインドするには、次の 3つのステップが必要です。

1. 最初のバインド情報を、OCIBindByName()を使用して設定する。

2. REF(TDOを含む )に対する追加のバインド情報は、OCIBindObject()を使用して設定する。

3. OCIBindDynamic()をコールする。

次のサンプル・コードでは、上記の例で必要なバインドを実行する関数を示します。

sword bind_output(stmthp, bndhp, errhp) OCIStmt *stmthp; OCIBind *bndhp[]; OCIError *errhp; { ub4 i;

/* get TDO for BindObject call */ if (OCITypeByName(envhp, errhp, svchp, (CONST text *) 0, (ub4) 0, (CONST text *) "ADDRESS_OBJECT", (ub4) strlen((CONST char *) "ADDRESS_OBJECT"), (CONST text *) 0, (ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, &addrtdo)) { return OCI_ERROR; }

/* initial bind call for both variables */ if (OCIBindByName(stmthp, &bndhp[2], errhp, (text *) ":addref", (sb4) strlen((char *) ":addref"), (dvoid *) 0, (sb4) sizeof(OCIRef *), SQLT_REF, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DATA_AT_EXEC) || OCIBindByName(stmthp, &bndhp[3], errhp, (text *) ":zip", (sb4) strlen((char *) ":zip"), (dvoid *) 0, (sb4) MAXZIPLEN, SQLT_CHR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DATA_AT_EXEC)) { return OCI_ERROR;

Page 146: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

NCHARおよび文字変換問題

バインディングと定義 5-23

}

/* object bind for REF variable */ if (OCIBindObject(bndhp[2], errhp, (OCIType *) addrtdo, (dvoid **) &addrref[0], (ub4 *) 0, (dvoid **) 0, (ub4 *) 0)) { return OCI_ERROR; }

for (i = 0; i < MAXCOLS; i++) pos[i] = i;

/* dynamic binds for both RETURNING variables */ if (OCIBindDynamic(bndhp[2], errhp, (dvoid *) &pos[0], cbf_no_data, (dvoid *) &pos[0], cbf_get_data) || OCIBindDynamic(bndhp[3], errhp, (dvoid *) &pos[1], cbf_no_data, (dvoid *) &pos[1], cbf_get_data)) { return OCI_ERROR; } return OCI_SUCCESS; }

コールバックに関するその他の注意コールバック関数がコールされるとき、バインド・ハンドルのOCI_ATTR_ROWS_RETURNED属性により、アプリケーションでは、ある特定の反復処理で戻される行数がわかります。 したがって、コールバックが、ある特定の反復処理で初めてコールされるとき (つまり索引 =0)、ユーザーは、そのバインド変数で戻されるすべての行のために、空白を割り当てることができます。 コールバックが引き続き同一の反復処理内でコールされるときは (つまり索引 >0)、ユーザーは、データを取り出すためには、割り当てた空白の範囲内で正確なメモリーへのバッファ・ポインタを増やすことしかできません。

NCHARおよび文字変換問題この項では、クライアントとサーバー間での、NCHARデータおよび文字変換を含む問題について説明します。

NCHAR問題Oracle8では、データベースの NCHARデータをサポートします。Oracle8 OCIで は、NCHARデータのバインドと定義をサポートします。 文字データを含むデータベースの列がNCHAR列として定義される場合、その列を含むバインドまたは定義では、キャラクタ・セット仕様の処理について特に考慮が必要です。

Page 147: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

NCHARおよび文字変換問題

5-24 Oarcle8コール・インタフェース・プログラマーズ・ガイド

クライアントとサーバーのキャラクタ・セットの幅が異なる場合、および、クライアントとサーバー間で適切に文字変換を行うために、考慮が必要です。 異なるキャラクタ・セット間でデータを変換する間に、データ・サイズが、4倍に増加したり 4分の 1に縮小する場合があります。 そのため、データを保持するために提供されるバッファが、確実に十分なサイズであるように注意する必要があります。

場合によっては、アプリケーションで、NCHARデータをバイト数(通常の場合)ではなく文字数で処理する方が簡単です。

各 OCIバインドおよび定義ハンドルには、"フォーム " (OCI_ATTR_CHRSETFORM)および"文字セット ID" (OCI_ATTR_CHRSETID)属性が関連付けられています。アプリケーションでは、バインド /定義バッファのキャラクタ・セット IDとフォームを指定するために、OCIAttrSet()コールを使用してこれらの属性を設定できます。

form属性に指定できる値は 2つあります。

■ SQLCS_IMPLICIT - データベース・キャラクタ・セット ID

■ SQLCS_NCHAR - NCHARキャラクタ・セット ID

デフォルト値は SQLCS_IMPLICITです。

キャラクタ・セット IDが指定されていない場合は、formの値に応じて、データベースのデフォルト値、またはクライアントの NCHARキャラクタ・セット IDが使用されます。 この値は、NLS_LANGまたは NLS_NCHAR環境変数で指定された値です。

何も指定されていない場合は、クライアントのデフォルトのデータベース・キャラクタ・セット IDが使用されます。

注意 : クライアント側バインド・バッファのキャラクタ・セット IDやフォームにどの値が割り当てられても、サーバのデータベース /NCHARキャラクタ・セット IDおよびフォームにしたがって、データが変換されデータベースに挿入されます。

関連項目 : NCHARデータの詳細は、『Oracle8 Serverリファレンス・マニュアル』を参照してください。

OCI_ATTR_MAXDATA_SIZE属性すべてのバインド・ハンドルは、OCI_ATTR_MAXDATA_SIZE属性を持っています。 この属性で、キャラクタ・セットの必要な変換を行った後、クライアント側バインド・データを格納するためにサーバーに割り当てるバイト数を指定します。

注意 : データがサーバーに送られる際に行われるキャラクタ・セットの変換により、データ拡張またはデータ縮小される場合があります。したがって、クライアントでのデータ・サイズがサーバーでのデータ・サイズと同一にならない場合があります。

通常、アプリケーションでは、使用方法に応じて、OCI_ATTR_MAXDATA_SIZEに、列の最大サイズ、または PL/SQL変数のサイズを設定します。 Oracleでは、OCI_ATTR_MAXDATA_SIZEの値が変換後のデータを格納するのに十分でない場合、エラーが発生します。

Page 148: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

PL/SQL REF CURSORおよびネステッド・テーブル

バインディングと定義 5-25

文字カウント属性バインドおよび定義ハンドルには、関連する文字カウント属性があります。 アプリケーションでは、データをバイト数ではなく文字数で操作するために、この属性を使用します。 この属性に 0(ゼロ )以外の値が設定された場合、すべての計算はバイトではなく文字数で行われ、サイズの制約もバイトではなく文字数で行われます。

この属性は、バインド・ハンドルの OCI_ATTR_MAXDATA_SIZE属性に加えて設定できます。 たとえば、OCI_ATTR_MAXDATA_SIZEに 100が設定され、OCI_ATTR_CHAR_COUNTに 0(ゼロ )が設定された場合、サーバーでのデータの変換後に可能な最大サイズは 100バイトです。 ただし、OCI_ATTR_MAXDATA_SIZEに 100が設定され、OCI_ATTR_CHAR_COUNTに 0(ゼロ )以外の値が設定された場合、そして、キャラクタ・セットに 2バイトまたは 2文字がある場合は、割当て可能な最大サイズは 200バイトです (2バイト /文字 × 100文字 )。

注意 : この属性は、固定幅のキャラクタ・セット IDに対してだけ有効です。 可変幅のキャラクタ・セット IDについては、これらの属性値は文字数ではなく、常にバイト数として処理されます。

バインドについては、バインドされたデータを格納するために、アプリケーションでサーバーに確保する文字数を、OCI_ATTR_CHAR_COUNTで設定します。 この属性値は、OCI_ATTR_MAXDATA_SIZE属性の値を上書きします。 VARCHAR2など値の一部に長さを示す接頭辞を持つデータ型については、長さを示す接頭辞の部分が、バイト数ではなく文字数と見なされます。 このような場合、標識の長さとリターン・コードも文字数になります。

注意 : OCI_ATTR_CHAR_COUNT属性の値に関係なく、バインド・コールまたは定義コールで指定されたバッファ長は、常にバイト数による長さと見なされます。 また、この場合は、ユーザーが送ったり受け取る実際の長さも文字数になります。

定義については、OCI_ATTR_CHAR_COUNT属性で、クライアント・アプリケーションで受け取るデータの最大文字数を指定します。 この指定は、OCIDefineByPos()コールで指定される maxlengthパラメータを上書きします。

PL/SQL REF CURSORおよびネステッド・テーブルOCIには、PL/SQL REF CURSORおよびネストした表を、バインドおよび定義する機能があります。 アプリケーションでは、これらの型の変数をハンドルおよび定義するために、文ハンドルを使用できます。 次の例で、この PL/SQLブロックを考えてみます。

static const text *plsql_block = (text *) "begin \ OPEN :cursor1 FOR SELECT empno, ename, job, mgr, sal, deptno \ FROM emp_rc WHERE job=:job ORDER BY empno; \ OPEN :cursor2 FOR SELECT * FROM dept_rc ORDER BY deptno; \ end;";アプリケーションは、OCIHandleAlloc()をコールして、バインドのための文ハンドルを割り当てます。そして、次のコード例の中で、:cursor1が stm2pにバインドされるように、

Page 149: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

PL/SQL REF CURSORおよびネステッド・テーブル

5-26 Oarcle8コール・インタフェース・プログラマーズ・ガイド

プレースホルダ :cursor1を文ハンドルにバインドします。 ハンドルを割り当てるコードは、この例に含まれていないことに注意してください。

err = OCIStmtPrepare (stm1p, errhp, (text *) nst_tab, strlen(nst_tab), OCI_NTV_SYNTAX, OCI_DEFAULT);...err = OCIBindByName (stm1p, (OCIBind **) bndp, errhp, (text *)":cursor1", (sb4)strlen((char *)":cursor1"), (dvoid *)&stm2p, (sb4) 0, SQLT_RSET, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT);

このコードでは、stm1pは PL/SQLブロックの文ハンドルです。一方、stm2pは、後のデータ検索のための REF CURSORとしてバインドされる文ハンドルです。 SQLT_RSETの値は、dtyパラメータに渡されます。

別の例として、次のコード例を考えてみます。

static const text *nst_tab = (text *) "SELECT ename, CURSOR(SELECT dname, loc FROM dept_rc) \ FROM emp_rc WHERE ename = ’LOCKE・;

この場合、2番目の位置がネストした表で、次のように、OCIアプリケーションで文ハンドルとして定義できます。 ハンドルを割り当てるコードは、この例に含まれていないことに注意してください。

err = OCIStmtPrepare (stm1p, errhp, (text *) nst_tab, strlen(nst_tab), OCI_NTV_SYNTAX, OCI_DEFAULT);...err = OCIDefineByPos (stm1p, (OCIDefine **) dfn2p, errhp, (ub4)2, (dvoid *)&stm2p, (sb4)0, SQLT_RSET, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT);

実行後、行を stm2pにフェッチすると、有効な文ハンドルになります。

注意 : 複数の REFカーソルを取り出した場合は、いつ stm2pにフェッチするかに注意する必要があります。 最初の REFカーソルをフェッチすると、そのデータを取り出すためにフェッチを実行できます。 ただし、2番目の REFカーソルを stm2pにフェッチすると、最初の REFカーソルからのデータにはアクセスできなくなります。

Page 150: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

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

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

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

この章は、次のトピックで構成されています。

■ 概要

■ OCIDescribeAny()の使用

■ 例

Page 151: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

概要

6-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

概要この章では、スキーマ・ オブジェクトを記述するために、OCIDescribeAny()関数の使用方法を説明します。 選択リスト項目の説明についての詳細は、4-8ページの「選択リスト項目の記述」を参照してください。

OCIDescribeAny()コールとそのパラメータについての詳細は、13-55ページの機能説明を参照してください。

OCIDescribeAny()の使用OCIDescribeAny()関数を使用して、次のスキーマ・オブジェクトのいずれか 1つの明示的な記述を実行できます。

■ 表とビュー

■ シノニム

■ プロシージャ

■ 関数

■ パッケージ

■ 順序

■ コレクション

■ 型

他のスキーマ要素(プロシージャ /関数の引数、および列、型属性、型メソッド)に関する情報は、上記のスキーマ・オブジェクトの 1つの記述を通して得ることができます。 たとえば、アプリケーションで表を記述する際、その表の列に関する情報も検索することができます。

OCIDescribeAny()コールには、パラメータの 1つとして記述ハンドルが必要です。 記述ハンドルは、OCIHandleAlloc()へのコールで前もって割り当てられていなければなりません。 アプリケーションでは、OCIDescribeAny()をコールした後、記述ハンドルから記述オブジェクトに関する情報を検索できます。

Page 152: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

OCIDescribeAny()で戻された情報は、ツリーのように階層的に編成されています。 次の図に表の記述の編成例を示します。

OCIDescribeAny()によって戻される記述ハンドルは、このような記述ツリーを指しています。 ツリーの各ノードには、そのノードに関連する属性と、再帰的な記述ハンドルのように情報を含むサブツリーを指す属性があります。 リスト(列リストなど)の要素のようにすべての属性が同質である場合には、それらの属性を「パラメータ」と言います。 このマニュアルでは、「ハンドル」と「パラメータ」は同じ意味です。 ノードに関連付けられた属性はOCIAttrGet()によって、パラメータは OCIParamGet()によって戻されます。

たとえば、表の記述ハンドルについての OCIAttrGet()は、列リストの情報のハンドルを戻します。 アプリケーションでは、OCIParamGet()を使用して、列リスト内の特定の列の列記述へのハンドルを検索します。 列記述子へのハンドルを、OCIAttrGet()へ受け渡すことによって、名前やデータ型などの列に関する詳細を得ることができます(上記の図の左側をたどるとそれがわかります)。

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

制限OCIDescribeAny()コールは基本情報に戻される情報を制限し、それが別の記述になる場合、ノードの拡張を停止します。 たとえば、表の列がオブジェクト型である場合、OCIは型を記述しているサブツリーを戻しません。その情報は別の記述によって取得できるからです。

同様の理由から、OCIでは、列または引数、表のフィールド、ビュー、ファンクション、プロシージャ、型についての記述もしません。 このような情報は、その情報を含むトップ・レベルのオブジェクトを記述することによって取得できるからです。

Page 153: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

データ型コードの注意型コード(たとえば、OCI_ATTR_TYPECODE属性で戻された OCI_TYPCODE値、OCI_ATTR_DATA_TYPE属性で戻された SQLT型コード)についての詳細は、3-23ページの「型コード」を参照してください。

OCI_ATTR_TYPECODEは、CREATE TYPE文を使用して新しい型が作成されるとき、ユーザーが供給する型を表す型コードを戻します。 これらの型コードは、数え上げ可能な型のOCITypeCodeで、OCI_TYPECODE定数で表されます。 内部 PL/SQL型(ブール、索引付き表)はサポートされません。

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

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

/* Initialize the OCI Process */ if (OCIInitialize((ub4) OCI_OBJECT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0 )) { (void) printf("FAILED: OCIInitialize()\n"); return OCI_ERROR; }

この機能についての詳細は、13-70ページの OCIInitialize()の説明を参照してください。

Page 154: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

OCI_ATTR_LIST_ARGUMENTSについての注意型メソッド用の OCI_ATTR_LIST_ARGUMENTS属性は、そのメソッドの "2番目のレベル "の引数を表します。

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

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

OCI_ATTR_LIST_ARGUMENTS属性は、my_typeレコードの引数 aと bに適用されます。

パラメータ属性パラメータは、OCIParamGet()によって戻されます。 パラメータは、異なる種類のオブジェクトや情報を記述できます。 したがって、パラメータの属性は、そのパラメータが含んでいる記述の型によって異なります。これらは、型特有の属性です。 この項では、さまざまなパラメータの属性およびハンドルについて説明します。

Page 155: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

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

これ以降の各項では、さまざまなパラメータの型に特有の属性およびハンドルのリストを示します。

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

属性 説明 属性データ型

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 - 表およびビューの列のリスト、または関数およびプロシージャの引数リスト、パッケージのサブプログラム・リスト

ub1

OCI_ATTR_TIMESTAMP この記述の基本であるオブジェクトのタイム・スタンプ(Oracleの日付書式による )。

ub1 *

OCI_ATTR_NUM_ATTRS 属性の数。 ub2

OCI_ATTR_NUM_PARAMS パラメータの数。 ub2

Page 156: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

表 /ビュー属性表またはビューのパラメータ (型 OCI_PTYPE_TABLEまたは OCI_PTYPE_VIEW)の場合、型特有の属性は次のとおりです。

その他に、表に属す次の属性があります。

プロシージャ /ファンクション属性プロシージャまたはファンクションのパラメータ (型 OCI_PTYPE_PROCまたはOCI_PTYPE_FUNC)の場合、型特有の属性は次のとおりです。

表 6–2 表またはビューに属す属性

属性 説明 属性データ型

OCI_ATTR_OBJID オブジェクト ID。 ub4

OCI_ATTR_NUM_COLS 列の数。 ub2

OCI_ATTR_LIST_COLUMNS 列リスト (型 OCI_PTYPE_LIST)。 dvoid *

表 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_ATTR_LIST_ARGUMENTS 引数リスト。 6-19ページの「リスト属性」を参照。

dvoid *

Page 157: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

次の属性は、パッケージ・サブプログラムでのみ定義されます。

パッケージ属性パッケージのパラメータ (型 OCI_PTYPE_PKG)の場合、型特有の属性は次のとおりです。

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

属性 説明 属性データ型

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

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

ub2

表 6–6 パッケージに属す属性

属性 説明 属性データ型

OCI_ATTR_LIST_SUBPROGRAMS サブプログラム・リスト。 6-19ページの「リスト属性」を参照。

dvoid *

Page 158: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

型属性パラメータが型用の場合 (型 OCI_PTYPE_TYPE)、属性はこれには表 6–7にリストされているとおりです。 これらの属性は、OCIInitialize()のコールの際に、アプリケーションによってOCI_OBJECTモードで OCIプロセスが初期化される場合にだけ有効です。

表 6–7 型に属す属性

属性 説明 属性データ型

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

OCIRef *

OCI_ATTR_TYPECODE 型コード。 6-4ページの「データ型コードの注意」を参照。 現在は、OCI_TYPECODE_OBJECTまたはOCI_TYPECODE_NAMEDCOLLECTIONだけが使用できます。

OCITypeCode

OCI_ATTR_COLLECTION_TYPECODE 型がコレクションの場合はコレクションの型コードで、それ以外の場合は無効。 6-4ページの「データ型コードの注意」を参照。 現在は、OCI_TYPECODE_VARRAYまたはOCI_TYPECODE_TABLEだけが使用できます。 この属性が非コレクション型に対して問い合せされた場合、エラーが戻されます。

OCITypeCode

OCI_ATTR_VERSION ユーザーが割り当てたバージョンを含む NULL終了文字列。

text *

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 この型は FILE属性を含むか。 ub1

OCI_ATTR_COLLECTION_ELEMENT コレクション要素へのハンドル。 6-13ページの「コレクション属性」を参照。

dvoid *

Page 159: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

型属性パラメータが型の属性の場合 (type OCI_PTYPE_TYPE_ATTR)、属性は表 6–8にリストされているとおりです。

OCI_ATTR_NUM_TYPE_ATTRS 型属性の数 ub4

OCI_ATTR_LIST_TYPE_ATTRS 型属性のリスト。 6-19ページの「リスト属性」を参照。

dvoid *

OCI_ATTR_NUM_TYPE_METHODS 型メソッドの数 ub4

OCI_ATTR_LIST_TYPE_METHODS 型メソッドのリスト。 6-19ページの「リスト属性」を参照。

dvoid *

OCI_ATTR_MAP_METHOD 型のマップ・メソッド。 6-11ページの「型メソッド属性」を参照。

dvoid *

OCI_ATTR_ORDER_METHOD 型の順序メソッド。 6-11ページの「型メソッド属性」を参照。

dvoid *

表 6–8 型属性に属す属性

属性 説明 属性データ型

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

ub2

OCI_ATTR_TYPECODE 型属性のデータ型。 6-4ページの「データ型コードの注意」を参照。

OCITypeCode

OCI_ATTR_DATA_TYPE 数値型属性の精度。6-4ページの「データ型コードの注意」を参照。

ub2

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

OCI_ATTR_PRECISION 数値型属性のスケール。記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

ub1

表 6–7 型に属す属性 (続き )

属性 説明 属性データ型

Page 160: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

型メソッド属性パラメータが型のメソッドの場合 (型 OCI_PTYPE_TYPE_METHOD)、属性は表 6–9にリストされているとおりです。

OCI_ATTR_SCALE the scale of numeric type attributes. 記述で、精度に0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

sb1

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

text *

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

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

OCIRef *

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

ub2

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

ub1

表 6–9 型メソッドに属す属性

属性 説明 属性データ型

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

text *

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

OCITypeEncap

OCI_ATTR_LIST_ARGUMENTS 引数リスト。 6-5ページの「OCI_ATTR_LIST_ARGUMENTSについての注意」、および 6-19ページの「リスト属性」を参照。

dvoid *

表 6–8 型属性に属す属性 (続き )

属性 説明 属性データ型

Page 161: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

参照として、次のコードは、対応するプロシージャ /ファンクションを判断するときに使用できるメソッド・フラグを示しています。

OCITypeMethodFlag{ OCI_TYPEMETHOD_INLINE = 0x0001, /* inline */ OCI_TYPEMETHOD_CONSTANT = 0x0002, /* constant */ OCI_TYPEMETHOD_VIRTUAL = 0x0004, /* virtual */ OCI_TYPEMETHOD_CONSTRUCTOR = 0x0008, /* constructor */ OCI_TYPEMETHOD_DESTRUCTOR = 0x0010, /* destructor */ OCI_TYPEMETHOD_OPERATOR = 0x0020, /* operator */ OCI_TYPEMETHOD_SELFISH = 0x0040, /* selfish method (generic otherwise) */

OCI_TYPEMETHOD_MAP = 0x0080, /* map (relative ordering) */ OCI_TYPEMETHOD_ORDER = 0x0100, /* order (relative ordering) */ /* OCI_TYPEMETHOD_MAP and OCI_TYPEMETHOD_ORDER are mutually exclusive */

OCI_TYPEMETHOD_RNDS= 0x0200, /* Read no Data State (default) */ OCI_TYPEMETHOD_WNDS= 0x0400, /* Write no Data State */ OCI_TYPEMETHOD_RNPS= 0x0800, /* Read no Process State */ OCI_TYPEMETHOD_WNPS= 0x1000 /* Write no Process State */ }

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

表 6–9 型メソッドに属す属性

属性 説明 属性データ型

Page 162: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

コレクション属性パラメータがコレクション型の場合 (型 OCI_PTYPE_COLL)、属性は表 6–10にリストされているとおりです。

表 6–10 コレクション型に属す属性

属性 説明 属性データ型

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

ub2

OCI_ATTR_TYPECODE 型コード。 6-4ページの「データ型コードの注意」を参照。

OCITypeCode

OCI_ATTR_DATA_TYPE 型属性のデータ型。 6-4ページの「データ型コードの注意」を参照。

ub2

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

ub4

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

OCI_ATTR_PRECISION 数値型属性の精度。 記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

ub1

OCI_ATTR_SCALE 数値型属性のスケール。 記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

sb1

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

text *

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

Page 163: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

シノニム属性パラメータがシノニムの場合 (型 OCI_PTYPE_SYN)、属性は表 6–11にリストされているとおりです。

順序属性順序のパラメータ (型 OCI_PTYPE_SEQ)の場合、属性は表 6–12にリストされ

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

OCIRef *

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

ub2

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

ub1

表 6–11 シノニムに属す属性

属性 説明 属性データ型

OCI_ATTR_OBJID オブジェクト ID。 ub4

OCI_ATTR_SCHEMA シノニム翻訳のスキーマ名を含む、NULLで終了する文字列。

text *

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

text *

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

text *

表 6–10 コレクション型に属す属性 (続き )

属性 説明 属性データ型

Page 164: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

ているとおりです。

列属性表またはビューの列のパラメータ (型 OCI_PTYPE_COL)の場合、属性は表 6–13にリストされているとおりです。

表 6–12 順序に属す属性

属性 説明 属性データ型

OCI_ATTR_OBJID オブジェクト ID。 ub4

OCI_ATTR_MIN 最小値 (Oracle数値書式 )。 ub1 *

OCI_ATTR_MAX 最大値 (Oracle数値書式 )。 ub1 *

OCI_ATTR_INCR 増分値 (Oracle数値書式 )。 ub1 *

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

ub1 *

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

OCI_ATTR_HW_MARK 高水位標 (Oracle数値書式 )。 ub1 *

表 6–13 表またはビューの列のパラメータに属す属性

属性 説明 属性データ型

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

ub2

OCI_ATTR_DATA_TYPE 列のデータ型。 6-4ページの「データ型コードの注意」を参照。

ub2

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

OCI_ATTR_PRECISION 数値列の精度。 記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

ub1

Page 165: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCI_ATTR_SCALE 数値列のスケール。 記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

sb1

OCI_ATTR_IS_NULL 列で NULL値が許されない場合に、0(ゼロ )を戻す。

ub1

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

text *

OCI_ATTR_SCHEMA_NAME 型作成時のスキーマ名が付いた文字列を戻す。 text *

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

OCIRef *

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

ub2

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

ub1

表 6–13 表またはビューの列のパラメータに属す属性 (続き )

属性 説明 属性データ型

Page 166: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

引数 /結果属性プロシージャまたは関数の引数のパラメータ (型 OCI_PTYPE_ARG)、または型メソッドの引数のパラメータ (型 OCI_PTYPE_TYPE_ARG)、メソッド結果のパラメータ (型OCI_PTYPE_TYPE_RESULT)の場合、属性は表 6–14にリストされているとおりです。

表 6–14 引数 /結果属性に属す属性

属性 説明 属性データ型

OCI_ATTR_NAME 引数名である文字列へのポインタを戻す。 text *

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

ub2

OCI_ATTR_TYPECODE 型コード。 6-4ページの「データ型コードの注意」を参照。

OCITypeCode

OCI_ATTR_DATA_TYPE 引数のデータ型。 6-4ページの「データ型コードの注意」を参照。

ub2

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

ub2

OCI_ATTR_PRECISION 数値引数の精度。 記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

ub1

OCI_ATTR_SCALE 数値引数のスケール。 記述で、精度に 0(ゼロ )値、またはスケールに -127を戻す場合、記述される項目が初期化されていないことを示します。つまり、データ・ディクショナリ内で NULLになっています。

sb1

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

ub2

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

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

dvoid *

OCI_ATTR_IOMODE 以下の引数モードを示す。

0は IN (OCI_TYPEPARAM_IN)

1は OUT (OCI_TYPEPARAM_OUT)

2は IN/OUT (OCI_TYPEPARAM_INOUT)

OCITypeParamMode

OCI_ATTR_RADIX 基数を戻す(数値型の場合)。 ub1

Page 167: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

6-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCI_ATTR_IS_NULL 列で NULL値が許されない場合に、0(ゼロ )を戻す。

ub1

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

text *

OCI_ATTR_SCHEMA_NAME SQLT_NTYまたは SQLT_REFについては、その型が作成されたスキーマ名、または、パッケージのローカル型の場合は、そのパッケージが作成されたスキーマ名を持つ文字列を戻す。

text *

OCI_ATTR_SUB_NAME SQLT_NTYまたは SQLT_REFについては、パッケージのローカル型の場合に、型名を持つ文字列を戻す。

text *

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

text *

OCI_ATTR_REF_TDO 引数の型がオブジェクトの場合に、その型のTDOの REFを戻す。

OCIRef *

OCI_ATTR_CHARSET_ID 引数が文字列 /文字型の場合に、キャラクタ・セット IDを戻す。

ub2

OCI_ATTR_CHARSET_FORM 引数が文字列 /文字型の場合、

キャラクタ・セット・フォームを戻す。

ub1

表 6–14 引数 /結果属性に属す属性 (続き )

属性 説明 属性データ型

Page 168: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIDescribeAny()の使用

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

リスト属性列または引数、サブプログラムのリストのパラメータ (型 OCI_PTYPE_LIST)の場合、型特有の属性およびハンドル(パラメータ)は次のとおりです。

■ リストには、リスト型を指定する OCI_ATTR_LIST_TYPE属性がある。可能な値は次のとおりです。

– OCI_LTYPE_COL - 列リスト

– OCI_LTYPE_ARG_PROC - プロシージャ引数リスト

– OCI_LTYPE_ARG_FUNC - ファンクション引数リスト

– OCI_LTYPE_SUBPRG - サブプログラム・リスト

– OCI_LTYPE_TYPE_ATTR - 型属性リスト

– OCI_LTYPE_TYPE_METHOD - 型メソッド・リスト

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

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

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

■ リストには、リスト内の各々の列または引数、サブプログラム (型 OCI_PTYPE_COLまたは OCI_PTYPE_ARG、OCI_PTYPE_PROC、OCI_PTYPE_FUNC)の1..OCI_ATTR_NUM_PARAMSパラメータがある。 ファンクション引数リストの場合、位置 0には、戻り値 (型 OCI_PTYPE_ARG)のパラメータがあります。

Page 169: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

6-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

例次の例では、異なる種類のスキーマ・オブジェクトを記述するための OCIDescribeAny()の使用方法を示します。 詳細なコードサンプルは、D-54ページの「例 4、オブジェクトの解明」を参照してください。

表用の列データ型の検索この例では、明示的な記述の使用方法を示しています。 表の列データ型を検索するアプリケーションを例として考えます。 次の擬似コードは、アプリケーションで記述インタフェースを使用する例です。

text objptr[] = <table-name>;ub4 objp_len = strlen(<table_name>);OCIParam *parmh; /* parameter handle */OCIParam *collsthd; /* handle to list of columns */OCIParam *colhd; /* column handle */

/* get the describe handle for the table */if (OCIDescribeAny(svch, errh, objptr, objp_len, OCI_OTYPE_NAME, 0,

OCI_PTYPE_TABLE, &dschp))return error;

/* get the parameter handle */if (OCIAttrGet(dschp, OCI_HTYPE_DESCRIBE, &parmh, 0, OCI_ATTR_PARAM,

errh))return errors;

/* 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 */if (OCIAttrGet(parmh, OCI_DTYPE_PARAM, &numcols, 0,

OCI_ATTR_NUM_COLS, errh))return errors;

/* get the handle to the column list of the table */if (OCIAttrGet(parmh, OCI_DTYPE_PARAM, &collsthd, 0,

OCI_ATTR_LIST_COLUMNS, errh)==OCI_NO_DATA)return 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(collsthd, OCI_DTYPE_PARAM, errh, &colhd, i))

return error;/* for example, get data type for ith column */if (OCIAttrGet(colhd, OCI_DTYPE_PARAM, &datatype[i-1], 0,

OCI_ATTR_DATA_TYPE, errh))

Page 170: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

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

return error;}

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

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

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

以下の擬似コードにより、P1の記述が説明されます。

text objptr[] = "P1"; /* procedure name */ub4 objp_len = strlen("P1");OCIParam *parmh; /* parameter handle */OCIParam *arglst; /* list of args */OCIParam *arg; /* argument handle */ub2 numargs, pos, level; text *name;ub4 namelen;

/* get the describe handle for the table */if (OCIDescribeAny(svch, errh, objptr, objp_len, OCI_OTYPE_NAME, 0,

OCI_PTYPE_PROC, &dschp))return error;

/* get the parameter handle */if (OCIAttrGet(dschp, OCI_HTYPE_DESCRIBE, &parmh, 0, OCI_ATTR_PARAM,

errh))return errors;

/* Get the number of arguments and the arg list */if (OCIAttrGet (parmh, OCI_DTYPE_PARAM, &arglst, 0, OCI_ATTR_LIST_ARGUMENTS, errh))

return errors;if (OCIAttrGet (parmh, OCI_DTYPE_PARAM, &numargs, 0,

OCI_ATTR_NUM_PARAMS, errh))

Page 171: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

6-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

return errors;

/* For a procedure, we begin with i = 1; for a function, we begin with i = 0. */

for (i = 1; i < numargs; i++) {OCIParamGet (arglst, OCI_DTYPE_PARAM, errh, &arg, i);OCIAttrGet (arg, OCI_DTYPE_PARAM, &name, &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 (arg, OCI_DTYPE_PARAM, &arglst1, 0,OCI_ATTR_LIST_ARGUMENTS, erh);

/* check if the current argument is a record. For arg1 in P1arglst1 is NULL. */

if (arglst1) {OCIAttrGet (arg, OCI_DTYPE_PARAM, &numargs1,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 P1, the number of arguments at the level 1 would be 2 */

for (i = 1; i < numargs1, i++) {OCIParamGet (arglst1, OCI_DTYPE_PARAM, errh, &arg1, i);OCIAttrGet (arg1, OCI_DTYPE_PARAM, &name1, &namelen1,

OCI_ATTR_NAME, errh);...}

}}

オブジェクト型の属性の検索この例では、名前付きオブジェクト型についての明示的な記述の使用方法を示します。 オブジェクトを名前によって、またはオブジェクト参照 (OCIRef)によって記述する方法を説明します。 以下の擬似コードにより、オプジェクト型の属性の各データ型値の検索が試みられます。 これは 6-20ページの最初の例によく似ています。

text type_name[] = <type_name>;ub4 type_name_len = strlen(<type_name>);OCIRef *type_ref = <type_ref>;un4 numattrs;

Page 172: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

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

OCIDescribe *dschp; /* describe handle */OCIParam *parmh; /* parameter handle */OCIParam *attrlsthd; /* handle to list of attrs */OCIParam *attrhd; /* attribute handle */

/* allocate describe handle */if (OCIHandleAlloc((dvoid *)envh, (dvoid **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (dvoid **)0))return errors;

/* get the describe handle for the type */if (describe_by_name)if (OCIDescribeAny(svch, errh, (dvoid*)type_name, type_name_len,

OCI_OTYPE_NAME, 0, OCI_PTYPE_TYPE, dschp))return error;

elseif (OCIDescribeAny(svch, errh, (dvoid*)type_ref, 0, OCI_OTYPE_REF,

0, OCI_PTYPE_TYPE, dschp))return error;

/* get the parameter handle */if (OCIAttrGet(dschp, OCI_HTYPE_DESCRIBE, &parmh, 0, OCI_ATTR_PARAM,

errh))return errors;

/* The type information of the object, in this case, OCI_PTYPE_TYPE, is obtained from the parameter descriptor returned by the OCIAttrGet */

/* get the number of attributes in the type */if (OCIAttrGet(parmh, OCI_DTYPE_PARAM, &numattrs, 0,

OCI_ATTR_NUM_TYPE_ATTRS, errh))return error;

/* get the handle to the attribute list of the type */if (OCIAttrGet(parmh, OCI_DTYPE_PARAM, (dvoid *)&attrlsthd, 0,

OCI_ATTR_LIST_TYPE_ATTRS, errh)==OCI_NO_DATA)return errors;

/* 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(attrlsthd, OCI_DTYPE_PARAM, errh, &attrhd, i))

return errors;

Page 173: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

6-24 Oracle8コール・インタフェース・プログラマーズ・ガイド

/* for example, get data type and typecode for attribute; note that OCI_ATTR_DATA_TYPE returns the SQLT code, while OCI_ATTR_TYPECODE returns the Oracle Type System typecode. */if (OCIAttrGet(attrhd, OCI_DTYPE_PARAM,&datatype[i-1], 0,

OCI_ATTR_DATA_TYPE,errh))return errors;

/* for example, get data type for attribute*/if (OCIAttrGet(attrhd, OCI_DTYPE_PARAM,&typecode[i-1], 0,

OCI_ATTR_TYPECODE, errh))return errors;

/* if attribute is an object type, recursively describe it */if (typecode[i-1] == OCI_TYPECODE_OBJECT){OCIRef *attr_type_ref;OCIDescribe *nested_dschp;

/* allocate describe handle */if (OCIHandleAlloc((dvoid *)envh,(dvoid**)&dschp,(ub4)OCI_HTYPE_DESCRIBE,(size_t)0,(dvoid **)0))return errors;

if (OCIAttrGet(attrhd, OCI_DTYPE_PARAM,&attr_type_ref, 0, OCI_ATTR_REF_TDO,errh))

return errors;OCIDescribeAny(svch, errh,(dvoid*)attr_type_ref, 0,

OCI_OTYPE_REF, 0, OCI_PTYPE_TYPE, nested_dschp);/* go on describing the type... */

}}

名前付きコレクション型のコレクション要素のデータ型の検索この例では、名前付きコレクション型についての明示的な記述の使用方法を示しています。 オブジェクトを名前によって、またはオブジェクト参照 (OCIRef)によって記述する方法を説明します。 以下の擬似コードにより、オプジェクト型の属性の各データ型値の検索が試みられます。 これは 6-20ページの最初の例によく似ています。

text type_name[] = <type_name>;ub4 type_name_len = strlen(<type_name>);OCIRef *type_ref = <type_ref>;un4 numattrs;OCIDescribe *dschp; /* describe handle */OCIParam *parmh; /* parameter handle */OCIParam *attrlsthd; /* handle to list of attrs */OCIParam *attrhd; /* attribute handle */

Page 174: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

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

/* allocate describe handle */if (OCIHandleAlloc((dvoid *)envh, (dvoid **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (dvoid **)0))return errors;

/* get the describe handle for the type */if (describe_by_name)if (OCIDescribeAny(svch, errh, (dvoid*)type_name, type_name_len,

OCI_OTYPE_NAME, 0, OCI_PTYPE_TYPE, dschp))return errors;

elseif (OCIDescribeAny(svch, errh, (dvoid*)type_ref, 0, OCI_OTYPE_REF, 0,

OCI_PTYPE_TYPE, &dschp))return errors;

/* get the parameter handle */if (OCIAttrGet(dschp, OCI_HTYPE_DESCRIBE, &parmh, 0, OCI_ATTR_PARAM,

errh))return errors;

/* get the Oracle Type System type code of the type to determine that this is a collection type */if (OCIAttrGet(attrhd, OCI_DTYPE_PARAM,&typecode, 0, OCI_ATTR_TYPECODE,

errh))return errors;

/* if typecode is OCI_TYPECODE_NAMEDCOLLECTION,proceed to describe collection element */

if (typecode == OCI_TYPECODE_NAMEDCOLLECTION){/* get the collection’s type: ie, OCI_TYPECODE_VARRAY or OCI_TYPECODE_TABLE */

if (OCIAttrGet(parmh, OCI_DTYPE_PARAM, (dvoid *)&collection_typecode, 0, OCI_ATTR_COLLECTION_TYPECODE, errh))

return errors;

/* get the collection element; you MUST use this to further retrieve information about the collection’s element */if (OCIAttrGet(parmh, OCI_DTYPE_PARAM, &collection_element_parmh, 0, OCI_ATTR_COLLECTION_ELEMENT, errh))

return errors;

/* get the number of elements if collection is a VARRAY; not valid for nested tables */if (collection_typecode == OCI_TYPECODE_VARRAY)

if OCIAttrGet(collection_element_parmh, OCI_DTYPE_PARAM,(dvoid *)&num_elements, 0, OCI_ATTR_NUM_ELEMENTS, errh))

Page 175: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

6-26 Oracle8コール・インタフェース・プログラマーズ・ガイド

return errors;

/* now use the collection_element parameter handle to retrieve information about the collection element */if OCIAttrGet(collection_element_parmh, OCI_DTYPE_PARAM,

(dvoid *)&element_typecode, 0, OCI_ATTR_TYPECODE, errh))return errors;

/* do the same to describe additional collection element information; this is very similar to describing type attributes */}

Page 176: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

7-1

7OCIプログラミングの応用

この章は、次のトピックで構成されています。

■ 概要

■ トランザクション

■ ユーザー認証およびパスワードの管理

■ スレッド・セーフティ

■ ランタイム・データ割当てとピース単位操作

■ LOBおよび FILE操作

■ 外部プロシージャからの OCIコールバック

■ アプリケーション・フェイルオーバー・コールバック

■ OCIおよびアドバンスト・キューイング

■ Oracle Security Servicesアプリケーションの作成

注意: OCIを使って Oracle8 Serverのオブジェクトを操作する方法については、 第 8章の「OCIオブジェクト・リレーショナル・ プログラミング」を参照してください。

Page 177: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

概要

7-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

概要第 2章では、OCIプログラミングの基本概念を紹介しました。 この章は、その応用として高度な概念を紹介することを目的としています。この章では、次の項目について説明します。

トランザクション 第 2章では、単純なトランザクションで、コミットまたはロールバックがどのように行われるかを説明しました。 この章では、異なるレベルのトランザクションの複雑性について、グローバル・トランザクション、および OCIコールを通して可能な操作を含めて説明します。

ユーザー認証およびパスワードの管理 第 2章では、OCIの初期化の一部としてOCISessionBegin()コールを取り上げました。 この章では、OCISessionBegin()で使用することができる追加のオプションについて説明します。 また、OCIPasswordChange()コールを使用するユーザー認証とパスワード管理について説明します。

スレッド・セーフティ この章では、スレッド・セーフティおよびマルチスレッド・アプリケーションの開発に対する OCIのサポートについて説明します。

ランタイム・データ割当てとピース単位操作 ピース単位でのデータの挿入および更新、フェッチを説明します。

LOBおよび FILE操作 LOBおよび FILEを操作するときに使用する OCI関数について説明します。

外部プロシージャからの OCIコールバック 外部サブルーチンを作成するときの注意事項を説明します。

アプリケーション・フェイルオーバー・コールバック アプリケーション・フェイルオーバー・コールバック関数の作成と使用方法について説明します。

OCIおよびアドバンスト・キューイング Oracle8のアドバンスト・キュー機能に関連するOCI関数について説明します。

Oracle Security Servicesアプリケーションの作成 Oracle Security Servicesアプリケーションを作成するときの注意事項を説明します。

Page 178: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

OCIプログラミングの応用 7-3

トランザクションOracleコール・インタフェースのリリース 8.0では、ローカル・トランザクションとグローバル・トランザクションの両方での操作をサポートする、一連の APIコールが提供されています。 これらのコールにはオブジェクトのサポートが含まれているので、OCIアプリケーションがオブジェクト・モードで実行されている場合、コミット・コールおよびロールバック・コールでは、オブジェクト・キャッシュとトランザクションの状態が同期します。

トランザクション操作を実行する関数は下記のとおりです。 それぞれのコールには、適切なサーバー・コンテキストおよびユーザー・セッション・ハンドルで初期化されるべき サービス・コンテキスト・ハンドルが必要です。 トランザクション・ハンドルは、サービス・コンテキストの 3番目の要素で、トランザクションに関する特定の情報を格納します。 SQL文が準備されると、トランザクション・ハンドルは、特定のサービス・コンテキストと関連付けられます。 その文が実行されると、その結果(問合せ、フェッチ、挿入)は、サービス・コンテキストと現在関連しているトランザクションの一部になります。

■ OCITransStart() - トランザクションの開始をマークする。

■ OCITransDetach() - トランザクションを切り離す。

■ OCITransCommit() - トランザクションをコミットする。

■ OCITransRollback() - トランザクションをロールバックする。

■ OCITransPrepare() - 分散処理環境でトランザクションをコミットする準備をする。

■ OCITransForget() - 発見的に完了したグローバル・トランザクションの記憶をサーバーから消す。

これらのコールをすべて使用するか、そのうちのいくつかだけを使用するかは、そのアプリケーションでのトランザクションの複雑性のレベルによって異なります。 次の項では、詳細に説明します。

関連項目 : これらのコールに関する特定の情報は、第 10章の関数の説明を参照してください。

トランザクションの複雑性のレベルOCIでは、3つのレベルのトランザクションの複雑性をサポートします。 それぞれのレベルについては、次の項以降で説明します。

1. 単純なローカル・トランザクション

2. 直列可能または読込み専用のローカル・トランザクション

3. グローバル・トランザクション

単純なローカル・トランザクションアプリケーションの多くは、単純なローカル・トランザクションだけを必要とします。 これらのアプリケーションでは、そのアプリケーションの中でデータベースを変更すると、暗黙

Page 179: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

7-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

的トランザクションが作成されます。 アプリケーションなどで必要とされるトランザクション特有のコールには、次のようなコールがあります。

■ OCITransCommit() - トランザクションをコミットする。

■ OCITransRollback() - トランザクションをロールバックする。

1つのトランザクションがコミットまたはロールバックするとすぐに、次のデータベース修正によって、そのアプリケーションに対する新規の暗黙的トランザクションが作成されます。

1つのサービス・コンテキストでは、常に 1つの暗黙的トランザクションだけをアクティブにできます。 暗黙のトランザクションの属性は、ユーザーには不明確です。

アプリケーションで複数の権限を作成すると、それぞれの権限に対し、関連する暗黙的トランザクションを 1つずつ保持することができます。

単純なローカル・トランザクションの使用方法を示すコード・サンプルは、13-144ページの例を参照してください。

直列可能または読込み専用のローカル・トランザクションアプリケーションで直列可能または読込み専用トランザクションを必要とする場合は、単純なローカル・トランザクションを操作するアプリケーションで必要とされる OCIコールの他に、追加の OCIコールが必要です。 直列可能または読込み専用トランザクションを初期化するには、トランザクションを開始する OCITransStart()をアプリケーションでコールして、トランザクションを作成する必要があります。

OCITransStart()コールでは、flagsパラメータで、OCI_TRANS_SERIALIZABLEまたはOCI_TRANS_READONLYのいずれか適切な値を指定します。 フラグが指定されない場合、デフォルト値は、標準の読取り書込みトランザクションの OCI_TRANS_READWRITEです。

OCITransStart()コールで読込み専用オプションを指定すると、SET TRANSACTION READ ONLY文を実行するためのサーバー往復は必要ありません。

グローバル・トランザクショングローバル・トランザクションは、より高度なトランザクション処理のアプリケーションでだけ必要です。

注意 :⦆分配またはグローバル・トランザクション環境での操作を行わない場合は、この項は飛ばしてください。

この項では、最初にグローバル・トランザクションの背景について説明し、次に、グローバル・トランザクションを処理するための OCIコールの使用に関する特定の情報について説明します。

トランザクション識別子 トランザクション処理 (TP)モニターなどの 3層アプリケーションでは、グローバ ル・トランザクションの作成および管理を行います。 これらのアプリケー

Page 180: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

OCIプログラミングの応用 7-5

ションは、グローバル・トランザクション識別子 (XID)を提供します。これによって、サーバーは、ローカル・トランザクションと関連付けられます。

グローバル・トランザクションには、1つ以上のブランチがあります。 それぞれのブランチは、XIDによって識別されます。 XIDは、グローバル・トランザクション識別子 (gtrid)とブランチ識別子 (bqual)で構成されています。 この構造は、標準の XA仕様に基づくものです。

次の例は、1234という XIDの構造の例です。

関連項目 : トランザクション識別子の詳細は、『Oracle8 Server分散システム』 のマニュアルを参照してください。

OCIトランザクション・コールで使用されるトランザクション識別子は、OCIAttrSet()を使用して、トランザクション・ ハンドルの OCI_ATTR_XID属性に設定します。OCIAttrSet()のかわりに、OCI_ATTR_TRANS_NAME属性で設定した名前でトランザクションを識別することもできます。

トランザクション・ブランチ Oracle8では、単一のグローバル・トランザクションで、一対のブランチが密結合している場合と疎結合している場合の両方をサポートしています。

■ 密結合ブランチとは、同じローカル・トランザクションを共有する個々のブランチです。 この場合は、gtridは、単一のローカル・トランザクションを指し、複数のブランチが同じトランザクションを指します。 トランザクションの所有者は、最初に作成されたブランチです。

■ 疎結合ブランチとは、異なるローカル・トランザクションを使用する個々のブランチです。 この場合、gtridと bqualがともに一意のローカル・トランザクションにマッピングされます。 各ブランチは、異なるトランザクションを指します。

OCITransStart()の flagsパラメータによって、アプリケーションから、OCI_TRANS_TIGHTまたは OCI_TRANS_LOOSEを渡して結合のタイプを指定できます。

Oracle8の OCIでは、1つのセッションは、OCISessionBegin()で作成した 1つのユーザー・セッションに対応します。

次の図は、あるアプリケーションの密結合ブランチを説明しています。 この図では、S1と S2がセッション、B1と B2がブランチ、Tがトランザクションです。 最初の例では、2つのブランチの XIDが同じトランザクションで操作されているので、同じ gtridを共有します。ただし、これらは別々のブランチなので、異なる bqualを持ちます。

コンポーネント 値

gtrid 12

bqual 34

gtrid+bqual=XID 1234

Page 181: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

7-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

図 7–1 複数の密結合ブランチ

また、単一セッションで異なる複数のブランチを操作することも可能です。 この場合、次の図に示すように、異なるグローバル・トランザクションなので、XIDの gtridコンポーネントが異なります。

図 7–2 複数のブランチ操作のセッション

この場合のコード・サンプルは、13-151ページの例を参照してください。

同じトランザクションを共有する複数のブランチを単一セッションで操作することも可能です。しかし、これはあまり実用的ではありません。 この場合のコード・サンプルは、13-154ページの例を参照してください。

次の図は、疎結合ブランチの例です。

T

B1

S1

B2

S2

T1 T2

B1

S1

B2

Page 182: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

OCIプログラミングの応用 7-7

図 7–3 疎結合ブランチ

ブランチの状態 トランザクション・ブランチの状態は、 アクティブ・ブランチと非アクティブ・ブランチの 2つに分類されます。

サーバー・プロセスがブランチに対する要求を実行しているとき、ブランチはアクティブ状態です。 サーバー・プロセスがブランチ内の要求を実行していないとき、ブランチは非アクティブ状態です。 この場合は、ブランチの親セッションは 1つもなく、ブランチはサーバーの PMONプロセスに所有されます。

ブランチの連結解除と再開 OCIアプリケーションが OCITransDetach()コールを使用して ブランチを連結解除すると、ブランチは非アクティブ状態になります。 flagsパラメータにOCI_TRANS_RESUMEを設定した OCITransStart()のコールを使用してブランチを再開すると、ブランチを再びアクティブにできます。

アプリケーションで OCITransDetach()をコールし、ブランチを連結解除する場合は、そのブランチを作成した OCITransStart()コールの timeoutパラメータで指定した値を使用します。 timeoutパラメータで指定した秒数が経過すると、PMONの子として休止しているトランザクションは削除されます。

アプリケーションでブランチを再開するには、OCITransStart()をコールします。このとき、トランザクション・ハンドルの属性としてブランチの XIDを、flagsパラメータにOCI_TRANS_RESUMEを、また、timeoutパラメータには前回とは異なる値を指定します。 このコールの timeoutの値は、ブランチが他のプロセスで使用中のとき、そのブランチが使用可能になるまでセッションが待つ時間の長さを指定します。 ブランチにアクセスしているプロセスがない場合は、すぐに再開されます。

注意 : トランザクションは、そのトランザクションを連結解除したプロセス以外のプロセスからでも再開できます。ただし、トランザクションを再開できるのは、そのトランザクションを連結解除したプロセスと同じ権限を持つプロセスに限ります。

T1 T2

B2B1

S2S1

Page 183: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

7-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

クライアント・データベース名の設定 サーバー・ハンドルには、関連するOCI_ATTR_EXTERNAL_NAME属性、および OCI_ATTR_INTERNAL_NAME属性があります。 これらの属性により、グローバル・トランザクションを実行するときに記録されるクライアント・データベース名を設定します。 この名前は、故障のために準備状態で保留になっている可能性があるトランザクションを追跡するために、DBAで使用できます。

警告 : OCIアプリケーションでは、グローバル・トランザクションにログオンして使用する前に、OCIAttrSet()を使用して、これらの属性を設定する必要があります。

1フェーズ・コミットと 2フェーズ・コミット グローバル・トランザクションは、1フェーズまたは 2フェーズでコミットされます。 最も単純な状態は、単一のトランザクションが単一のデータベースに対して操作されている場合です。 この場合、アプリケーションでOCITransCommit()をコールすることによって、そのトランザクションの 1フェーズ・コミットを実行できます。OCITransCommit()コールのデフォルト値は、1フェーズ・コミットです。

アプリケーションが、複数のデータベースまたは複数の Oracle Serverに対して処理を行っている場合は、より複雑な状態になります。 この場合は、2フェーズ・コミットが必要です。 2フェーズ・コミットは、次のステップで構成されています。

1. 準備 - アプリケーションは、各トランザクションに対し、準備コール OCITransPrepare()を発行します。 トランザクションでは、現在の作業をコミットできるか(OCI_SUCCESS)、できないか (OCI_ERROR)を示す値を戻します。

2. コミット - 各準備コールが OCI_SUCCESSの値を戻した場合は、アプリケーションから、各トランザクションにコミット・コール OCITransCommit()を発行できます。 適切な処理を行うためには、このコミット・コールの flagsパラメータにOCI_TRANS_TWOPHASEを明示的に設定する必要があります。 このコールのデフォルトは、1フェーズ・コミットです。

注意 : トランザクションが読込み専用であるため、コミットが不適切かつ不必要であることを示す必要がある場合、準備コールは OCI_SUCCESS_WITH_INFOを戻します。

追加のコール OCITransForget()は、偶発的に完了したトランザクションの情報をデータベースで消す必要があることを示します。 このコールは、問題が起きて 2フェーズ・コミットを異常終了しなければならない場合に使用します。 サーバーで OCITransForget() コールを受け取ると、トランザクションに関する情報はすべて「記憶から消去」されます。

関連項目 : 2フェーズ・コミットの詳細は、『Oracle8 Server分散システム』 マニュアルを参照してください。

トランザクションの例この項では、トランザクション OCIコールの使用方法の例を示します。 次の表は、一連のOCIコールおよびその他の処理を、その処理結果とあわせて示したものです。 簡潔な表にするため、これらのコールのパラメータをすべてリストするのではなく、コールの流れを中心に解説します。

Page 184: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

OCIプログラミングの応用 7-9

「OCIの処理」列は、OCIアプリケーションの活動やコールの内容を示します。 「XID」列には、必要に応じて、トランザクション識別子がリストされます。 「フラグ」列は、flagsパラメータに渡された値を示します。 「結果」列は、コールの結果を説明します。

更新成功 1フェーズ・コミット

トランザクションの開始、切離し、再開、準備、2フェーズ・コミット

ステップ OCIの処理 XID フラグ 結果

1 OCITransStart 1234 OCI_TRANS_NEW 新規の読込み /書込みトランザクションを開始する

2 SQL UPDATE 列を更新する

3 OCITransCommit コミットが成功する

ステップ OCIの処理 XID フラグ 結果

1 OCITransStart 1234 OCI_TRANS_NEW 新規の読込み専用トランザクションを開始する

2 SQL UPDATE 列を更新する

3 OCITransDetach トランザクションを切り離す

4 OCITransStart 1234 OCI_TRANS_RESUME トランザクションを再開する

5 SQL UPDATE

6 OCITransPrepare トランザクションで 2フェーズ・コミットを準備する

7 OCITransCommit OCI_TRANS_TWOPHASE トランザクションをコミットする

注意 :⦆上の表のステップ 4では、トランザクションは、同じ権限を持つ別のプロセスからでも再開できます。

Page 185: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

トランザクション

7-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

読込み専用トランザクションの更新失敗

読込み専用トランザクションの開始および選択、コミット

関連する初期化パラメータグローバル・トランザクション・ブランチおよび移行可能オープン接続の使用には、関連する 2つの初期化パラメータがあります。

■ TRANSACTIONS - このパラメータでは、システム全体のグローバル・トランザクション・ブランチの最大数を指定します。 一方、MAX_TRANSACTION_BRANCHESは、1つのグローバル・トランザクションのブランチ数を指定します。

■ OPEN_LINKS_PER_INSTANCE - このパラメータは、移行可能オープン接続の最大数を指定します。 移行可能オープン接続は、トランザクションをコミットした後に接続をキャッシュできるように、グローバル・トランザクションで使用します。 これが、OPEN_LINKSパラメータとは異なる点です。OPEN_LINKパラメータで指定するのは、1セクションからの接続数です (OPEN_LINKパラメータは、グローバル・トランザクションには適用できません )。

ステップ OCIの処理 XID フラグ 結果

1 OCITransStart 1234 OCI_TRANS_NEW |

OCI_TRANS_READONLY

新規の読込み専用トランザクションを開始する

2 SQL UPDATE トランザクションが読込み専用なので、更新は失敗する

3 OCITransCommit コミットによる影響なし

ステップ OCIの処理 XID フラグ 結果

1 OCITransStart 1234 OCI_TRANS_NEW |

OCI_TRANS_READONLY

新規の読込み専用トランザクションを開始する

2 SQL SELECT データベースに問合せをする

3 OCITransCommit 影響なし - トランザクションは読込み専用なので、何も変更なし。

Page 186: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ユーザー認証およびパスワードの管理

OCIプログラミングの応用 7-11

ユーザー認証およびパスワードの管理OCIリリース 8.0からは、OCIアプリケーションで複数のユーザーの認証とメンテナンスができるようになりました。 新しい OCIコールでは、アプリケーションでユーザーのパスワードを更新できます。 このコールが特に役立つのは、認証の処理でパスワード期限満了のメッセージが戻された場合です。

認証OCISessionBegin()コールは、サービス・コンテキスト・ハンドルに設定されたサーバーに対して、ユーザーを認証するときに使用します。

Oracle8では、サーバー・ハンドルに要求を行う前に対して OCISessionBegin()をコールする必要があります。 OCISessionBegin()は、サーバー・ハンドルによってサービス・コンテキスト内に指定されたユーザーによる Oracleサーバーへのアクセスだけを認証します。 つまり、OCIServerAttach()をコールしてサーバー・ハンドルを初期化した後、指定のサーバーに対してユーザーを認証するために OCISessionBegin()をコールする必要があります。

指定のサーバー・ハンドルに対して、最初に OCISessionBegin()をコールしたとき、ユーザー・セッションは、移動可能モード (OCI_MIGRATE)では作成されません。

サーバー・ハンドルに対して OCISessionBegin()をコールした後、アプリケーションではOCISessionBegin()を再度コールし、別のユーザー・セッション・ハンドルを、別の(または同じ)資格証明と別の(または同じ)操作モードを使用して初期化できます。 アプリケーションでユーザーを OCI_MIGRATEモードで認証する場合、サービス・ハンドルは、移動可能ではないユーザー・ハンドルにすでに関連付けられている必要があります。 このユーザー・ハンドルのユーザー IDは、移動可能なユーザー・セッションの所有者 IDになります。 移動可能なすべてのセッションは、移動可能ではない親セッションを持つ必要があります。

OCI_MIGRATEを指定しない場合、ユーザー・セッション・コンテキストは、svchpに設定されたサーバー・ハンドルと同じサーバー・ハンドルでしか使用できません。 OCI_MIGRATEモードを指定した場合、ユーザー認証は、異なるサーバー・ハンドルで設定されます。 しかし、ユーザー・セッション・コンテキストは、同じデータベース・インスタンスを要求するサーバー・ハンドルでだけ使用できます。 セキュリティ・チェックは、セッションの切替え中に行われます。 プロセスまたは回路は、セッションの所有者 IDが、現在同じプロセスまたは回路に接続された移動可能ではないセッションのユーザー IDと一致する場合だけ(セッションの作成者でない限り)、移動可能なセッションに切り替えることができます。

OCI_SYSDBAおよび OCI_SYSOPER、OCI_PRELIM_AUTHは、1次ユーザー・セッション・コンテキストでだけ使用できます。

OCISessionBegin()のコール用の資格証明を用意するには、2通りの方法のうち 1つがサポートされています。 最初の方法は、OCISessionBegin()に渡されるユーザー・セッション・ハンドル内にデータベース認証用の有効なユーザー名とパスワードのペアを用意することです。 この方法では、OCIAttrSet()を使用して、ユーザー・セッション・ハンドルに対して

Page 187: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ユーザー認証およびパスワードの管理

7-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCI_ATTR_USERNAMEおよび OCI_ATTR_PASSWORD属性を設定します。 こうすると、OCI_CRED_RDBMSを指定して OCISessionBegin()がコールされます。

注意 :⦆ユーザー・セッション・ハンドルが OCISessionEnd()によって終了した場合、ユーザー名とパスワード属性は変更されないため、OCISessionBegin()への以降のコールで再使用できます。 再使用しない場合は、次回の OCISessionBegin()コールの前に新しい値を設定し直す必要があります。

もう 1つの資格証明の方法は、外部資格証明です。 この方法では、OCISessionBegin()をコールする前に、ユーザー・セッション・ハンドルについて属性を設定する必要はありません。 資格証明タイプは OCI_CRED_EXTです。 これは Oracle7の ‘connect /’ 構文に相当します。 すでに OCI_ATTR_USERNAMEおよび OCI_ATTR_PASSWORDに値が設定してある場合、OCI_CRED_EXTを使用すると、これらの値は無視されます。

パスワード管理リリース 8.0の OCIでは、OCIPasswordChange()を提供しており、OCIアプリケーションで、必要に応じて、ユーザーのデータベース・パスワードを変更できます。 これは、OCISessionBegin()へのコールで、ユーザーのパスワードが期限切れであることを示すエラー・メッセージまたは警告が戻された場合に特に有効です。

アプリケーションでは、適切なフラグを設定すれば、OCIPasswordChange()を使用して、パスワードを変更するのと同様にユーザー認証コンテキストを設定できます。 OCIPasswordChange()が未初期化サービス・コンテキストと共にコールされる場合、サービス・コンテキストが確立され、旧パスワードを使ってユーザーのアカウントを認証し、次に新しいパスワードに変更されます。 OCI_AUTHフラグを設定している場合、ユーザー・セッションは初期化された状態のままになります。 OCI_AUTHフラグを設定していない場合、ユーザー・セッションは消去されます。

OCIPasswordChange()に渡したサービス・コンテキストがすでに初期化済みである場合、OCIPasswordChange()では、指定のアカウントが旧パスワードを使用して認証され、旧パスワードが新パスワードに変更されます。 この場合、どのフラグを設定していても、ユーザー・セッションは初期化された状態のままになります。

Page 188: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

スレッド・セーフティ

OCIプログラミングの応用 7-13

スレッド・セーフティOracle8 Serverおよび OCIライブラリのスレッド・セーフティ機能により、開発者は、OCIをマルチスレッド環境で使用できます。 スレッド・セーフティ機能を使用すると、1つのスレッドから他のスレッドへの副次作用なしに、OCIのコードを、OCIコールを実行するユーザー・プログラムの複数のスレッドから再入可能にできます。

注意 : スレッド・セーフティは、どのプラットフォームでも利用できるとは限りません。 詳細は、使用しているシステム固有の Oracleマニュアルで確認してください。

次の項以降では、OCIを使用してマルチスレッド・アプリケーションを開発する方法について説明します。

OCIスレッド・セーフティの利点Oracleコール・インタフェースにスレッド・セーフティを組み込むことは、次の利点があります。

■ 複数のスレッドで OCIコールを実行した場合も、単一のスレッドで連続するコールを実行したのと同じ結果になる。

■ 複数のスレッドで OCIコールを実行した場合、スレッド間で副次作用はない。

■ マルチスレッド・プログラムを作成しない場合でも、スレッド・セーフの OCIコールを使用してもパフォーマンスは低下しない。

■ 複数のスレッドを使用すると、プログラムのパフォーマンスが向上する。 パフォーマンスが向上するのは、スレッドが別々のプロセッサで並行稼動するマルチプロセッサ・システム、および低速操作と高速操作の間でオーバーラップが発生するシングル・プロセッサ・システムの場合です。

スレッド・セーフティと 3層アーキテクチャクライアント /サーバー・アプリケーションでは、クライアントをマルチスレッド・プログラムにできます。クライアント /サーバー以外のマルチスレッド・アプリケーションの典型は、3層(クライアント /エージェント /サーバーとも呼ぶ)アーキテクチャのアプリケーションです。 このアーキテクチャでは、クライアントが関係するのは表示サービスだけです。 エージェント(すなわちアプリケーション・サーバー)は、クライアント・アプリケーションのアプリケーション・ロジックを処理します。 一般的には、この関係は多対 1の関係で、複数のクライアントが同一のアプリケーション・サーバーを共有します。

この場合のサーバー層は、Oracleデータベースです。 このアプリケーション・サーバー(エージェント)は、それぞれのスレッドがクライアント・アプリケーションに対してサービスを提供することから、マルチスレッド・アプリケーション・サーバーとして最適です。 Oracle環境では、このアプリケーション・サーバーは OCIプログラムまたはプリコンパイラ・プログラムです。

Page 189: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

スレッド・セーフティ

7-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

マルチスレッド開発の基本概念スレッドは大きなプロセス内に存在する軽量のプロセスです。 複数のスレッドで同一コードおよび同一データ・セグメントを共有しますが、プログラム・カウンタおよびマシン・レジスタ、スタックは、スレッドごとにあります。 グローバル変数および静的変数は、すべてのスレッドに共通です。そのため、1つのアプリケーション内で、複数のスレッドによるこれらの変数へのアクセスを管理する相互排他メカニズムが必要です。

スレッドは、一度作成されると他のスレッドとは非同期的に動作します。 このため、順序を気にしないで共通のデータ要素にアクセスし、OCIコールを実行できます。 このようにデータ要素に共有アクセスを行うので、複数のスレッドによってアクセスされるデータの整合性を維持するメカニズムが必要です。

データ・アクセスを管理するメカニズムでは、mutexes (相互排他ロック )のフォームを使用します。これにより、アプリケーションで共有リソースにアクセスする複数のスレッド間で、競合が発生しません。 Oracle8の OCIでは、相互排他ロックは、それぞれの環境ハンドルに基づくものとみなされます。

OCI 8.0でのスレッド・セーフティの実現Oracle8の OCIでスレッド・セーフティを利用するには、まずアプリケーションをスレッド・セーフなプラットフォーム上で実行する必要があります。 次に、アプリケーションはマルチスレッド・モードで実行されていることを、OCI_THREADEDを指定することで OCIレイヤーに知らせる必要があります。OCI_THREADEDは、OCIInitialize()のオープン・コールの modeパラメータで、OCIInitialize()は、アプリケーションで必ず最初にコールされるべき OCI関数です。

注意 : スレッド・セーフでないプラットフォームで実行するアプリケーションの場合は、OCI_THREADEDの値を OCIInitialize()に渡さないでください。

単一スレッド・アプリケーションの場合、プラットフォームがスレッド・セーフであるかどうかに関わらず、そのアプリケーションは、OCIInitialize()に OCI_DEFAULTを渡す必要があります。 単一スレッド・アプリケーションを OCI_THREADEDモードで実行すると、パフォーマンスが低下する可能性があります。

マルチスレッド・アプリケーションがスレッド・セーフなプラットフォーム上で動作している場合は、アプリケーションにかわって OCIライブラリが、環境ハンドル単位で相互排他ロックを管理します。 必要な場合は、アプリケーションでこの機能を上書きし、独自の相互排他ロックのスキームを採用することもできます。 これは、OCI_NO_MUTEXの値をOCIEnvInit()コールに指定すると実行されます。

想定されるのは、次の 3つのシナリオです。これらのシナリオは、環境ハンドルごとに存在する接続の数および接続ごとに作成されるスレッドの数によって変わります。

1. アプリケーションに複数の環境ハンドルがあっても、それぞれの環境ハンドルにつきスレッドが 1つ(環境ハンドル 1つにつき 1つのセッションが存在)しかない。相互排他ロックする必要はありません。

Page 190: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

スレッド・セーフティ

OCIプログラミングの応用 7-15

2. OCI_THREADEDモードで実行しているアプリケーションに複数の環境ハンドルがあり、それぞれの環境ハンドルに複数のスレッドを作成する接続が 1つある場合、次の方法の中から選択できます。

■ OCIEnvInit()でモードの値として OCI_NO_MUTEXを渡す。 この場合は、アプリケーション側で、同一環境ハンドルで独自に実行する OCIコールを相互排他ロックする必要があります。 この方法には、アプリケーションの設計に基づいて相互排他ロックのスキームを最適化できるという 利点があります。 この方法では、1つの環境ハンドル接続で必ず一度に 1つの OCIコールを処理するようにプログラミングする必要があります。

■ OCIEnvInit()に OCI_DEFAULTの値を渡す。 この場合は、OCIライブラリが、環境ハンドルの各 OCIコールに対して自動的に相互排他ロックを獲得します。

3. OCI_THREADEDモードで実行しているアプリケーションに 1つ以上の環境ハンドルがあり、それぞれの環境ハンドルに複数の接続がある場合は、次の方法の中から選択できます。

■ OCIEnvInit()でモードの値として OCI_NO_MUTEXを渡す。 この場合は、アプリケーション側で、同一環境ハンドルで実行する OCIコールを相互排他ロックする必要があります。 この方法には、アプリケーションの設計に基づいて相互排他ロックのスキームを最適化できるという 利点があります。 この方法では、1つの環境ハンドル接続で必ず一度に 1つの OCIコールを処理するようにプログラミングする必要があります。

■ OCIEnvInit()に OCI_DEFAULTの値を渡す。 この場合は、OCIライブラリが、環境ハンドルの各 OCIコールに対して自動的に相互排他ロックを獲得します。

ただし、この場合、注意する必要があるのは、アプリケーションが同一環境ハンドルで2つのコールを実行し、サーバー上で実行している 1つのコールが相互排他ロックされている場合です。相互排他ロックされたコールの実行時間が長いと、アプリケーションのパフォーマンスが低下し、サーバー接続が専有されます。

リリース 7.xおよびリリース 8.0の OCIコールの混合アプリケーションで 8.0と 7.xの OCIコールが混在し、またアプリケーションが、適切な8.0のコールを使用してスレッド・セーフとして初期化されている場合、スレッド・セーフティを達成するために opinit()をコールする必要はありません。 アプリケーションでは、後続の 7.xファンクション・コールで 7.xの動作を得ることができます。

Page 191: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

7-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

ランタイム・データ割当てとピース単位操作OCIを使用して、ピース単位の挿入と更新、およびピース単位のデータのフェッチができます。 また、配列の挿入または更新の場合は、バインド値の静的バインドのかわりに、OCIを使用して動的にデータを提供できます。 非常に大きな列は、小さなサイズのチャンク(かたまり)が連続したものとして 挿入または検索できます。これによって、クライアント側のメモリー所要量を最小限にできます。

個々のピースのサイズは、実行時にアプリケーションで決定します。 それぞれのピースは、他のピースと同サイズにすることも、違うサイズにすることもできます。

OCIのピース単位機能性は、文字列やバイナリ・データの膨大なブロックで操作を行う際に特に有効です(たとえば、LOB、LONG、LONG RAWデータなどを記憶するデータベースの列に関わる操作)。 ピース単位操作に有効なデータベースは、7-17ページの「ピース単位操作に有効なデータ型」を参照してください。

図 7–4は、挿入操作 (i1, i2, i3...in)を連続して行うことによって、データベース表に 1つのLONG列をピース単位で挿入しています。 この例では、挿入するピースのサイズは一定ではありません。

図 7–4 LONG列のピース単位の挿入

ピース単位操作は、次の 2通りの方法で実行できます。

i i i i1 2 3 n

. . .

Page 192: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

OCIプログラミングの応用 7-17

■ ポーリング・パラダイムに基づいてピース単位操作を実行するには、リリース 7.3で行ったように、OCIライブラリで提供されているコールを使用。

■ 必要な情報およびデータ・ブロックを提供するには、ユーザー定義のコールバック関数を使用。

OCIBindByPos()または OCIBindByName()コールの modeパラメータをOCI_DATA_AT_EXECに設定した場合は、OCIアプリケーションが、実行時に、INSERTまたは UPDATEのためのデータを動的に提供することを示します。

同様に、OCIDefineByPos()コールの modeパラメータを OCI_DYNAMIC_FETCHに設定した場合は、アプリケーションが、フェッチ時にデータを受け取るための割当てスペースを動的に提供することを示します。

どちらの場合でも、INSERTまたは UPDATE、FETCHのためのランタイム情報は、次の 2通りの方法のどちらかを使用して提供できます。それは、コールバック関数を使用する方法とピース単位操作を使用する方法です。 コールバックを使用するときはコールバックを登録するために、追加のバインド・コールまたは定義コールが必要です。

次項以降では、挿入および更新、フェッチのためのデータ割当てとピース単位操作に関する特有の情報について説明します。

注意 :⦆ピース単位操作は、SQL文だけでなく、PL/SQLブロックでも有効です。

ピース単位操作に有効なデータ型一部のデータ型だけが、ピース単位で操作できます。 次のデータ型は、OCIアプリケーションでピース単位のフェッチまたは挿入、更新を実行できます。

■ VARCHAR2

■ 文字列

■ LONG

■ LONG RAW

LOBおよび FILE操作の中にも、データの読み書きに対し、ピース単位セマンティクスを提供しているものがあります。 これらの操作の詳細は、13-109ページの OCILobWrite()および13-105ページの OCILobRead()の説明を参照してください。

すべてのデータ型に対してこの機能を使用する別な方法として、配列の挿入または更新のためにデータを動的に提供する方法があります。 ただし、ピース単位操作をサポートしないデータ型に対しては、コールバックで、そのコールバックの piecepパラメータのOCI_ONE_PIECEを常に指定する必要があります。

実行時の INSERTまたは UPDATEデータの提供OCIBindByPos()または OCIBindByName()コールで OCI_DATA_AT_EXECを指定する場合は、value_szパラメータで 実行時に提供できるデータのサイズの合計を定義します。 アプリケーションでは、実行時 INデータ・バッファを、要求に応じて操作完了に必要な回数だけ

Page 193: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

7-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCIライブラリに提供する用意をしておく必要があります。 割り当てたバッファが不要になった場合は、クライアント側で解放する必要があります。

実行時データは、次の 2つの方法のいずれかで提供されます。

■ 実行時にコールする場合、データのピースまたはデータ全体を戻す OCIBindDynamic()コールを使用して、コールバックを定義。

■ コールバックを 1つも定義していない場合は、SQL文を処理する OCIStmtExecute()コールは、OCI_NEED_DATAエラー・コードを戻す。 クライアント・アプリケーションは、次に OCIStmtSetPieceInfo()コールを使用して、IN/OUTデータ・バッファまたはピースを提供します。 OCIStmtGetPieceInfo()コールにより、どのバインドおよびピースが使用されているかについての情報が提供されます。

ピース単位挿入の実行OCI環境が初期化され、データベース接続およびセッションが確立すると、SQL文またはPL/SQL文を準備するコールと入力値をバインドするコールが実行され、ピース単位挿入が開始されます。 ユーザー定義のコールバックではなく、標準の OCIコールを使用するピース単位操作では、OCIBindDynamic()をコールする必要はありません。

注意 : ピース単位操作の一部でない文にある追加のバインド変数は、データ型に応じて、追加のバインド・コールが必要な場合があります。

準備およびバインドの文に従い、アプリケーションで OCIStmtExecute()およびOCIStmtGetPieceInfo()、OCIStmtSetPieceInfo()を連続してコールし、ピース単位操作を完了します。 それぞれの OCIStmtExecute()コールは、次にどの処理を実行するかを決定する値を戻します。 一般的には、アプリケーションで次のピースの挿入を指示する値を検索し、そのピースをバッファに移してから挿入を行います。 最後のピースを挿入すると操作は完了します。

挿入バッファは任意のサイズにすることができ、実行時に使用されることに留意してください。 また、挿入する各ピースは、同じサイズである必要はありません。 挿入するピースのサイズは、それぞれ OCIStmtSetPieceInfo()コールで設定します。

注意 : すべての挿入で同じサイズのピースが使用され、挿入されるデータのサイズがそのピースのサイズで均等に割り切れない場合は、挿入される最後のピースは、その前に挿入されたピースよりも小さくなります。 たとえば、10,050,036バイトの長さのデータの値を、それぞれ 500バイトの チャンクで挿入すると、最後に残るピースは 36バイトにしかなりません。 プログラマはこのことを考慮して、最後の OCIStmtSetPieceInfo()コールで小さいサイズを指定する必要があります。

次のステップは、ピース単位挿入に関する手順の概略です。 手順は、次のページ で図示しています。

ステップ 1⦆ OCI環境を初期化し、必要なハンドルを割り当て、サーバーに接続し、ユーザーを認証し、文の要求を準備する。 これらのステップに関しては 2-14ページの「OCIプログラミング・ステップ」で説明されています。

Page 194: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

OCIプログラミングの応用 7-19

ステップ 2⦆ OCIBindByName()または OCIBindByPos()を使用して、プレースホルダをバインドする。 ここでは、使用するピースそれぞれの実際のサイズを指定する必要はありません。実行時に提供するデータの全体のサイズを指定します。

7.x⦆アップグレードの注意 :⦆以前に obindps() および ogetpi() ルーチンの一部であったコンテキスト・ポインタは、リリース 8.0では存在しません。独自のコンテキストを提供したいクライアントでは、コールバック方法を使えます。

ステップ 3 OCIStmtExecute()の最初のコールを実行する。 この時点では、データは実際には挿入されていません。アプリケーションに OCI_NEED_DATAエラー・コードが戻されます。

その他の値が戻された場合は、エラーが起きたことを示しています。

ステップ 4 OCIStmtGetPieceInfo()をコールし、挿入する必要があるピースの情報を検索する。 OCIStmtGetPieceInfo()のパラメータの 1つに、必要なピースが先頭のピース(OCI_FIRST_PIECE)なのか、後続のピース (OCI_NEXT_PIECE)なのかを示す値を戻すポインタがあります。

ステップ 5 アプリケーションは、挿入するデータのピースをバッファに移し、CIStmtSetPieceInfo()をコールする。 OCIStmtSetPieceInfo()に渡されるパラメータの中には、ピースのポインタ、およびピースの長さのポインタ、このピースは最初のピースか(OCI_FIRST_PIECE)または中間のピースか (OCI_NEXT_PIECE)、最後のピースか(OCI_LAST_PIECE)を示す値が含まれます。

ステップ 6 再度 OCIStmtExecute()をコールする。 ステップ 5で OCI_LAST_PIECEが示され 、OCIStmtExecute()が OCI_SUCCESSを戻した場合は、すべてのピースが正常に挿入されています。 OCIStmtExecute()で OCI_NEED_DATAが戻された場合は、ステップ 3に戻り、次の挿入を行います。 OCIStmtExecute()がこれ以外の値を戻した場合は、エラーが発生します。

最後のピースを正常に挿入すると、ピース単位操作は完了します。 完了すると、最後のOCIStmtExecute()コールの戻り値が OCI_SUCCESSになります。

Page 195: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

7-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

図 7–5 ピース単位挿入実行の手順

ピース単位更新も同様の方法で実行します。 ピース単位更新操作では、挿入バッファに更新されるデータが移され、OCIStmtExecute()がコールされて更新を実行します。

注意 :⦆ピース単位操作に関するその他の重要な情報は、7-22ページの「コールバックなしのピース単位操作に関する追加情報」を参照してください。

PL/SQLでのピース単位操作OCIアプリケーションでは、前に概説した方法と似た方法で、INおよび OUT、IN/OUTバインド変数について、PL/SQLでのピース単位操作を実行できます。 PL/SQL文のすべてのプレースホルダは、定義ではなくバインドされることに注意してください。 OCIBindDynamic()のコールでは、OUTパラメータまたは IN/OUTパラメータについて、適切なコールバックを指定します。

実行時の FETCH情報の提供modeパラメータに OCI_DYNAMIC_FETCHを設定して OCIDefineByPos()をコールする場合は、アプリケーションでフェッチ時のデータ・バッファの情報を指定できます。 また、OCIDefineDynamic()をコールして、ユーザーのデータ・バッファに関する情報の取得時に呼び出されるコールバック関数を設定する必要がある場合があります。

実行時データは、次の 2つの方法のいずれかで提供されます。

■ OCIDefineDynamic()コールを使用してコールバックを定義。 実行時に提供されるデータの最大サイズは、value_szパラメータで指定します。 クライアント・ライブラリで、フェッチ済みデータを戻すためのバッファを必要とする場合は、コールバックを呼び出して、データのピースまたはデータ全体を戻すための実行時バッファを提供します。

■ コールバックが 1つも定義されていない場合は、OCI_NEED_DATAエラー・コードが戻り、クライアント・アプリケーションで OCIStmtSetPieceInfo()コールを使用して、

OCI_SUCCESS

Page 196: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

OCIプログラミングの応用 7-21

OUTデータ・バッファまたはピースを提供。 OCIStmtGetPieceInfo()コールにより、どの定義およびピースが含まれるかについての情報が提供されます。

関連項目 :⦆ピース単位操作に有効なデータ型については、7-17ページの「ピース単位操作に有効なデータ型」を参照してください。

ピース単位挿入の実行OCI環境が初期化され、データベース接続およびセッションが確立すると、SQL文またはPL/SQL文を準備するコールと出力変数を定義するコールが実行され、ピース単位操作が開始されます。 ユーザー定義のコールバックではなく、標準の OCIコールを使用するピース単位操作では、OCIDefineDynamic()をコールする必要はありません。

準備および定義の文に従い、アプリケーションで OCIStmtFetch()およびOCIStmtGetPieceInfo()、OCIStmtSetPieceInfo()を連続してコールし、ピース単位操作を完了します。 それぞれの OCIStmtFetch()コールは、次にどの処理を実行するかを決定する値を戻します。 一般的には、アプリケーションで次のピースのフェッチを指示する値を検索し、そのピースをバッファにフェッチします。 最後のピースをフェッチすると、操作は完了します。

フェッチ・バッファは、任意のサイズにできます。 また、フェッチする各ピースは、同じサイズである必要はありません。 ただし、最後にフェッチするサイズは、残っている最後のピースに一致するサイズでなければなりません。 フェッチするピースのサイズは、それぞれOCIStmtSetPieceInfo()コールで設定します。

次のステップは、ピース単位に行をフェッチする方法の概略です。

ステップ 1 OCI環境を初期化し、必要なハンドルを割り当て、データベースに接続し、ユーザーを認証し、文を準備し、文を実行する。 これらのステップについては、2-14ページで説明しています。

ステップ 2 modeを OCI_DYNAMIC_FETCHに設定し、OCIDefineByPos()を使用して出力変数を定義する。 この時点では、使用するピースそれぞれの実際のサイズを指定する必要はありません。実行時にフェッチするデータの全体のサイズを指定します。

7.x⦆アップグレードの注意 :⦆以前に obindps() および ogetpi() ルーチンの一部であったコンテキスト・ポインタは、リリース 8.0では存在しません。独自のコンテキストを提供したいクライアントでは、コールバック方法を使えます。

ステップ 3 OCIStmtFetch()を初回コールする。 この時点では、実際のデータは検索されません。アプリケーションに OCI_NEED_DATAエラー・コードが戻されます。

その他の値が戻された場合は、エラーが起きています。

ステップ 4 OCIStmtGetPieceInfo()をコールし、フェッチするピースの情報を取得する。 piecepパラメータは、そのピースが最初のピース (OCI_FIRST_PIECE)であるか、その後続のピース (OCI_NEXT_PIECE)であるか、最後のピース (OCI_LAST_PIECE)であるかを示します。

ステップ 5 OCIStmtSetPieceInfo()をコールし、ピースをフェッチするバッファを指定する。

Page 197: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ランタイム・データ割当てとピース単位操作

7-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

ステップ 6⦆ 再度 OCIStmtFetch()をコールし、実際のピースを検索する。 OCIStmtFetch()で OCI_SUCCESSが戻された場合は、すべてのピースが正常にフェッチされています。 OCIStmtFetch()で OCI_NEED_DATAが戻された場合は、ステップ 4に戻って次のピースを処理します。 その他の値が戻された場合は、エラーが起きています。

最後の OCIStmtFetch()が OCI_SUCCESSの値を戻すと、ピース単位フェッチが完了します。

図 7–6 ピース単位のフェッチを実行するステップ

コールバックなしのピース単位操作に関する追加情報ピース単位のフェッチおよび挿入では、操作を正常に完了するために必要なコールの順序を理解することが重要です。 特に、ピース単位挿入では、コールバックが使用されない場合、挿入するピースの数よりも 1回多く OCIStmtExecute()をコールする必要があります。 これは、最初の OCIStmtExecute()コールは、単に最初のピースを挿入する必要があることを示す値を戻すだけだからです。 結果として、n個のピースを挿入する場合、OCIStmtExecute()を合計 n+1回コールする必要があります。

同様に、ピース単位フェッチを実行するときは、フェッチするピースの数より 1回多くOCIStmtFetch()をコールする必要があります。

PL/SQL表をバインドする場合は、OCIStmtGetPieceInfo()コール時に、その表の現行の索引へのポインタを取り出せます。

OCI_SUCCESS

Page 198: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

OCIプログラミングの応用 7-23

LOBおよび FILE操作Oracle8 OCIには、データベース内のラージ・オブジェクト (LOB)で操作を実行するための一連の関数があります。 内部 LOB(BLOB、CLOB、NCLOB)は、データベースの表領域に、領域の最適化とアクセスの効率化を実現するように格納されます。 これらの LOBは、データベース・サーバーのトランザクションを完全にサポートしています。 外部 LOB(FILE)とは、データベース表領域の外のサーバーのオペレーティング・システム・ファイルに格納された大型のデータ・オブジェクトのことです。

LOBおよび FILEの最大長は、4GBです。

FILE機能は読込み専用です。 Oracle8 Serverでは、現在、バイナリ・ファイル (BFILE)だけをサポートしています。

関連項目 :⦆LOB操作の使用方法を示すコード・サンプルは、D-74ページの「例 5、CLOB/BLOB操作」および D-94ページの「例 6、LOBバッファリング」を参照してください。

LOBと併用するための dbms_lobパッケージに興味がある場合は、『Oracle8 Serverアプリケーション開発者ガイド』を参照してください。

LOBおよび LOBロケータデータベースの表には、LOB値を指す「LOBロケータ」が格納されます。 OCIアプリケーションで選択リストに LOB列を含む SQL問合せを発行した場合、問合せ結果のフェッチでは、実際の LOB値ではなくロケータが戻されます。 OCIでは、LOBロケータはOCILobLocatorデータ型にマッピングされます。

注意 :⦆LOB値は、約 4,000バイトより小さい場合、データベースの表にインラインで格納できます。

内部 LOBには、コピー・セマンティクスがあります。 そのため、ある列の LOBを別の列のLOBにコピーすると、実際の LOBの値がコピーされ、コピーされた LOBに対し、新規のLOBロケータが作成されます。

LOB用の OCI関数では、引数として LOBロケータを使用します。 LOBに値が含まれているかどうかに関係なく、OCI関数はロケータが指す LOBがすでに作成済みであるとみなします。

アプリケーションでは、最初に SQLを使用してロケータをフェッチし、次に、そのロケータを使用して操作の実行を続けます。 OCI関数が実際の LOB値をパラメータとして受け取ることはありません。 スナップショットが最新で LOBデータの現在の設定値である場合に限り、そのスナップショットが変更される現在の設定値なので、LOB修正コールでロケータを使用するのがよい方法となります。

記述子型として OCI_DTYPE_LOBを渡した OCIDescriptorAlloc()のコールを使用して、内部LOBロケータのメモリを割り当てます。 外部 LOB(FILE)ロケータのメモリを割り当てるには、OCI_DTYPE_FILEを渡します。

Page 199: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

7-24 Oracle8コール・インタフェース・プログラマーズ・ガイド

LOBロケータのメモリを割り当てたら、それを OCI LOBルーチンに渡す前に、初期化する必要があります。 以下の方法のどれでも、これを達成できます。

1. データベースから LOB(有効な LOBロケータを所有する )を、割り当てたばかりのLOBロケータに SELECTする。

2. SQL INSERTまたは UPDATE文の RETURNING句内のロケータを使う。

3. すでに初期化された別の LOBロケータを、新しく割当てられた LOBロケータに割り当てる。

あるいはロケータの OCI_ATTR_LOBEMPTY属性を OCIAttrSet()でコールして、LOBロケータを空にして初期化できます。 ただし、この方法で初期化されたロケータは、データベースに空の LOBを作成する場合にのみ使えます つまり、SQL INSERT文の VALUES句か、または SQL UPDATE文の SET句のソースとしてのみ使えます。

警告 :⦆ LOBおよび FILE操作のためのロケータは交換できません。 LOB操作のロケータは型 OCI_DTYPE_LOBとして、FILE操作のロケータは型 OCI_DTYPE_FILEとして割り当てる必要があります。 内部 LOBロケータを外部 LOB(FILE)ロケータに割り当てることはできません。この反対もできません。

関連項目 :⦆LOBロケータなど、ロケータの詳細は、2-11ページの「記述子およびロケータ」を参照してください。

OCIの LOBコールを使用したサンプル・コードは、付録 Bの例 3および 13-109ページの OCILobWrite() の説明を参照してください。

LOB、ロケータ、読込み整合性のある LOBの詳細は、『Oracle8 Serverアプリケーション開発者ガイド』を参照してください。

Page 200: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

OCIプログラミングの応用 7-25

FILEFILEロケータは、サーバーのファイル・システムにあるファイルのポインタとして見なされます。 Oracle8 Serverでは、FILEに関してトランザクション・セマンティクスを提供していません。また、Oracle8 Serverでは、バイナリ FILE(BFILE)に対する読込み専用操作だけを現在サポートしています。

内部 LOBの操作と FILEの操作は似ているので、OCIのすべての LOB関数および FILE関数では、すべての操作の入力として LOBロケータが予期されます。 唯一の違いは、FILEロケータを割り当てる方法です。 FILEのロケータを割り当てる場合、OCIDescriptorAlloc()コールで、記述子型として OCI_DTYPE_FILEを渡す必要があります。

警告 : LOBおよび FILE操作のためのロケータは交換できません。 LOB操作のロケータは型 OCI_DTYPE_LOBとして、FILE操作のロケータは型 OCI_DTYPE_FILEとして割り当てる必要があります。 内部 LOBロケータを外部 LOB(FILE)ロケータに割り当てることはできません。この反対もできません。

関連項目 :⦆BFILEと OSファイルの関連付けについては、7-25ページの「表内の FILEと OSファイルの関連付け」を参照してください。

内部 LOBの作成と変更内部 LOBを新規作成するには、OCIDescriptorAlloc()を使用して新規の LOBロケータを初期化してから、OCIAttrSet()をコールして (OCI_ATTR_LOBEMPTY属性を使用して )空に設定し、次に INSERT文でロケータをプレースホルダにバインドします。 この処理により、LOB列または属性がある表に空のロケータを挿入します。 次に、SELECT...FOR UPDATEでこの行を選択し、ロケータを入手します。その後、OCIの LOB関数を使用してロケータに書き込みます。

注意 :⦆LOB列または属性を変更(書込み、コピー、切捨て等)する場合は必ず LOBを含む行をロックする必要があります。 これを実行する方法の 1つは、操作を実行する前に SELECT...FOR UPDATE文を使用してロケータを選択します。

LOB書込みコマンドを正常に実行するには、トランザクションがオープンされた状態でなければなりません。 このため、データを書き込む前にトランザクションをコミットする場合、コミットによってトランザクションはクローズするため、たとえば、SELECT...FOR UPDATE文を再発行して、行を再ロックする必要があります。

注意 :⦆LOBの読込みと書込みは、トリガー内からはできません。

関連項目 :⦆LOBロケータのプレースホルダへのバインディング、およびそれらをINSERT文での使用方法については、5-9ページの「LOBのバインディング」を参照してください。

表内の FILEと OSファイルの関連付けBFILENAME()関数は、外部のサーバー側 (OS)ファイルと表内の BFILE列 /属性を関連付けるため、INSERT文で使用できます。 UPDATE文で BFILENAME()を使用すると、BFILE列または属性と、別の OSファイルを関連付けます。

Page 201: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

7-26 Oracle8コール・インタフェース・プログラマーズ・ガイド

関連項目 :⦆BFILENAME()関数については、『Oracle8 Serverアプリケーション開発者ガイド』を参照してください。

オブジェクトの LOB属性への書込みOCIを使って、LOB属性を持つ新規の持続的なオブジェクトを作成したり、その LOB属性への書込みができます。 アプリケーションでは次のステップに従います。

1. OCIObjectNew()をコールして、LOB属性を持つ持続的なオブジェクトを作成する。

2. オブジェクトをダーティとマークする。

3. 表に行を挿入して、オブジェクトをフラッシュする。

4. オブジェクトをデータベースから取り出し、LOBに有効なロケータを取得して、オブジェクトの最新バージョンを確保する(またはオブジェクトをリフレッシュする)。

5. オブジェクトの LOBロケータを使って OCILobWrite()をコールし、データを書込む。

マーク、フラッシュ、リフレッシュなど、オブジェクト操作の詳細は、第 8章の「OCIオブジェクト・リレーショナル・ プログラミング」を参照してください。

LOB属性を持つ一時オブジェクトアプリケーションでは、OCIObjectNew()をコールして、内部 LOB(BLOB 、CLOB、NCLOB)属性を持つ一時オブジェクトを作成できます。 ただし、一時 LOBは現在サポートされていないので、ユーザーが LOB属性で操作(読込みまたは書込み等)を実行することはできません。 一時内部 LOB型を作成するための OCIObjectNew()コールは失敗しませんが、アプリケーションでは、この一時 LOBで LOB操作を使用することはできません。

ただし、アプリケーションでは、FILE属性を持つ一時オブジェクトを作成し、FILE属性を使ってデータをサーバーのファイル・システムに記憶したファイルから読み込めます。 アプリケーションでは、OCIObjectNew()をコールして一時 FILEを作成し、その FILEでサーバーのファイルから読み込むことができます。

Page 202: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

OCIプログラミングの応用 7-27

LOBバッファリングOracle8 OCIでは、内部 LOB値の小さな読込みと書込みのために、次のように、LOBのバッファリングを制御するコールを提供します。

■ OCILobEnableBuffering()

■ OCILobDisableBuffering()

■ OCILobFlushBuffer()

これらの関数により、アプリケーションで内部 LOB (BLOB、CLOB、NCLOB)を使用して、クライアント側のバッファで LOBの小さな読込みと書込みをバッファできるので、パフォーマンスが改善されます。 これにより、ネットワーク往復の回数と LOBのバージョンを削減でき、小さな読込みと書込みについては、LOBのパフォーマンスが改善されます。

関連項目 :⦆LOBのバッファリングの詳細は、『Oracle8 Serverアプリケーション開発者ガイド』の LOBに関する章と、このガイドの付録 Dにある LOBバッファリングのコード・サンプルを参照してください。

LOBバッファリングの使用方法を示すコード・サンプルは、D-94ページの「例 6、LOBバッファリング」を参照してください。

LOB/FILE関数表 7–1の関数は、LOBおよび FILEで操作するために使用できます。 各関数に関する詳細は、第 13章で説明しています。

これらの LOBおよび FILEコールは、アプリケーションが Oracle7 Serverに接続している場合は無効です。

注意 :⦆データへのオフセットを伴うすべての LOB操作では、オフセットは 1から開始されます。BLOBおよび BFILEのオフセットと量はバイトで表します。 CLOBおよびNCLOBのオフセットとサイズは、文字数で換算されます。

Page 203: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

7-28 Oracle8コール・インタフェース・プログラマーズ・ガイド

関連項目 :⦆FILEの詳細は、『Oracle8 Serverアプリケーション開発者ガイド』の BFILEに関する説明を参照してください。

表 7–1 OCI LOB関数と FILE関数

関数 制限 用途

OCILobAppend() 内部 LOBのみ この関数は、ある内部 LOBのデータを別の内部 LOBに追加する。 追加元 LOBと 追加先 LOBは、すでに存在している必要があります。 新規に書き込むデータが追加先 LOBの現行の長さよりも大きい場合は、追加先 LOBは、そのデータに合わせて拡張されます。

追加先 LOBを最大長 (4GB)を超えて拡張したり、NULLである LOBから追加しようとすると、エラーになります。

OCILobAssign() LOB/FILEロケータを別のロケータに割り当てる。

OCILobCharSetForm() CLOB/NCLOBのキャラクタ・セット・フォームを入手する。

OCILobCharSetId() CLOB/NCLOBのキャラクタ・セット IDを入手する。

OCILobCopy() 内部 LOBのみ この関数は、内部 LOBの一部を別の内部 LOBにコピーする。 コピー元 LOBおよびコピー先 LOBは、すでに存在している必要があります。 データが宛先の開始位置にすでに存在する場合、ソース・データで上書きされます。

宛先の開始位置が現在の設定値の終了地点を越える場合は、宛先の設定値の終了地点から新たにソースから書込まれるデータの開始地点までの LOBに、0(ゼロ )バイト充てん文字 (BLOB)か空白 (CLOB/NCLOB)が配置されます。 新規に書き込むデータが追加先 LOBの現行の長さよりも大きい場合は、追加先 LOBは、そのデータに合わせて拡張されます。 コピー先 LOBを最大長 (4GB)を超えて拡張すると、エラーになります。

LOBのコピー操作は、同じ型の LOBSで実行されなければなりません。たとえば、ある CLOBは別の CLOBにコピーでき、ある BLOBは別の BLOBにコピーできますが、CLOBは BLOBにコピーできず、その反対もできません。

OCILobDisableBuffering() 内部 LOBのみ 指定の内部ロケータについて、LOBのバッファリングを使用禁止にする。

OCILobEnableBuffering() 内部 LOBのみ 指定の内部ロケータについて、LOBのバッファリングを使用可能にする。

Page 204: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

OCIプログラミングの応用 7-29

OCILobErase() 内部 LOBのみ 指定されたオフセットから始まる指定された部分を内部 LOB値から消去する。 実際に消去した文字数またはバイト数が戻ります。 要求した文字数またはバイト数を消去する前に LOBデータの終了位置を達すると、実際に消去した文字数またはバイト数と要求した文字数またはバイト数は異なる値になります。

LOBが NULLの場合、このルーチンは、0(ゼロ )文字 /バイトを消去したことを表示します。

OCILobFileClose(),OCILobFileCloseAll()

以前にオープンした FILEまたはオープンしているすべての FILEをクローズする。 内部 LOBに対してこの関数をコールするとエラーになります。 FILEが存在していてオープンしていないときは、エラーは戻りません。

OCILobFileExists() FILEがサーバー上に存在するかテストする。

OCILobFileGetName() FILEの名前とディレクトリ別名を入手する。

OCILobFileIsOpen() FILEが入力ロケータでオープンされているかどうかをテストする。

OCILobFileOpen() FILEをオープンする。 FILEは、読込み専用アクセス用にオープンできます。 この関数を内部 LOBに対してコールするとエラーになります。

OCILobFileSetName() FILEの名前とディレクトリ別名を設定する。

OCILobFlushBuffer() 内部 LOBのみ LOBのバッファをフラッシュする。

OCILobGetLength() この関数は、LOBまたは FILEの長さを入手する。 LOBまたは FILEが NULLの場合、長さは未定義です。 空の内部 LOBの長さは 0(ゼロ)です。

OCILobIsEqual() 2つの LOB/FILEロケータが等しいかテストする。 2つのロケータが等しいのは、両方のロケータが同じ LOB/FILE値を参照している場合だけです。

OCILobLoadFromFile() FILEからのデータを持つ LOBのすべてまたは一部を移入する。

OCILobLocatorIsInit() LOB/FILEロケータが初期化されているかテストする。

OCILobRead() この関数は、LOBまたは FILE値の一部をバッファへ読み込みます。 NULLの LOBまたは FILEから読み取るとエラーになります。

OCILobTrim() 内部 LOBのみ この関数は、LOBの値を指定された長さに短く切り詰めて、LOBの切捨てを行います。

OCILobWrite() 内部 LOBのみ この関数は、バッファのデータを内部 LOBに書き込みます。 データがすでに LOBの中に存在する場合は、バッファに記憶されていたデータによって上書きされます。

表 7–1 OCI LOB関数と FILE関数 (続き )

関数 制限 用途

Page 205: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

7-30 Oracle8コール・インタフェース・プログラマーズ・ガイド

LOB関数のサーバー往復個々の OCI LOB関数に必要なサーバー往復数を示す表は、付録 Eの「OCI関数のサーバー往復」を参照してください。

LOBの読込み /書込みコールバックOCI LOBの読込みと書込み関数により、書込みデータを提供したり読込みデータを処理するのに使用できるコールバック関数を定義します。これによって、クライアント・アプリケーションでは、データでオプション処理を実行できます。 この使用例としては、データを書き込むための圧縮アルゴリズムと、読み込むための圧縮解凍アルゴリズムを実現するコールバックの使用があげられます。

注意 :⦆ LOB読込み書込みストリーム転送コールバックは、大量の LOBデータの読込み書込みに使える高速な方法を提供します。

次の項では、コールバックの使用方法を詳しく説明します。

ストリーム転送のコールバック・インタフェース使用しているアプリケーションで、ユーザー定義の読込みおよび書込み用コールバック関数を使って、データを LOBへ挿入したり LOBから取り出したりできます。 データを LOBへストリーム転送したり、LOBからデータを取り出すためのポーリング方法に代わる方法を提供します。 ユーザー定義のコールバックには、以下に説明する特定のプロトタイプがあります。 これらの関数はユーザーがインプリメントし、OCILobRead() コールおよび OCILobWrite() コールを通じて OCIに登録します。 コールバック関数は、必要に応じて OCIでコールします。

Page 206: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

OCIプログラミングの応用 7-31

コールバックを使用して LOBを読込むユーザー定義の読込みコールバック関数は、OCILobRead()関数を通じて登録されます。 コールバック関数には次のプロトタイプが必要です。

<CallbackFunctionName> ( dvoid *ctxp, CONST dvoid *bufp, ub4 len, ub1 piece)

最初のパラメータ、ctxpはコールバックのコンテキストで、OCILobRead()関数コールで OCIに渡されます。 コールバック関数がコールされると、ctxpでユーザーが提供する情報はユーザーに戻されます (OCIが INの途中でこの情報を使うことはありません )。 bufp パラメータは、LOBデータが戻される格納場所へのポインタで、buflはこのバッファの長さを表します。 これで、ユーザーが提供するバッファに読み込まれたデータの量を伝えます。

元の OCILobRead()コールでユーザーが提供したバッファの長さが、サーバーから戻されるデータをすべて格納するのに十分でない場合は、ユーザー定義コールバックがコールされます。 この場合、pieceパラメータで、バッファに戻された情報が最初、後続、最後のどのピースであるかをユーザーに示します。

次に、読込みコールバック関数の実現に使われる一般的なコードの一部を示します。

ここでは loblを前もって選択された有効なロケータと想定します。svchpは有効なサービス・ハンドルで、errhpは有効なエラー・ハンドルです。

...ub4 offset = 1;ub4 loblen = 0;ub1 bufp[MAXBUFLEN];ub4 amtp = 0;

sword retval;

amtp = 4294967295; /* 4 gigabytes */

if (retval = OCILobRead(svchp, errhp, lobl, &amtp, offset, (dvoid *) bufp, (ub4) MAXBUFLEN, (dvoid *) bufp, cbk_read_lob, (ub2) 0, (ub1) SQLCS_IMPLICIT)) { (void) printf("ERROR: OCILobRead() LOB.\n"); report_error(); }...sb4 cbk_read_lob(ctxp, bufxp, lenp, piece)dvoid *ctxp;CONST dvoid *bufxp;ub4 lenp;ub1 piece;

{static ub4 piece_count = 0;

Page 207: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

7-32 Oracle8コール・インタフェース・プログラマーズ・ガイド

piece_count++;

switch (piece){ case OCI_LAST_PIECE:

/* process buffer bufxp */ --- buffer processing code goes here --- (void) printf("callback read the %d th piece\n\n", piece_count);

piece_count = 0;

break;

case OCI_FIRST_PIECE: case OCI_NEXT_PIECE:

/* process buffer bufxp */ --- buffer processing code goes here --- (void) printf("callback read the %d th piece\n", piece_count);

break;

default:

(void) printf("callback read error: unkown piece = %d.\n", piece);

return OCI_ERROR; } return OCI_CONTINUE;}

上記の例では、すべての LOBデータをユーザーが読み込むまで、ユーザー定義関数、cbk_read_lobが繰り返しコールされます。

コールバックを使用して LOBを書込む読込みコールバックと同様に、ユーザー定義コールバック関数が OCILobWrite()関数を通じて登録されます。 コールバック関数には次のプロトタイプが必要です。

<CallbackFunctionName> ( dvoid *ctxp, dvoid *bufp, ub4 *len, ub1 *piece)

最初のパラメータ、ctxpはコールバックのコンテキストで、OCILobWrite()ファンクション・コールで OCIに渡されます。 コールバック関数がコールされると、ctxpでユーザーが提供す

Page 208: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

LOBおよび FILE操作

OCIプログラミングの応用 7-33

る情報はユーザーに戻されます (OCIが INの途中でこの情報を使うことはありません )。 bufp パラメータは、挿入する LOBデータが含まれる格納領域へのポインタで、buflはこの格納領域の長さを表します。 ユーザーは、コールでこのポインタを OCILobWrite()に提供します。 コールで提供するデータを OCILobWrite()に挿入後も、書込むその他のデータが存在する場合は、ユーザー定義コールバックがコールされます。 コールバックで、ユーザーはbufpで示す格納領域の挿入データを提供し、またその長さを buflに指定します。 ユーザーはまた pieceパラメータを使って、後続のピース (OCI_NEXT_PIECE)か最後のピース(OCI_LAST_PIECE)かを示します。 アプリケーションで提供する格納領域ポインタに対する全責任はユーザーにあるため、割当てられた格納領域のサイズ以上書込まないように注意してください。

次に、書込みコールバック関数の実現に使われる一般的なコードの一部を示します。

ここでは loblを更新用にロックされた有効なロケータと想定します。svchpは有効なサービス・ハンドルで、errhpは有効なエラー・ハンドルです。

...

ub4 offset = 1;ub1 bufp[MAXBUFLEN];ub4 amtp = MAXBUFLEN * 20;ub4 nbytes = MAXBUFLEN;

/* Fill bufp with some data */

-- code to fill bufp with data goes here. nbytes should reflect the size and should be less than or equal to MAXBUFLEN --

if (retval = OCILobWrite(svchp, errhp, lobl, &amtp, offset, (dvoid*) bufp,(ub4)nbytes, OCI_FIRST_PIECE, (dvoid *)0, cbk_write_lob, (ub2) 0, (ub1) SQLCS_IMPLICIT))

{ (void) printf("ERROR: OCILobWrite().\n"); report_error(); return; } ...

sb4 cbk_write_lob(ctxp, bufxp, lenp, piece)dvoid *ctxp;dvoid *bufxp;ub4 *lenp;ub1 *piece;

{ /* Fill bufxp with data */

Page 209: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

外部プロシージャからの OCIコールバック

7-34 Oracle8コール・インタフェース・プログラマーズ・ガイド

-- code to fill bufxp with data goes here. *lenp should reflect the size and should be less than or equal to MAXBUFLEN --

if (this is the last data buffer)

*piecep = OCI_LAST_PIECE;

else

*piecep = OCI_NEXT_PIECE;;

return OCI_CONTINUE;}

上記の例では、アプリケーションで最後のピースを提供中であることを、piecepパラメータを使って示すまでは、ユーザー定義関数 cbk_write_lobが繰り返しコールされます。

外部プロシージャからの OCIコールバック外部プロシージャからのコールバックとして使用できる OCI関数は 4つあります。 これらの関数は、第 16章の「OCI外部プロシージャ関数」にリストされています。

PL/SQLコードからコールできる Cサブルーチンの作成については、使用できる OCIコールのリストとサンプル・コードも含めて、『PL/SQL ユーザーズ・ガイドおよびリファレンス』を参照してください。

Page 210: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

アプリケーション・フェイルオーバー・コールバック

OCIプログラミングの応用 7-35

アプリケーション・フェイルオーバー・コールバックアプリケーション・フェイルオーバー・コールバックは、あるデータベースのインスタンスで故障が発生し、別のインスタンスへフェイルオーバーする場合に使用できます。 フェイルオーバー中に遅延が発生する場合があるため、アプリケーションの開発者は、フェイルオーバーが進行中であることをユーザーに知らせ、ユーザーに待機するように要求する必要がある場合があります。 さらに、最初のインスタンスのセッションで、いくつかの ALTER SESSIONコマンドを受け取る可能性もあります。 これらが、2番目のインスタンスで自動的に再実行されることはありません。 したがって、開発者は、これらの ALTER SESSIONコマンドを 2番目のインスタンスでも再実行したいと考える可能性があります。

注意 :⦆アプリケーション・フェイルオーバーを利用するには、パラレル・サーバー・オプション付きの Oracle8 Enterprise Editionを使用する必要があります。

関連項目 :⦆アプリケーション・フェイルオーバーの詳細は、『Oracle8 Parallel Server 概要および管理』 マニュアルを参照してください。

フェイルオーバー・コールバックの概要前述の問題を処理するために、アプリケーションの開発者は、フェイルオーバー・コールバック関数を登録できます。 フェイルオーバーが発生した場合、コールバック関数は、ユーザー・セッションを再確立する過程で数回呼び出されます。

コールバック関数が最初にコールされるのは、Oracleがインスタンスの接続中断を最初に検出したときです。 このコールバックは、アプリケーションがユーザーに対して遅延の発生を通知することを目的にしています。 フェイルオーバーが正常終了すると、コールバック関数の 2番目のコールは、接続が再確立して使用可能になったときに発生します。 このとき、クライアントで ALTER SESSIONコマンドを再実行し、ユーザーにフェイルオーバーが発生したことを通知したい場合があります。 フェイルオーバーが異常終了した場合、コールバックは、フェイルオーバーが発生しなかったことをアプリケーションに通知するためにコールされます。 さらに、1次ハンドル以外のユーザー・ハンドルが新しい接続で再認証されるたびに、コールバックがコールされます。 各ユーザー・ハンドルはサーバー側セッションを表すので、クライアントでは、そのセッションのために ALTER SESSIONコマンドを再実行する場合があります。

フェイルオーバー・コールバック構造およびパラメータユーザー定義のアプリケーション・フェイルオーバー・コールバック関数の基本的な構造は次のとおりです。

sb4 callback_fn ( dvoid * svchp, dvoid * envhp, dvoid * fo_ctx, ub4 fo_type, ub4 fo_event );

Page 211: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

アプリケーション・フェイルオーバー・コールバック

7-36 Oracle8コール・インタフェース・プログラマーズ・ガイド

各パラメータは以下に説明されており、その例は 7-37ページの「フェイルオーバー・コールバックの例」に提供されています。

svchp 最初のパラメータの svchpは、サービス・コンテキスト・ハンドルです。 このパラメータは型 dvoid *です。

envhp 2番目のパラメータの envhpは、OCI環境ハンドルです。 このパラメータは型 dvoid *です。

fo_ctx 3番目のパラメータの fo_ctxは、クライアント・コンテキストです。 このパラメータは、クライアントが指定するメモリーを指すポインタです。 この領域には、クライアントが必要な状態またはコンテキストを保管できます。 dvoid *として渡されます。

fo_type 4番目のパラメータの fo_typeは、フェイルオーバーの種類です。 このパラメータにより、クライアントが要求したフェイルオーバーの種類をコールバックが判断できます。 通常の値は次のとおりです。

■ OCI_FO_SESSION。ユーザーがセッションのフェイルオーバーだけを要求したことを示します。

■ OCI_FO_SELECT。ユーザーが選択フェイルオーバーも要求したことを示します。

fo_event 最後のパラメータは、フェイルオーバーのイベントです。 このパラメータは、コールバックがコールされた理由を示します。 次の値をとることができます。

■ OCI_FO_BEGIN。フェイルオーバーが中断した接続を検出し、フェイルオーバーが開始することを示す。

■ OCI_FO_END。フェイルオーバーが正常終了したことを示す。

■ OCI_FO_ABORT。フェイルオーバーが異常終了したことを示す。

■ OCI_FO_REAUTH。ユーザー・ハンドルが再認証されたことを示す。 どのユーザー・ハンドルかを調べるために、アプリケーションで、最初のパラメータであるサービス・コンテキスト・ハンドルの OCI_ATTR_SESSION属性をチェックする必要があります。

フェイルオーバー・コールバックの登録フェイルオーバー・コールバックを使用するには、それをサーバー・コンテキスト・ハンドルに登録する必要があります。 この登録は、コールバック定義構造体を作成し、サーバー・ハンドルの OCI_ATTR_FOCBK属性にこの構造体を設定することにより行います。 コールバック定義構造体は、OCIFocbkStruct型でなければなりません。 これにはフィールドが 2つあります。 1つは callback_functionで、コールする関数のアドレスが含まれ、もう 1つはfo_ctx で、クライアント・コンテキストのアドレスが含まれます。

コールバック登録の例は、次の項にある例の一部に含まれています。

Page 212: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

アプリケーション・フェイルオーバー・コールバック

OCIプログラミングの応用 7-37

フェイルオーバー・コールバックの例次のコード例は、単純なユーザー定義コールバック関数の定義と登録を示しています。

パート 1 、フェイルオーバー・コールバックの定義sb4 callback_fn(svchp, envhp, fo_ctx, fo_type, fo_event )dvoid * svchp;dvoid * envhp;dvoid *fo_ctx;ub4 fo_type;ub4 fo_event;{switch (fo_event) { case OCI_FO_BEGIN: { printf(" Failing Over ... Please stand by \n"); printf(" Failover type was found to be %s \n", ((fo_type==OCI_FO_SESSION) ? "SESSION" :(fo_type==OCI_FO_SELECT) ? "SELECT" : "UNKNOWN!")); printf(" Failover Context is :%s\n", (fo_ctx?(char *)fo_ctx:"NULL POINTER!")); break; } case OCI_FO_ABORT: { printf(" Failover aborted. Failover will not take place.\n"); break; } case OCI_FO_END: { printf(" Failover ended ...resuming services\n"); break; } case OCI_FO_REAUTH: { printf(" Failed over user. Resuming services\n"); break; } default: { printf("Bad Failover Event: %d.\n", fo_event); return -20000; /* error -should not have happened */ } }

Page 213: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

アプリケーション・フェイルオーバー・コールバック

7-38 Oracle8コール・インタフェース・プログラマーズ・ガイド

return 0;}

パート 2 、フェイルオーバー・コールバックの登録int register_callback(svrh, errh)dvoid *svrh;/* the server handle */OCIError *errh; /* the error handle */{ OCIFocbkStruct failover; /* failover callback structure */

/* allocate memory for context */ if (!(failover.fo_ctx = (dvoid *)malloc(strlen("my context.")))) return(1); /* initialize the context. */ strcpy((char *)failover.context_function, "my context.");

failover.callback_function = &callback_fn;

/* do the registration */ if (OCIAttrSet(srvh, (ub4) OCI_HTYPE_SRV, (dvoid *) &failover, (ub4) 0, (ub4) OCI_ATTR_FOCBK, errh) != OCI_SUCCESS) return(2);

/* successful conclusion */ return (0);}

Page 214: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIおよびアドバンスト・キューイング

OCIプログラミングの応用 7-39

OCIおよびアドバンスト・キューイングOCIでは、Oracle8 Serverのアドバンスト・キューイング機能へのインタフェースを提供します。 Oracle AQは、Oracle Serverの統合された一部としてメッセージ・キューイングを提供します。 Oracle AQは、キューイング・システムをデータベースと統合させ、メッセージ使用可能データベースを作成することにより、この機能性を提供しています。統合された解決策を提供することにより、Oracle AQは、自由に特定のビジネス・ロジックに貢献できるよう、メッセージ・インフラストラクチャの構築からアプリケーション開発者を開放しました。

注意 :⦆アドバンスト・キューイングを使用するには、Oracle8 Enterprise Editionが必要です。 AQを RAWの代わりにデータ型のキューで使うには、オブジェクト・オプションも購入していなければなりません。

関連項目 :⦆概念、機能、例など AQの詳細は、『Oracle8 Serverアプリケーション開発者ガイド』のアドバンスト・キューイングの章を参照してください。

AQとの OCIの使用方法を示すコード・サンプルは、13-11ページの OCIAQEnq().の説明を参照してください。

OCIアドバンスト・キューイング関数OCIライブラリには、アドバンスト •キューイングに関して次の 2つの関数が含まれています。

■ OCIAQEnq()

■ OCIAQDeq()

第 13章の「OCIリレーショナル関数」に、これらの関数およびパラメータについてすべて説明されています。

OCIアドバンスト・キューイングの説明次の記述子が OCI AQ操作に使われます。

■ OCIAQEnqOptions - dbms_aq.enqueue_options_tと等価

■ OCIAQDeqOptions - dbms_aq.dequeue_options_tと等価

■ OCIAQMsgProperties - equivalent to dbms_aq.message_properties_tと等価

■ OCIAQAgent - sys.aq$_agentと等価

標準 OCIDescriptorAlloc()コールを使って、サービス・ハンドルに関するこれらの記述子を割り当てられます。 次のコードでこの例を示します。

OCIDescriptorAlloc(svch, &enqueue_options, OCI_DTYPE_AQENQ_OPTIONS, 0, 0 ); OCIDescriptorAlloc(svch, &dequeue_options, OCI_DTYPE_AQDEQ_OPTIONS, 0, 0 ); OCIDescriptorAlloc(svch, &message_properties, OCI_DTYPE_AQMSG_PROPERTIES, 0, 0);OCIDescriptorAlloc(svch, &agent, OCI_DTYPE_AQAGENT, 0, 0 );

Page 215: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIおよびアドバンスト・キューイング

7-40 Oracle8コール・インタフェース・プログラマーズ・ガイド

その他の OCI記述子と同様に、記述子の構造体はユーザーには不明確になっています。 各記述子には、設定または読込み(あるいはその両方)ができる、さまざまな属性が含まれます。 これらの属性については、B-28ページの「アドバンスト・キューイング記述子の属性」で詳しく説明しています。

OCIのアドバンスト・キューイング対 PL/SQL次の表は、OCI AQ関数および記述子の関数、パラメータ、オプションと、dbms_aqパッケージの PL/SQL AQ関数との比較を表します。

PL/SQL関数 OCI関数

DBMS_AQ.ENQUEUE OCIAQEnq()

DBMS_AQ.DEQUEUE OCIAQDeq()

DBMS_AQ.ENQUEUEパラメータ OCIAQEnq()パラメータ

queue_name queue_name

enqueue_options enqueue_options

message_properties message_properties

payload payload

msgid msgid

注意 :⦆OCIAQEnq()には、その他のパラメータとして、 svchおよび errh、payload_tdo、payload_ind、flagsも必要です。

DBMS_AQ.DEQUEUEパラメータ OCIAQDeq()パラメータ

queue_name queue_name

dequeue_options dequeue_options

message_properties message_properties

payload payload

msgid msgid

注意 : OCIAQDeq()には、その他のパラメータとして、 svchおよび errh、payload_tdo、payload_ind、flagsも必要です。

Page 216: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIおよびアドバンスト・キューイング

OCIプログラミングの応用 7-41

PL/SQL Agentパラメータ OCIAQAgent属性

name OCI_ATTR_AGENT_NAME

address OCI_ATTR_AGENT_ADDRESS

protocol OCI_ATTR_AGENT_PROTOCOL

PL/SQLメッセージ・プロパティ OCIAQMsgProperties属性

priority OCI_ATTR_PRIORITY

delay OCI_ATTR_DELAY

expiration OCI_ATTR_EXPIRATION

correlation OCI_ATTR_CORRELATION

attempts OCI_ATTR_ATTEMPTS

recipient_list OCI_ATTR_RECIPIENT_LIST

exception_queue OCI_ATTR_EXCEPTION_QUEUE

enqueue_time OCI_ATTR_ENQ_TIME

state OCI_ATTR_MSG_STATE

PL/SQLエンキュー・オプション OCIAQEnqOptions属性

visibility OCI_ATTR_VISIBILITY

relative_msgid OCI_ATTR_RELATIVE_MSGID

sequence_deviation OCI_ATTR_SEQUENCE_DEVIATION

Page 217: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle Security Servicesアプリケーションの作成

7-42 Oracle8コール・インタフェース・プログラマーズ・ガイド

Oracle Security Servicesアプリケーションの作成Oracle Security Services Toolkitを使用して Cアプリケーションを作成する方法については、『Oracle Security Serverガイド』を参照してください。

PL/SQL Dequeue Option OCIAQDeqOptions属性

consumer_name OCI_ATTR_CONSUMER_NAME

dequeue_mode OCI_ATTR_DEQ_MODE

navigation OCI_ATTR_NAVIGATION

visibility OCI_ATTR_VISIBILITY

wait OCI_ATTR_WAIT

msgid OCI_ATTR_DEQ_MSGID

correlation OCI_ATTR_CORRELATION

Page 218: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

第 2部 OCIオブジェクトの概念

このガイドの第 2部は、OCIでの Oracle8オブジェクトの使用方法について説明している章で構成されています。

■ 第 8章の「OCIオブジェクト・リレーショナル・ プログラミング」では、OCIでのオブジェクトの概念とプロジェクト リレーショナル プログラミングについて紹介します。

■ 第 9章の「オブジェクト・リレーショナル・データ型」では、オブジェクト・ データ型と、データベース・オブジェクトを C構造体で表す方法について説明します。また、データ型をマッピングし操作する OCI関数についても説明します。

■ 第 10章の「オブジェクト・アプリケーションでのバインディングおよび定義」では、オブジェクト・リレーショナル・データ型のバインディングと定義について説明します。

■ 第 11章の「オブジェクトのキャッシュおよびオブジェクト・ナビゲーション」では、オブジェクト・キャッシュと、オブジェクトでのナビゲート方法について説明します。

■ 第 12章の「オブジェクト型トランスレータの使用」では、OTTを使用して、データベース型定義をホスト言語表現に変換する方法について説明します。

注意 :⦆マニュアルのこの部分で説明する機能性は、オブジェクト・オプション付きのOracle8 Enterprise Editionを購入した場合にのみ使用できます。

Page 219: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・リレーショナル・ プログラミング 8-1

8OCIオブジェクト・リレーショナル・

プログラミング

この章では、オブジェクトを Oracle8 Serverで操作するための OCIの機能を紹介します。 また、OCIのオブジェクト・ナビゲーショナル・ファンクション・コールについても説明します。

この章は、次のトピックで構成されています。

■ 章の概要

■ OCIオブジェクトの概要

■ OCIでのオブジェクトの操作

■ OCIオブジェクト・アプリケーションの開発

注意 : この章で説明されている機能は、オブジェクト・オプションのある Oracle8 Enterprise Editionを購入された場合にのみ使用可能です。

Page 220: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

章の概要

8-2 Oracle8 コール・インタフェース・プログラマーズ・ガイド

章の概要この章は 3つに分かれており、Oracle8のオブジェクトを操作する OCIアプリケーションの作成も含めた基本的な概念を説明します。 OCIナビゲーショナル・ファンクション・コールについても説明します。

次の項目があります。

■ OCIオブジェクトの概要では、オブジェクトを操作するための OCIの機能に関する概略を簡単に説明します。

■ OCIでのオブジェクトの操作では、OCIオブジェクトアプリケーションの基本的な構造体と、OCIで操作できるオブジェクトの種類について説明します。 この項目の内容は、その後ほ章の内容の基礎になります。

■ OCIオブジェクト・アプリケーションの開発では、OCIオブジェクト・アプリケーションの主な要素について、詳細に説明します。 ここでは、簡単な例をあげて重要な点を説明します。

これに続く 4つの章には、OCIを使用したオブジェクト操作についての追加情報が記載されています。

■ 第 9章の「オブジェクト・リレーショナル・データ型」,では、OCIオブジェクト・リレーショナル・アプリケーションで使うデータ型について説明します。この情報は、第3章の「データ型」の補足です。OCIデータ型マッピングおよび操作関数についても説明します。

■ 第 10章の「オブジェクト・アプリケーションでのバインディングおよび定義」では、オブジェクト・リレーショナル・データ型に特有な操作のバインドおよび定義について説明します。この情報は、第 2章の「OCIプログラミングの基本」および第 5章の「バインディングと定義」の補足です。

■ 第 11章の「オブジェクトのキャッシュおよびオブジェクト・ナビゲーション」では、オブジェクト・キャッシュおよびオブジェクト・ナビゲーションについて説明します。OCIナビゲーショナル関数についても説明します。

■ 第 12章の「オブジェクト型トランスレータの使用」では、オブジェクト型トランスレータについて説明します。

OCIリレーショナル・ファンクションのすべてに関する説明は、第 14章の「OCIナビゲーショナル関数と型関数」および第 15章の「OCIデータ型マッピング関数および操作関数」にあります。その他に、一部のオブジェクト機能は、第 13章の「OCIリレーショナル関数」の関数の節で説明されています。

OCIオブジェクトの概要Oracleコール・インタフェース (OCI)には、データベース・アクセス管理および SQL文処理のための一連の関数があります。 これらの関数の詳細は、このマニュアルの第 1部に記載されています。 OCIリレーショナル・インタフェースの SQL機能によって、アプリケーションで SQL文を使用して、Oracle8 Serverのオブジェクトにアクセスできます。

Page 221: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクトの概要

OCIオブジェクト・リレーショナル・ プログラミング 8-3

注意 : Oracle8 OCIライブラリは、C向けにのみサポートされています。

OCIでは、アプリケーションからスカラー値、コレクション、任意のオブジェクト型のインスタンスなど、Oracle8 Server内のすべてのデータ型にアクセスできます。 次のデータ型があります。

■ オブジェクト

■ 可変長配列 (VARRAY)

■ ネストした表(多重集合)

■ 参照 (REF)

■ LOB

Oracle8 Serverのオブジェクト機能を十分に活用するには、ほとんどのアプリケーションでは単にオブジェクトにアクセスするだけでは十分ではありません。 アプリケーションでは、オブジェクトを検索した後、そのオブジェクトから他のオブジェクトへ参照を通してナビゲートする必要があります。 OCIはそのための機能を提供します。

OCIオブジェクトのナビゲーショナル・コールを通じて、アプリケーションで次のすべての機能を Oracle8オブジェクトで実行できます。

■ オブジェクトを作成およびアクセス、ロック、削除、コピー、フラッシュする

■ オブジェクトとそのメタ・オブジェクトの参照を入手する

■ オブジェクト属性の値を動的に取得したり設定する

OCIナビゲーショナル・コールについては、この章の後半で詳しく説明します。

また、OCIでは、Oracle8のデータベースに格納されている型情報にアクセスする機能も備えています。 アプリケーションでは、OCIDescribeAny()関数を使用して、データベースに格納されている型に関するほとんどの情報(メソッド、属性、型メタデータなど)にアクセスできます。

OCIDescribeAny()は、第 6章の「スキーマ・メタデータの記述」で説明します。

Oracle8オブジェクトを操作するアプリケーションでは、オブジェクトをホスト言語形式で表現する手段が必要です。 Oracle8には、オブジェクト型トランスレータ (OTT)というユーティリティがあり、それを使用してデータベース内の型定義を Cの構造体宣言に変換できます。 宣言はヘッダー・ファイルに格納され、それを OCIアプリケーションに組み込むことができます。

型定義が Cで表されると、属性の型は、Oracle8の新しい特殊な C変数型にマップされます。OCIには、一組のデータ型マップおよび操作関数が含まれ、アプリケーションでこれらのデータ型を操作したりオブジェクトの属性を操作できます。 これらの関数については、第9章の「オブジェクト・リレーショナル・データ型」で詳しく説明します。

オブジェクトに関する用語は混同することがあります。 この章では、これ以降、「オブジェクト」と「インスタンス」という用語は両方とも、データベースに格納されたオブジェクトか、またはオブジェクト・キャッシュにあるオブジェクトを参照します。

Page 222: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでのオブジェクトの操作

8-4 Oracle8 コール・インタフェース・プログラマーズ・ガイド

OCIでのオブジェクトの操作第 2章から第 6章で説明したリレーショナル OCIアプリケーションに関するプログラミング原則の多くは、オブジェクト・リレーショナル・アプリケーションにも適用されます。 オブジェクト・リレーショナル・アプリケーションでは、標準 OCIコールを使用してデータベース接続を確立し、SQL文を処理します。 その違いは、発行される SQL文はオブジェクト・リファレンスを取り出し(または値ごとのオブジェクト)、その後に OCIのオブジェクト・ファンクションで操作することです。

基本的なオブジェクト・プログラム構造体オブジェクトを使う OCIアプリケーションの基本的な構造体は、本質的にはリレーショナルOCIアプリケーションと同じで、これについては 2-2ページの「OCIプログラム構造」で説明しています。ここでは、基本的なオブジェクト機能についての追加情報とともに、そのモデルをもう一度示します。

1. OCIプログラミング環境を初期化する。

注意 : 環境はオブジェクト・モードで初期化しなければなりません。

また、アプリケーションでは通常、ヘッダー・ファイルからデータベース・オブジェクトの C構造体の表現を組み込む必要があります。 これらの構造体はプログラマが作成するか、またはより簡単な方法としては、第 12章の「オブジェクト型トランスレータの使用」で説明するように、、オブジェクト型トランスレータ (OTT)でも生成できます。

2. 必要なハンドルを割り当て、サーバーとの接続を確立する。

3. SQL文を準備して実行する。 これは、ローカル(クライアント側)ステッ プで、プレースホルダのバインドと出力変数の定義を行います。 オブジェクト・リレーショナル・アプリケーションの場合、この SQL文はオブジェクトへの参照 (REF)を戻します。

注意 : オブジェクトを参照 (REF)するだけでなく、オブジェクト全体をフェッチすることもできます。 参照可能なオブジェクトを選択する場合、それを確保するのではなく、オブジェクトを「値渡し」で取得します。8-14ページの「埋込みオブジェクトのフェッチ」で説明するとおり、交互に参照可能でないオブジェクトを選択できます。

4. 準備した文をデータベース・サーバーに関連付けて実行する。

5. 戻された結果をフェッチする。

オブジェクト・リレーショナル・アプリケーションでは、このステップで、REFを検索し、参照するオブジェクトを確保します。 オブジェクトを確保した後、次の一部またはすべてを実行します。

– オブジェクトの属性を操作し、それを「ダーティ」とマークする

– 別の 1個のオブジェクト、または一連のオブジェクトへの REFをたどる

– 型および属性の情報にアクセスする

– 複合オブジェクト検索グラフをナビゲートする

Page 223: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでのオブジェクトの操作

OCIオブジェクト・リレーショナル・ プログラミング 8-5

– 変更したオブジェクトをサーバーにフラッシュする

6. トランザクションをコミットする。 このステップでは、暗黙的に、変更されたすべてのオブジェクトをサーバーにフラッシュし、変更をコミットします。

7. 再利用しない文とハンドルを解放するか、準備した文を再実行する。

この章の後の項目で、すべてのステップを詳しく説明します。

関連項目 : OCIを使用したサーバーへの接続および SQL文の処理、ハンドルの割当ての詳細は、第 2章、および第 13章にある OCIリレーショナル・ファンクションの説明を参照してください。

OTTに関する情報は、8-7ページの「オブジェクトの Cアプリケーションでの表現」および第 12章の「オブジェクト型トランスレータの使用」を参照してください。

永続オブジェクトおよび一時オブジェクト、値Oracle8の型のインスタンスは、存続期間によって、「永続オブジェクト」と「一時オブジェクト」に分類されます。 永続オブジェクトのインスタンスは、オブジェクト識別子によって参照可能かどうかに応じて、さらに「スタンドアロン・オブジェクト」と「埋込みオブジェクト」に分割できます。

注意 : このマニュアルで使用しているオブジェクトとインスタンスとは、互換性のある用語として使われます。

関連項目 : オブジェクトの詳細は、『Oracle8 Server概要』 のマニュアルを参照してください。

永続オブジェクト永続オブジェクトは Oracle8データベースに格納されているオブジェクトです。 永続オブジェクトは、OCIアプリケーションによってオブジェクト・キャッシュにフェッチされ、変更されます。 永続オブジェクトは、それにアクセスしているアプリケーションの存続期間が過ぎても存続できます。 作成された永続オブジェクトは、明示的に削除されるまでデータベースに残留します。 永続オブジェクトには次の 2種類があります。

■ スタンドアロン・インスタンス。オブジェクト表の行に格納され、それぞれが他と重複しないオブジェクト識別子を持っています。 OCIアプリケーションでは、スタンドアロン・インスタンスへの REFを検索してオブジェクトを確保し、確保したオブジェクトからその他の関連オブジェクトにナビゲートできます。

スタンドアロン・オブジェクトは参照可能オブジェクトとも呼ばれます。

参照可能オブジェクトの選択も可能で、その場合 REFをフェッチする代わりにオブジェクトを「値渡し」でフェッチします。

■ 埋込みインスタンスのこれは、オブジェクト表の行として格納されません。 埋込みインスタンスは、他の構造体の中に埋め込まれます。 埋込みオブジェクトの例は、別のオブジェクトの属性であるオブジェクトや、データベースの表のオブジェクト列に存在する

Page 224: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでのオブジェクトの操作

8-6 Oracle8 コール・インタフェース・プログラマーズ・ガイド

インスタンスなどです。 埋込みインスタンスにはオブジェクト識別子がないので、OCIアプリケーションで埋込みインスタンスへの REFを入手することはできません。

埋込みオブジェクトは参照不能オブジェクトまたは値インスタンスとも呼ばれます。 埋込みオブジェクトが値と呼ばれることがありますが、それがスカラー・データ値と混同されることはありません。 文脈によりどちらの意味かわかります。

次の SQLの例で、この 2種類の永続オブジェクトの違いを説明します。

例 1 スタンドアロン・オブジェクトCREATE TYPE person_t AS OBJECT (name varchar2(30), age number(3));CREATE TABLE person_tab OF person_t;

オブジェクト表 person_tabに格納されるオブジェクトは、スタンドアロン・インスタンスです。 このオブジェクトはオブジェクト識別子を持ち、参照可能です。 したがって、OCIアプリケーションで確保できます。

例 2 埋込みオブジェクトCREATE TABLE department (deptno number, deptname varchar2(30), manager person_t);

department表の manager列に格納されるオブジェクトは、埋込みオブジェクトです。 このオブジェクトはオブジェクト識別子を持たず、参照不能です。 つまり、OCIアプリケーションで確保することはできないので、確保を解除する必要もありません。 それらは常にオブジェクト・キャッシュの中に「値渡し」で取り込まれます。

一時オブジェクト一時オブジェクトはオブジェクト型のインスタンスです。 一時オブジェクトはオブジェクト識別子を持ち、その存続期間はインスタンス作成時にアプリケーションによって決定されます。 また、一時オブジェクトはいつでもアプリケーションで削除できます。

アプリケーションでは、OCIObjectNew()関数を使用して一時オブジェクトを作成し、計算のための一時的な値を格納することがよくあります。

一時オブジェクトを永続オブジェクトに変換することはできません。 オブジェクトのロールは、インスタンス化されたときに決定されます。

関連項目 :⦆OCIObjectNew()の使用方法については、8-30ページの「オブジェクトの作成および開放、コピー」を参照してください。

値このマニュアルでは、値は次のいずれかを意味します。

Page 225: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-7

■ データベースの表の非オブジェクト列に格納されるスカラー値。 OCIアプリケーションでは、SQL文を発行してデータベースから値をフェッチすることができます。

■ 埋込みまたは参照不能オブジェクト。

どちらを指しているのかは文脈でわかります。

注意 : 参照可能オブジェクトは、確保する代わりにオブジェクト・キャッシュ内で選択することが可能で、その場合、REFをフェッチする代わりにオブジェクトを「値渡し」でフェッチします。

OCIオブジェクト・アプリケーションの開発この項目では、基本的な OCIオブジェクト・アプリケーションの開発に伴う ステップを説明します。 8-4ページの「基本的なオブジェクト・プログラム構造体」で述べている各ステップは、ここでさらに詳しく説明します。

次の図は、アプリケーションがオブジェクトを操作する方法について、プログラム・ロジックを簡単に示します。 図を簡略にするために、必要なステップの一部が省略されています。 このダイアグラムにある各ステップについては、後の節で説明します。

図 8–1 基本的なオブジェクト操作のフロー

オブジェクトの Cアプリケーションでの表現OCIアプリケーションでオブジェクト型を操作するには、データベースにそのオブジェクト型が存在していなければなりません。 一般に、SQLスキーマ定義言語文で型を作成します(CREATE TYPEなど )。

Page 226: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-8 Oracle8 コール・インタフェース・プログラマーズ・ガイド

型定義 DDLコマンドが Oracle8 Serverで処理されるとき、型定義は型記述子オブジェクト(TDO)としてデータ・ディクショナリに格納されます。

アプリケーションでデータベースからオブジェクトのインスタンスを検索する場合は、クライアント側のオブジェクト表現を使用する必要があります。 Cプログラムでは、オブジェクト型の表現は structです。 OCIオブジェクト・アプリケーションには、各オブジェクト型構造体に対応する NULL標識構造体があります。

Oracle8 Serverには、データベース・オブジェクト型の C構造体表現を生成するオブジェクト型トランスレータ (OTT)というユーティリティがあります。 たとえば、次のように宣言した型がデータベースにあるとします。

CREATE TYPE emp_t AS OBJECT( name VARCHAR2(30), empno NUMBER, deptno NUMBER, hiredate DATE, salary NUMBER);

OTTで、次の C構造体と、対応する NULL標識構造体を生成します。

struct emp_t{ OCIString * name; OCINumber empno; OCINumber deptno; OCIDate hiredate; OCINumber salary;};typedef struct emp_t emp_t

struct emp_t_ind{ OCIInd _atomic; OCIInd name; OCIInd empno; OCIInd deptno; OCIInd hiredate; OCIInd salary;};typedef struct emp_t_ind emp_t_ind;

この構造体宣言で使用している変数型は、OCIオブジェクト・コールで採用されている 特殊な型です。 OCI関数のサブセットでは、このデータ型のデータを操作します。 これらの関数は、この章の後半に説明があるほか、第 9章の「オブジェクト・リレーショナル・データ型」でも詳しく述べられています。

Page 227: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-9

これらの構造体の宣言は自動的に .hファイルに書き込まれます。このファイルの名前はOTT入力パラメータで決定されます。 このヘッダー・ファイルをアプリケーションのコード・ファイルに組み込んで、オブジェクトにアクセスできます。

関連項目 : OTTの詳細は、第 12章の「オブジェクト型トランスレータの使用」を参照してください。

NULL標識構造体の使用方法については、8-27ページの「NULL」を参照してください。

環境およびオブジェクト・キャッシュの初期化OCIアプリケーションでオブジェクトにアクセスして操作する場合、OCIアプリケーションの最初の OCIコールである OCIInitialize()の modeパラメータに、OCI_OBJECTの値を指定する必要があります。 modeにこの値を指定して、アプリケーションでオブジェクトを操作することを OCIライブラリに通知します。 この通知には次の重要な効果があります。

■ 「オブジェクト・ランタイム環境」を確立する

■ 「オブジェクト・キャッシュ」を設定する

OCIInitialize()の modeパラメータに OCI_OBJECTを設定しないと、オブジェクト関連関数を使用しても結果はエラーになります。

クライアント側のオブジェクト・キャッシュは、プログラムのプロセス領域に割 り当てられます。 このキャッシュは、サーバーから検索してアプリケーションで使用できるオブジェクトのメモリーです。

注意 : OCI環境をオブジェクト・モードに初期化すると、実際にオブジェクト・コールを使用するかどうかに関係なく、オブジェクト・キャッシュ用のメモリーを割り当てることになります。

関連項目 : この章全体を通して、オブジェクト・キャッシュについて言及しています。 オブジェクト・キャッシュの詳しい説明は、第 11章の「オブジェクトのキャッシュおよびオブジェクト・ナビゲーション」を参照してください。

データベース接続の実行アプリケーションでは、OCI環境を正しく初期化した後、サーバーに接続できます。 これは標準 OCI接続コールを通して達成され、詳細は 2-14ページの「OCIプログラミング・ステップ」に説明があります。標準 OCI接続コールを使用すると、アプリケーションでオブジェクトにアクセスするための特別な配慮は必要ありません。

OCI環境ごとに、1つのオブジェクト・キャッシュだけ割り当てられます。 1つの環境内で異なる接続を通して検索または作成されたオブジェクトは、すべて同じ物理的なオブジェクト・キャッシュを使用します。

Page 228: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-10 Oracle8 コール・インタフェース・プログラマーズ・ガイド

サーバーからのオブジェクト参照の取得アプリケーションでオブジェクトを操作するには、最初にサーバーから 1つ以上のオブジェクトを検索する必要があります。 検索は、1つ以上のオブジェクトへの REFを戻す SQL文を発行して行います。

注意 : SQL文によって、データベースから REFではなく埋込みオブジェクトをフェッチすることもできます。 詳細は、8-14ページの「埋込みオブジェクトのフェッチ」を参照してください。

次の例では、データベース内の従業員のオブジェクト表 (emp_tab)から 1つの従業員オブジェクトへの REFを検索するように設計した SQL文があり、その文を格納しているテキスト・ブロックをアプリケーションで宣言しています。実行時に入力変数 (:emp_num)として特定の従業員番号を指定します。

text *selemp = (text *) "SELECT REF(e) FROM emp_tab e WHERE empno = :emp_num";

アプリケーションでは、第 2章で説明したリレーショナル SQL文の操作と同じ方法でこの文を作成し、処理します。

■ OCIStmtPrepare()を使用してアプリケーション要求を準備する。

■ 適切なバインド・コールを使用してホスト入力変数をバインドする。

■ 従業員オブジェクト参照を受け取る出力変数を宣言し、準備する。 ここでは、8-7ページの「オブジェクトの Cアプリケーションでの表現」で宣言したような従業員オブジェクト参照を使います。

OCIRef *emp1_ref = (OCIRef *) 0; /* reference to an employee object */

出力変数を定義するとき、定義コールのデータ型パラメータ dtyに SQLT_REF (REFのデータ型定数 )を設定します。

■ OCIStmtExecute()で文を実行する。

■ OCIStmtFetch()を使用して結果の REFを emp1_refにフェッチする。

これで、オブジェクト参照を使用して、オブジェクト、またはデータベースからのオブジェクトにアクセスして操作できます。

関連項目 : SQL文の準備および実行についての一般情報は、2-14ページの「OCIプログラミング・ステップ」を参照してください。REF変数のバインディングおよび定義に関する特定の情報は、5-9ページの「拡張バインド操作」および 5-15ページの「拡張バインド操作」を参照してください。

REFの取出しおよびその確保を示すコード・サンプルは、D-115ページの「例 7、REF確保とナビゲーション」を参照してください。

Page 229: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-11

オブジェクトの確保フェッチを行うステップが完了すると、アプリケーションでは、オブジェクトへの REF、つまりポインタを取得します。 この時点ではまだ実際のオブジェクトは操作できません。 オブジェクトを操作する前に、オブジェクトを「確保」する必要があります。 オブジェクトの確保では、オブジェクト・インスタンスをオブジェクト・キャッシュにロードすることにより、必要に応じて、インスタンスの属性へのアクセスおよび変更や、1オブジェクトからその他のオブジェクトへの参照追跡を可能にします。 アプリケーションでは、変更したオブジェクトをいつサーバーに書き込むかも制御できます。

注意 : この項目では、一度に単一のオブジェクトを確保する単純な操作の例を示します。 複合オブジェクト検索を通しての複数のオブジェクトの取り出しは、8-20ページの「複合オブジェクト検索」を参照してください。

アプリケーションでオブジェクトを確保するには、関数 OCIObjectPin()をコールします。 この関数のパラメータで、オブジェクトの「確保のオプション」、「確保継続時間」、および「ロック・オプション」を指定できます。

次のサンプル・コードは、前の項目で検索した従業員参照を確保する操作を示しています。

if (OCIObjectPin(env, err, &emp1_ref, (OCIComplexObject *) 0, OCI_PIN_ANY, OCI_DURATION_TRANS, OCI_LOCK_X, &emp1) != OCI_SUCCESS) process_error(err);

この例では、process_error()はエラー処理関数を表しています。 OCIObjectPin()関数で、OCI_SUCCESS以外の値が戻された場合、このエラー処理関数がコールされます。 OCIObjectPin()関数のパラメータは次のとおりです。

■ envは環境ハンドル。

■ errは OCIエラー・ハンドル。

■ emp1_refは、SQLによって検索された参照。

■ (OCIComplexObject *) 0は、この確保操作で複合オブジェクト検索を行わないことを示す。

■ OCI_PIN_ANYは確保オプション。 詳細は 11-6ページの「オブジェクト・コピーの確保」を参照してください。

■ OCI_DURATION_TRANSは確保継続時間。 詳細は 11-13ページの「オブジェクトの継続時間」を参照してください。

■ OCI_LOCK_Xはロック・オプション。 詳細は 11-12ページの「更新するためのオブジェクトのロック」を参照してください。

■ emp1は出力パラメータであり、確保したオブジェクトへのポインタを戻す。

Page 230: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-12 Oracle8 コール・インタフェース・プログラマーズ・ガイド

これでオブジェクトが確保され、OCIアプリケーションでは、そのオブジェクトを変更できます。 この単純な例では、オブジェクトは他のオブジェクトへの参照を含んでいません。 インスタンスからインスタンスへのナビゲーション例は、11-17ページの「単純なオブジェクト・ナビゲーション」を参照してください。

配列確保OCIアプリケーションでは、OCIObjectArrayPin()をコールすることによって、参照の配列に対してオブジェクトの配列を確保できます。 参照は、異なる種類のオブジェクトを指すことができます。

オブジェクト属性の操作これでオブジェクトが確保され、OCIアプリケーションでは、その属性を変更できます。 OCIには、オブジェクト型構造体のデータ型を操作する一連の関数である、OCIデータ型マッピングおよび操作関数があります。

注意 : オブジェクト・キャッシュで確保したオブジェクトに対する変更は、オブジェクトのコピー(インスタンス)にだけ影響し、データベースにある元のオブジェクトには影響しません。 アプリケーションで行った変更をデータベースに反映するには、変更内容をサーバーにフラッシュまたはコミットする必要があります。 詳細は 8-13ページの「オブジェクトのマークおよび変更のフラッシュ」を参照してください。

たとえば、従業員給与を増額できるよう前項で従業員オブジェクトを確保したとします。 また、この会社では、入社して 180日間未満の従業員には、年間昇給率が案分比例されるとします。

したがって、この例では従業員の雇用日にアクセスし、それが現在の日付より 180日以上前か 180日以内かをチェックします。 その計算を基盤として、従業員の給与を $5000(180日以上前 )または $3000(180日以内 )分増額します。 次のページのサンプル・コードでは、このプロセスを示しています。

データ型マッピングおよび操作関数で操作できるのは特定のいくつかのデータ型であり、int型などのその他の型は、適切な OCI型に変換しなければ計算で使用できないことに注意してください。

/* assume that sysdate has been fetched into sys_date, a string. *//* emp1 and emp1_ref are the same as in previous sections. *//* err is the OCI error handle. *//* NOTE: error handling code is not included in this example. */

sb4 num_days; /* the number of days between today and hiredate */OCIDate curr_date; /* holds the current date for calculations */int raise; /* holds the employee’s raise amount before calculations */OCINumber raise_num; /* holds employee’s raise for calculations */OCINumber new_sal; /* holds the employee’s new salary */

/* convert date string to an OCIDate */

Page 231: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-13

OCIDateFromText(err, (text *) sys_date, (ub4) strlen(sys_date), (text *) NULL, (ub1) 0, (text *) NULL, (ub4) 0, &curr_date);

/* get number of days between hire date and today */OCIDateDaysBetween(err, &curr_date, &emp1->hiredate, &num_days);

/* calculate raise based on number of days since hiredate */if num_days > 180 raise = 5000else raise = 3000;

/* convert raise value to an OCINumber */OCINumberFromInt(err, (dvoid *)&raise, (uword)sizeof(raise), OCI_NUMBER_SIGNED, &raise_num);

/* add raise amount to salary */OCINumberAdd(err, &raise_num, &emp1->salary, &new_sal);OCINumberAssign(err, &new_sal, &emp1->salary);

この例は、値をパラメータとして OCIデータ型マッピングおよび操作関数に渡す前に、どのように OCIデータ型 (OCIDateや OCINumberなど )に変換するかを示しています。

関連項目 : OCIデータ型およびデータ型マッピング、およびその操作関数については、第 9章の「オブジェクト・リレーショナル・データ型」を参照してください。

オブジェクトのマークおよび変更のフラッシュ前の項の例では、オブジェクト・インスタンスの属性を変更しました。 ただし、この時点では変更はクライアント側のオブジェクト・キャッシュにだけ存在しています。 変更をデータベースに確実に書き込むために、アプリケーションで特定のステップを実行する必要があります。

最初のステップでは、オブジェクトが変更されたことを指示します。 これは、OCIObjectMarkUpdate()関数を使用して行います。 この関数は、オブジェクトにダーティ(変更あり)とマークします。

ダーティ・フラグが設定されているオブジェクトは、変更をデータベースに記録するために、サーバーにフラッシュする必要があります。 次の 3つの方法でこれを実行します。

■ 単一のダーティ・オブジェクトは、OCIObjectFlush()をコールしてフラッシュする。

■ OCICacheFlush()を使用して、キャッシュ全体をフラッシュする。 この場合、キャッシュで管理されているダーティ・リストが OCIによって走査され、ダーティ・オブジェクトがサーバーにフラッシュされます。

■ OCITransCommit()をコールして、トランザクションをコミットする。 この方法でも、ダーティ・リストが走査されてオブジェクトがサーバーにフラッシュされます。

Page 232: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-14 Oracle8 コール・インタフェース・プログラマーズ・ガイド

フラッシュ命令は、キャッシュの永続オブジェクトだけに作用します。 一時オブジェクトはサーバーにフラッシュされません。

オブジェクトをサーバーにフラッシュすることで、データベースのトリガーをアクティブにすることができます。 実際、アプリケーションでオブジェクトを明示的にフラッシュし、サーバー側のトリガーを起動する必要がある場合があります。

関連項目 : OCITransCommit()の詳細は、7-3ページの「トランザクション」を参照してください。

一時および映像オブジェクトについては、8-30ページの「オブジェクトの作成および開放、コピー」を参照してください。

オブジェクトのメタ属性の照会およびチェックについては(「ダーティ」など)、8-16ページの「オブジェクトのメタ属性」を参照してください。

埋込みオブジェクトのフェッチ使用しているアプリケーションで、埋込みオブジェクト・インスタンス(オブジェクト表でなく、通常の表の列に格納されたオブジェクト)をフェッチする必要がある場合、8-10ページの「サーバーからのオブジェクト参照の取得」で説明する REF取出し機能は使えません。埋込みインスタンスにはオブジェクト識別子がないので、埋込みインスタンスへの REFは入手できません。 これは埋込みインスタンスがオブジェクト・ナビゲーションの基礎として機能しないことを意味します。 しかし、アプリケーションで埋込みインスタンスをフェッチすることが必要な状況は数多くあります。

たとえば、address型が作成されたとします。

CREATE TYPE address AS OBJECT( street1 varchar2(50), street2 varchar2(50), city varchar2(30), state char(2), zip number(5))

その型を、他の表で列のデータ型として使用することができます。

CREATE TABLE clients( name varchar2(40), addr address)

OCIアプリケーションで次の SQL文を発行します。

SELECT addr FROM clientsWHERE name=’BEAR BYTE DATA MANAGEMENT’

この文は、clients表の埋込みオブジェクト addressを戻します。 アプリケーションでは、このオブジェクトの属性値を別の処理で使用できます。

Page 233: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-15

アプリケーションでは、第 2章で説明したリレーショナル SQL文の操作と同じ方法でこの文を作成し、処理します。

■ OCIStmtPrepare()を使用してアプリケーション要求を準備する。

■ 適切なバインド・コールを使用して入力変数をバインドする。

■ addressインスタンスを受け取る出力変数を定義する。 8-7ページの「オブジェクトのCアプリケーションでの表現」で説明するとおり、OTTで生成されたオブジェクト型のC構造体表現を使います。

addr1 *address; /* variable of the address struct type */

出力変数を定義するときは、定義コールのデータ型パラメータ dtyに、SQLT_NTY(名前付きデータ型のデータ定義定数 )を設定する必要があります。

■ OCIStmtExecute()で文を実行する。

■ OCIStmtFetch()を使用して結果のインスタンスを addr1にフェッチする。

8-12ページの「オブジェクト属性の操作」で説明するとおり、インスタンスの属性にアクセスするか、インスタンスを別の SQL文の入力パラメータとして渡せます。

注意 : 埋込みインスタンスに行う変更は、SQL UPDATE文を実行する場合にのみ永続的にできます。

関連項目 : SQL文の準備および実行については、2-14ページの「OCIプログラミング・ステップ」を参照してください。

Page 234: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-16 Oracle8 コール・インタフェース・プログラマーズ・ガイド

オブジェクトのメタ属性オブジェクトのメタ属性は、アプリケーションまたはオブジェクト・キャッシュに、オブジェクトのステータスに関する情報を提供するフラグの役割をします。 たとえば、オブジェクトのメタ属性の 1つとして、オブジェクトがサーバーにフラッシュ済みかどうかを示す属性があります。 これは、アプリケーションでインスタンスの動作を制御するのに役立ちます。

永続オブジェクトのインスタンスと一時オブジェクトのインスタンスには、それぞれ異なるメタ属性があります。 永続オブジェクトのメタ属性は、さらに永続メタ属性と一時メタ属性に分かれます。 一時メタ属性は、インスタンスがメモリー内にあるときにだけ存在します。 永続メタ属性は、サーバーに格納されているオブジェクトにも適用されます。

永続オブジェクトのメタ属性次の表は、スタンドアロン永続オブジェクトのメタ属性を示しています。

注意 : 埋込み永続オブジェクトの属性は、一時属性である NULLと割当て継続時間だけです。

OCIは、アプリケーションでオブジェクトのあらゆる属性のステータスをチェックできるOCIObjectGetProperty() 機能を提供します。

永続オブジェクトのメタ属性 意味

既存 オブジェクトが存在しているか。

NULL インスタンスの NULL情報

ロック オブジェクトはロックされているか。

ダーティ オブジェクトが「ダーティ済み」とマークされているか。

一時メタ属性

確保済み オブジェクトは確保済みか。

割当て継続時間 11-13ページの「オブジェクトの継続時間」を参照。

確保継続時間 11-13ページの「オブジェクトの継続時間」を参照。

Page 235: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-17

関数の構文は次のとおりです。

sword OCIObjectGetProperty ( OCIEnv *envh, OCIError *errh, CONST dvoid *obj, OCIObjectPropId propertyId, dvoid *property, ub4 *size );

propertyId および property パラメータは、あらゆるプロパティまたは属性に関する情報の検索に使われます。

異なるプロパテ idsと、対応するプロパティ因数の型は以下のとおりです。 詳細は、14-29ページの OCIObjectGetProperty()を参照してください。

OCI_OBJECTPROP_LIFETIME 与えられたオブジェクトが、永続オブジェクトか一時オブジェクト、値インスタンスのどれかを識別します。 プロパティ因数は、OCIObjectLifetime型の変数を指すポインタでなければなりません。 可能な値は次のとおりです。

■ OCI_OBJECT_PERSISTENT

■ OCI_OBJECT_TRANSIENT

■ OCI_OBJECT_VALUE

OCI_OBJECTPROP_SCHEMAこれでオブジェクトが存在する表のスキーマ名を戻します。 与えられたオブジェクトが、一時的なインスタンスまたは値をポイントする場合、エラーが戻されます。 入力バッファにスキーマ名を保持できるスペースがない場合、エラーが戻され、エラー・メッセージに必要なサイズが表示されます。 成功すると、戻されたスキーマ名のサイズが sizeを通じてバイト数で戻されます。プロパティ引数は型 textの配列で、sizeはバイトによる要求ごとの配列のサイズに設定する必要があります。

OCI_OBJECTPROP_TABLE これでオブジェクトが存在する表名を戻します。 与えられたオブジェクトが、一時的なインスタンスまたは値をポイントする場合、エラーが戻されます。 入力バッファに表名を保持できるスペースがない場合、エラーが戻され、エラー・メッセージに必要なサイズが表示されます。 成功すると、戻された表名のサイズが sizeを通じてバイト数で戻されます。プロパティ引数は型 textの配列で、sizeはバイトによる要求ごとの配列のサイズに設定する必要があります。

OCI_OBJECTPROP_PIN_DURATION これでオブジェクトの確保継続時間を戻します。与えられたオブジェクトが値インスタンスをポイントする場合、エラーが戻されます。プロパティ引数は、型 OCIDurationの変数を指すポインタでなければなりません。 有効値には次があります。

■ OCI_DURATION_SESSION

Page 236: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-18 Oracle8 コール・インタフェース・プログラマーズ・ガイド

■ OCI_DURATION_TRANS

継続時間については、11-13ページの「オブジェクトの継続時間」を参照してください。

OCI_OBJECTPROP_ALLOC_DURATIONこれでオブジェクトの割当て継続時間を戻します。 プロパティ引数は、型 OCIDurationの変数を指すポインタでなければなりません。 有効値には次があります。

■ OCI_DURATION_SESSION

■ OCI_DURATION_TRANS

継続時間については、11-13ページの「オブジェクトの継続時間」を参照してください。

OCI_OBJECTPROP_LOCKこれでオブジェクトのロック・ステータスを戻します。 可能なロック・ステータスは、OCILockOptで計数値です。 与えられたオブジェクトが、一時的なまたは値インスタンスをポイントする場合、エラーが戻されます。 プロパティ因数は、OCILockOpt型の変数を指すポインタでなければなりません。 オブジェクトのロック・ステータスも、OCIObjectIsLocked()を要求して取得できます。

OCI_OBJECTPROP_MARKSTATUSこれでダーティ・ステータスを戻し、オブジェクトが新規オブジェクトか更新済オブジェクト、削除済オブジェクトのどれかを示します。 与えられたオブジェクトが、一時的なまたは値インスタンスをポイントする場合、エラーが戻されます。 プロパティ因数は、OCIObjectMarkStatus型でなくてはなりません。 有効値には次があります。

■ OCI_OBJECT_NEW

■ OCI_OBJECT_DELETED

■ OCI_OBJECT_UPDATED

オブジェクトのマーク・ステータスのテストに、次のマクロを使えます。

■ OCI_OBJECT_IS_UPDATED(flag)

■ OCI_OBJECT_IS_DELETED(flag)

■ OCI_OBJECT_IS_NEW(flag)

■ OCI_OBJECT_IS_DIRTY(flag)

OCI_OBJECTPROP_VIEW指定するオブジェクトがビュー・オブジェクトかどうかを識別します。 戻されるプロパティ値が TRUEの場合、オブジェクトがビューであることを示します。 与えられたオブジェクトが、一時的なまたは値インスタンスをポイントする場合、エラーが戻されます。 プロパティ因数は、型ブールでなければなりません。

Page 237: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-19

その他の属性関数次の表に示すように、OCIには、アプリケーションでこれらの属性を直接的または間接的に設定あるいはチェックできるルーチンが提供されています。

一時オブジェクトのメタ属性一時オブジェクトには次の一時属性があります。一時オブジェクトに永続属性はありません。

メタ属性 設定に使用する関数 チェックに使用する関数

NULL <none> OCIObjectGetInd()

存在 <none> OCIObjectExists()

ロック OCIObjectLock() OCIObjectIsLocked()

ダーティ OCIObjectMark() OCIObjectIsDirty()

一時メタ属性 意味

既存 オブジェクトが存在しているか。

確保済み オブジェクトはアプリケーションによってアクセスされるか。

ダーティ オブジェクトが「ダーティ済み」とマークされているか。

NULL インスタンスの NULL情報。

割当て継続時間 11-13ページの「オブジェクトの継続時間」を参照。

確保継続時間 11-13ページの「オブジェクトの継続時間」を参照。

Page 238: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-20 Oracle8 コール・インタフェース・プログラマーズ・ガイド

複合オブジェクト検索ここまでの例は、一度に 1つのインスタンスだけのフェッチまたは確保を行う例でした。 その場合、オブジェクトを検索するためのサーバー往復が、確保操作ごとに別個に発生します。

オブジェクト指向アプリケーションでは、相互に関連したオブジェクトの集合として問題をモデル化することがよくあります。それらのオブジェクトは、オブジェクトのグラフを形成します。 アプリケーションでは、初期のオブジェクトの集合の一部を起動してオブジェクトを処理し、それら初期のオブジェクトの参照を使用して残りのオブジェクトを走査します。 クライアント /サーバー設定では、走査のたびにオブジェクトをフェッチするためのネットワーク往復が発生し、非効率です。

アプリケーションでオブジェクトを処理するとき、複合オブジェクト検索 (COR)を行うとパフォーマンスが向上します。 これはプリフェッチ・メカニズムであり、アプリケーションでは、このメカニズムを使用して、リンクされた一連のオブジェクトを 1回の操作で検索するための基準を指定します。

注意 : 次に説明するとおり、事前にフェッチされたオブジェクトがすべて確保されているとは限りません。 それらはオブジェクト・キャッシュ内にフェッチされるため、後続の確保コールはローカル操作で行われます。

「複合オブジェクト」は、ルート・オブジェクトと、指定の「ネスト・レベル」に基づいてそれぞれプリフェッチされる一連のオブジェクトで構成される、論理的に関連したオブジェクトの集まりです。 「ルート・オブジェクト」は、明示的にフェッチまたは確保されます。 ネスト・レベルは、複合オブジェクトのルート・オブジェクトから指定のプリフェッチ対象オブジェクトまで最短で走査した場合の参照の数です。

アプリケーションで複合オブジェクトを指定するときは、複合オブジェクトの内容と境界を記述します。 複合オブジェクトのフェッチは、環境のプリフェッチ制限、およびオブジェクト・キャッシュ内の使用可能なメモリーの量によって制約されます。

CORは、パフォーマンスを改善するだけであり、機能を追加するものではありません。 そのため、使用するかどうかはオプションです。

例として、次の型宣言があるとします。

CREATE TYPE customer(...);CREATE TYPE line_item(...);CREATE TYPE line_item_varray as VARRAY(100) of REF line_item;CREATE TYPE purchase_order AS OBJECT( po_number NUMBER, cust REF customer, related_orders REF purchase_order, line_items line_item_varray)

purchase_order型は、スカラー値 po_number、明細品目 (line_items)の VARRAY、そして 2つの参照を含みます。 1つは customer型への参照、もう 1つは purchase_order型への参照であり、この型がリンク済みリストとして組み込まれることを示しています。

Page 239: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-21

複合オブジェクトをフェッチする場合は、アプリケーションで次の指定をする必要があります。

1. 目的のルート・オブジェクトへの REF。

2. 複合オブジェクトの境界を指定するための一組以上の型およびネストの情報。 型情報はCORでたどる REF属性を指示し、ネスト・レベルはリンクをたどるレベル数を指示します。

前述の購入オーダー (purchase_order)オブジェクトの場合は、アプリケーションで次の指定をする必要があります。

1. ルート購入オーダー・オブジェクトへの REF。

2. cust、related_ordersまたは line_itemsについての一組以上の型およびネストの情報。

購入オーダーをフェッチするアプリケーションでは、購入オーダーを出した顧客の情報にアクセスすることも十分考えられます。 単純なナビゲーションでは、2つのオブジェクトをフェッチするためにサーバーに 2回アクセスすることが必要です。 複合オブジェクト検索によって、購入オーダーを確保するときに顧客をプリフェッチができます。 この場合、複合オブジェクトは、購入オーダーのオブジェクトと参照する顧客のオブジェクトから成り立ちます。

この例では、アプリケーションは purchase_order REFを指定し、cust REF属性をネスト・レベル 1までたどるように指示します。

1. REF(PO object)

2. {(customer, 1)}

アプリケーションで、purchase_orderオブジェクトと、オブジェクト・グラフに含まれるすべてのオブジェクトをプリフェッチする必要がある場合、custおよびrelated_ordersは両方とも、最大のネスト・レベルまでたどるようにアプリケーションで指示します。

1. REF(PO objcet)

2. {(customer, 1), (purchase_order, UB4MAXVAL)}

UB4MAXVALは、ルート・オブジェクトから参照を通して到達できる指定の型のオブジェクトすべてのプリフェッチを指定します。

アプリケーションで、POおよび関連する明細品目すべてをフェッチする場合は、次の指定をします。

1. REF(PO object)

2. {(line_item, 1)}

アプリケーションでは、REFを通して特定の深さまで到達できる(推移閉包)オブジェクトすべてをフェッチすることも選択できます。 そのためには、目的の深さをレベル・パラメータとして設定する必要があります。 前述の 2つの例では、それぞれアプリケーションで (PO

Page 240: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-22 Oracle8 コール・インタフェース・プログラマーズ・ガイド

object REF, UB4MAXVAL)と (PO object REF, 1)を指定して、必要なオブジェクトをプリフェッチすることもできます。 そう指定した場合、多数のフェッチが余計に発生しますが、指定が非常に簡単であり、サーバー往復が 1回だけですみます。

オブジェクトのプリフェッチ複合オブジェクトを指定してフェッチした後に行う、複合オブジェクトに含まれるオブジェクトのフェッチでは、ネットワーク往復は発生しません。これは、オブジェクトがすでにプリフェッチ済みであり、オブジェクト・キャッシュ内にあるためです。 プリフェッチするオブジェクトが多すぎると、オブジェクト・キャッシュがあふれることがあるので注意が必要です。 オブジェクト・キャッシュがあふれると、アプリケーションですでに確保している他のオブジェクトがキャッシュから押し出され、パフォーマンスの改善ではなく逆に低下につながることがあります。

注意 : プリフェッチ済みのオブジェクトをすべて保持するだけのメモリーがキャッシュにない場合、オブジェクトの一部がプリフェッチされない場合があります。 アプリケーションでは、後でそれらのオブジェクトにアクセスするとき、ネットワーク往復が発生します。

すべてのプリフェッチ対象オブジェクトに対して、SELECT権限が必要です。 複合オブジェクト内のオブジェクトに対する SELECT権限がアプリケーションにない場合、そのオブジェクトはフェッチできません。

OCIでの複合オブジェクト検索の実現複合オブジェクト (COR)の場合、アプリケーションで ルート・オブジェクトをフェッチするときに複合オブジェクトのプリフェッチができます。 単純オブジェクトに対して使用するのと同じ OCIObjectPin()関数に、複合オブジェクト指定を渡します。

アプリケーションで、複合オブジェクト検索ハンドルを使用して、複合オブジェクト検索のパラメータを指定します。 このハンドルは、OCIComplexObject型であり、その他の OCIハンドルと同じ方法で割り当てます。

複合オブジェクト検索ハンドルの内容は、複合オブジェクト検索記述子のリストです。 複合オブジェクト検索記述子は、OCIComplexObjectComp型であり、その他の OCI記述子と同じ方法で割り当てます。

各 COR記述子には、型 REFとネスト・レベルが含まれています。 型 REFでは、複合オブジェクトを組み立てるときにたどる参照の型を指定します。 ネスト・レベルでは、特定の型の参照をどこまでたどるかを指示します。 ネスト・レベルの最大値は、整数値または定数UB4MAXVALを指定します。

アプリケーションでは、型パラメータとネスト・レベル・パラメータの COR記述子を作成しないで、CORハンドルにネスト・レベルを指定することもできます。 この場合、すべてのREFについて、CORハンドルに指定されたネスト・レベルまでたどります。 また、要求があったときに個別にコレクション属性がフェッチされる(ライン外)かどうかも、CORハンドルで指定できます。デフォルトでは、コレクション属性は、それを含むオブジェクトとともにフェッチされます(インライン)。

Page 241: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-23

アプリケーションで CORハンドルの属性を設定するには、OCIAttrSet()を使用します。 次の属性があります。

OCI_ATTR_COMPLEXOBJECT_LEVEL - ネスト・レベル

OCI_ATTR_COMPLEXOBJECT_COLL_OUTOFLINE - オブジェクト型のコレクション属性をライン外でフェッチ

アプリケーションで、OCIDescriptorAlloc()を使用して COR記述子を割り当て、次の属性を設定できます。

OCI_ATTR_COMPLEXOBJECTCOMP_TYPE - 型 REF

OCI_ATTR_COMPLEXOBJECTCOMP_LEVEL - 上記の型の参照に用いるネスト・レベル

これらの属性を設定すると、アプリケーションでは OCIParamSet()をコールして記述子を複合オブジェクト検索ハンドルに設定します。 ハンドルにはハンドルの記述子の数を指定するOCI_ATTR_PARAM_COUNT属性があります。 この属性は OCIAttrGet()で読み込めます。

ハンドルに記述子を挿入した後、ハンドルを OCIObjectPin()コールに渡してルート・オブジェクトを確保し、複合オブジェクトの残りのオブジェクトのプリフェッチを行います。

複合オブジェクト検索ハンドルと記述子は、必要がなくなったとき、明示的に解放する必要があります。

関連項目 : ハンドルおよび記述子については、2-5ページの「ハンドル」および 2-11ページの「記述子およびロケータ」を参照してください。

Page 242: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-24 Oracle8 コール・インタフェース・プログラマーズ・ガイド

CORプリフェッチアプリケーションでは、ルート・オブジェクトのフェッチ時に複合オブジェクトを指定します。 プリフェッチ対象オブジェクトは、指定のルート・オブジェクトを基点とするオブジェクトのグラフに対して、幅優先走査を実行することによって取得されます。 走査は、必要なオブジェクトがすべてプリフェッチされたとき、またはプリフェッチ済みオブジェクトの合計サイズが「プリフェッチ制限」を超えたときに停止します。

CORインタフェース複合オブジェクトをフェッチするためのインタフェースは、OCI確保インタフェースです。 アプリケーションは、初期化済みの CORハンドルを OCIObjectPin()に(またはハンドルの配列を OCIObjectArrayPin()に)渡して、ルート・オブジェクト、および CORハンドルで指定したプリフェッチ対象オブジェクトをフェッチすることができます。

sword OCIObjectPin ( OCIEnv *env, OCIError *err, OCIRef *object_ref, OCIComplexObject *corhdl, OCIPinOpt pin_option, OCIDuration pin_duration, OCILockOpt lock_option, dvoid **object );

sword OCIObjectArrayPin ( OCIEnv *env, OCIError *err, OCIRef **ref_array, ub4 array_size, OCIComplexObject **cor_array, ub4 cor_array_size, OCIPinOpt pin_option, OCIDuration pin_duration, OCILockOpt lock, dvoid **obj_array, ub4 *pos );

CORを使用するとき、次の点に注意してください。

1. NULLの CORハンドル引数は、デフォルトでルート・オブジェクトだけを確保する。

2. ルート・オブジェクト型でネスト・レベル 0の CORハンドルは、ルート・オブジェクトだけをフェッチする。つまり、NULLの CORハンドルに相当します。

3. ロック・オプションは、ルート・オブジェクトだけに適用される。

注意 : プリフェッチ対象オブジェクトのロック・オプションを指定するために、アプリケーションでは配列インタフェース (OCIObjectArrayPin())を使用して、複合オブジェクト内のオブジェクトすべてにアクセスし、REFの配列を作成し、個別の往復で複合オブジェクト全体をロックできます。

Page 243: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-25

CORの例次の例では、複合オブジェクト検索を行うためにアプリケーション・プログラムを修正する方法を詳しく説明します。

購入発注とそれに関連する明細品目を表示するアプリケーションを考えてみます。 太字のコードでこの処理を実行します。 残りのコードでは、プリフェッチの複合オブジェクト検索を使用するため、アプリケーションのパフォーマンスを改善します。

OCIEnv *envhp;OCIError *errhp;OCIRef *liref;OCIRef *poref;OCIIter *itr;boolean eoc;purchase_order *po = (purchase_order *)0;line_item *li = (line_item *)0;OCISvcCtx *svchp;OCIComplexObject *corhp;OCIComplexObjectComp *cordp;OCIType *litdo;ub4 level = 0;

/* get COR Handle */OCIHandleAlloc((dvoid *) envhp, (dvoid **) &corhp, (ub4) OCI_HTYPE_COMPLEXOBJECT, 0, (dvoid **)0);

/* get COR descriptor for type line_item */OCIDescriptorAlloc((dvoid *) envhp, (dvoid **) &cordp, (ub4) OCI_DTYPE_COMPLEXOBJECTCOMP, 0, (dvoid **) 0);

/* get type of line_item to set in COR descriptor */OCITypeByName(envhp, errhp, svchp, (const text *) 0, (ub4) 0, const text *) "LINE_ITEM", (ub4) strlen((const char *) "LINE_ITEM"), OCI_DURATION_SESSION, &litdo);

/* set line_item type in COR descriptor */OCIAttrSet( (dvoid *) cordp, (ub4) OCI_DTYPE_COMPLEXOBJECTCOMP, dvoid *) litdo, (ub4) sizeof(dvoid *), (ub4) OCI_ATTR_COMPLEXOBJECTCOMP_TYPE, (OCIError *) errhp);level = 1;

/* set depth level for line_item_varray in COR descriptor */OCIAttrSet( (dvoid *) cordp, (ub4) OCI_DTYPE_COMPLEXOBJECTCOMP, (dvoid *) &level, (ub4) sizeof(ub4), (ub4) OCI_ATTR_COMPLEXOBJECTCOMP_TYPE_LEVEL, (OCIError *) errhp);

/* put COR descriptor in COR handle */

Page 244: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-26 Oracle8 コール・インタフェース・プログラマーズ・ガイド

OCIParamSet(corhp, OCI_HTYPE_COMPLEXOBJECT, &errhp, cordp, OCI_DTYPE_COMPLEXOBJECTCOMP, 1);

/* pin the purchase order */OCIObjectPin(envhp, errhp, poref, corhp, OCI_PIN_LATEST, OCI_REFRESH_LOADED, OCI_DURATION_SESSION, OCI_LOCK_NONE, (ub2) 1, (dvoid **)&po)

/* free COR descriptor and COR handle */OCIDescriptorFree((dvoid *) cordp, (ub4) OCI_DTYPE_COMPLEXOBJECTCOMP);OCIHandleFree((dvoid *) corhp, (ub4) OCI_HTYPE_COMPLEXOBJECT);

/* iterate and print line items for this purchase order */OCIIterCreate(envhp, errhp, po.line_items, &itr);

/* get first line item */OCIIterNext(envhp, errhp, itr, &liref, (dvoid **)0, &eoc);while (!eoc) /* not end of collection */{/* pin line item */ OCIObjectPin(envhp, errhp, liref, (dvoid *)0, OCI_PIN_RECENT, OCI_REFRESH_LOADED,OCI_DURATION_SESSION, OCI_LOCK_NONE, (ub2) 1, (dvoid **)&li); display_line_item(li);

/* get next line item */OCIIterNext(envhp, errhp, itr, &liref, (dvoid **)0, &eoc);}

Page 245: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-27

確保カウントおよび確保解除オブジェクト・キャッシュ内の各オブジェクトには、確保カウントが関連付けられています。 本来、確保カウントはオブジェクトに並行アクセスするコード・モジュールの数を表します。 オブジェクトを初めてキャッシュに確保したときに、確保カウントを 1に設定します。 複合オブジェクト検索でプリフェッチ対象オブジェクトをオブジェクト・キャッシュに入れた時点では、オブジェクトの確保カウントは 0(ゼロ )です。

すでに確保されているオブジェクトを確保することができます。 そうすると、確保カウントが 1増えます。 プロセスでオブジェクトの使用が終了したとき、OCIObjectUnpin()を使用して「確保解除」を行う必要があります。 このコールによって確保カウントが 1減ります。

オブジェクトの確保カウントが 0(ゼロ )になった場合、必要があればオブジェクトをキャッシュから出し、オブジェクトが占めているメモリー領域を解放できます。

オブジェクトの確保カウントは、OCIObjectPinCountReset()をコールして、明示的に 0(ゼロ)に設定できます。

アプリケーションでは OCICacheUnpin()をコールして、キャッシュ内にある特定の接続に関連した全オブジェクトを確保解除できます。

関連項目 : 確保カウントが 0(ゼロ )のオブジェクトがキャッシュから削除される条件については、11-8ページの「オブジェクト・コピーの開放」を参照してください。

オブジェクトまたはキャッシュ全体の明示的なフラッシュについては、8-13ページの「オブジェクトのマークおよび変更のフラッシュ」を参照してください。

期限切れのためにキャッシュから出されるオブジェクトについては、11-8ページの「オブジェクト・コピーの開放」を参照してください。

NULLデータベースの表で行の列に値がない場合、その列は NULLである、またはNULLを含むといいます。 2種類の NULLがオブジェクトに適用できます。

■ オブジェクトの属性はすべて、NULL値を持つことができる。 これはオブジェクトの属性の値が不明であることを意味します。

■ オブジェクトのインスタンスは、「アトミック NULL」にできる。 これはオブジェクト全体の値が不明なことを意味します。

アトミック NULLとは、オブジェクトが存在しないということではありません。 アトミックNULLのインスタンスは、値が不明なだけで、存在はしています。 つまり、データを持たないオブジェクトとして考えることができます。

OCIでオブジェクトを操作するとき、アプリケーションでは、使用する各オブジェクト型の「NULL標識構造体」を定義できます。 通常そのために必要なのは、OTTで生成した NULL標識構造体を構造体宣言とともに組み込むことだけです。 OTTの出力ヘッダー・ファイルを組み込むと、アプリケーションで NULL標識構造体を使用できるようになります。

Page 246: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-28 Oracle8 コール・インタフェース・プログラマーズ・ガイド

各型について、NULL標識構造体の内容は、アトミック NULL標識 (OCIInd型 )とインスタンスの各属性の NULL標識です。 型にオブジェクト属性がある場合、NULL標識構造体には、その属性の NULL標識構造体が含まれます。 次の例では、対応する NULL標識構造体で C表現を示しています。

struct address{ OCINumber no; OCIString *street; OCIString *state; OCIString *zip;};typedef struct address address;

struct address_ind{ OCIInd _atomic; OCIInd no; OCIInd street; OCIInd state; OCIInd zip;};typedef struct address_ind address_ind;

struct person { OCIString *fname; OCIString *lname; OCINumber age; OCIDate birthday; OCIArray *dependentsAge; OCITable *prevAddr; OCIRaw *comment1; OCILobLocator *comment2; address addr; OCIRef *spouse;};typedef struct person person; struct person_ind{ OCIInd _atomic; OCIInd fname; OCIInd lname; OCIInd age; OCIInd birthday;

Page 247: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

OCIオブジェクト・リレーショナル・ プログラミング 8-29

OCIInd dependentsAge; OCIInd prevAddr; OCIInd comment1; OCIInd comment2; address_ind addr; OCIInd spouse;};typedef struct person_ind person_ind;

注意 : person_indの dependentsAgeフィールドは、personの配列dependentsAgeフィールド全体がアトミック NULLかどうかを示します。 dependentsAgeフィールドの個々の要素の NULL情報は、OCICollGetElem()のコールの elemindパラメータを通して検索できます。 同様に、person_indの prevAddrフィールドは、ネストした表 (personの prevAddrフィールド )全体がアトミックNULLかどうかを示します。 prevAddrフィールドの個々の要素の NULL情報は、OCICollGetElem()のコールの elemindパラメータを通して検索できます。

オブジェクト型インスタンスでは、NULL標識構造体の最初のフィールドがアトミックNULL標識で、残りのフィールドは、レイアウトがオブジェクト型インスタンスの属性に似ている属性 NULL標識です。

アプリケーションでは、アトミック NULL標識の値をチェックすることで、インスタンスがアトミック NULLかどうかをテストできます。 また、その他のインスタンスをチェックすることで、次のコード・サンプルで示すように、アプリケーションでその属性の NULL状態をテストできます。

person_ind *my_person_indif ( my_person_ind -> _atomic = OCI_IND_NULL){ /* instance is atomically null */}if ( my_person_ind -> fname = OCI_IND_NULL){ /* fname attribute is NULL */}上記の例では、アトミック NULL標識、または属性のNULL標識の 1つが事前定義済みの値 OCI_IND_NULLと比較され、NULL状態がテストされます。 この比較では、事前定義済みの次の値が使用可能です。

■ OCI_IND_NOTNULL。値がNULLでないことを示します。

■ OCI_IND_NULL。値がNULLであることを示します。

■ OCI_IND_BADNULL。囲みオブジェクト(または、親オブジェクト)が NULLであることを示します。 この値は PL/SQLで使用され、INVALID_NULLとしても参照されます。 たとえば、型インスタンスが NULLの場合、その属性は INVALID_NULLです。

OCIObjectGetInd()関数を使用して、オブジェクトの NULL標識構造体の検索や、記憶域の割当てができます。

Page 248: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIオブジェクト・アプリケーションの開発

8-30 Oracle8 コール・インタフェース・プログラマーズ・ガイド

関連項目 : OTTで生成する NULL標識構造体の詳細は、第 12章を参照してください。

オブジェクトの作成および開放、コピーOCIアプリケーションでは、OCIObjectNew()を使用してあらゆるオブジェクトを作成できます。 アプリケーションで永続オブジェクトを作成するには、新規オブジェクトを挿入するオブジェクト表を指定しなければなりません。 この値は、OCIObjectPinTable()をコールして検索し、tableパラメータで渡します。 一時オブジェクトを作成するには、作成するオブジェクトの型に対する型記述子オブジェクト (OCITypeByName()をコールして検索 )だけを渡す必要があります。

また、typecodeパラメータに適切な値を渡し、OCIObjectNew()を使用して、スカラーのインスタンス (REF、LOB、文字列、ロー、数値、日付など )、およびコレクション(可変長配列およびネストした表)を作成できます。

OCIObjectFree()を使用して、OCIObjectNew()で割り当てたメモリーを解放できます。 オブジェクトの解放とは、オブジェクト用に割り当てたメモリーと関連する NULL標識構造体をすべて割当て解除することです。 このプロシージャでは、存続期間が満了になる前にオブジェクトを削除します。 また、アプリケーションでは、OCIObjectMarkDelete()を使用して永続オブジェクトを削除できます。

アプリケーションでは、OCIObjectCopy()を使用して、1つのインスタンスを同じ型の別のインスタンスにコピーできます。

関連項目 : これらの関数の説明は、第 14章の説明を参照してください。

オブジェクト参照と型参照アプリケーションでは、OCIのオブジェクト拡張機能を利用して、オブジェクトの内容に対してポインタや参照による柔軟なアクセスができます。 OCIでは、ポインタによるオブジェクトへの参照を返還できるよう OCIObjectGetObjectRef()の関数を提供しています。

アプリケーションで、オブジェクトの型情報へのアクセスも望む場合、OCIではOCIObjectGetProperty()の関数で、ポインタがオブジェクトを指す場合のオブジェクトの型記述子オブジェクト (TDO)の参照を返還できます。

オブジェクト・アプリケーションでのエラー処理アプリケーションでオブジェクトを使用する場合も使用しない場合も、OCIアプリケーションでのエラー処理の方法は同じです。 ファンクション・リターン・コードおよびエラー・メッセージについての詳細は、2-24ページの「エラー処理」を参照してください。

Page 249: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・リレーショナル・データ型 9-1

9オブジェクト・リレーショナル・データ型

OCIデータ型マッピングおよび操作関数を使用すると、OCIプログラムで Cのアプリケーション内の Oracle事前定義済みデータ型のインスタンスを操作できます。 この章では、この関数について説明し、オブジェクト型をデータベースに格納する方法についても説明します。 Oracle8 Cデータ型を使用した、バインドおよび定義操作についての情報は、第 10章の「オブジェクト・アプリケーションでのバインディングおよび定義」を参照してください。

この章は、次のトピックで構成されています。

■ 概要

■ Oracle8データ型の Cへのマッピング

■ OCIでの Cデータ型の操作

■ 日付 (OCIDate)

■ 数値 (OCINumber)

■ 固定長または可変長文字列 (OCIString)

■ ロー (OCIRaw)

■ コレクション (OCITable、OCIArray、OCIColl、OCIIter)

■ REF (OCIRef)

■ オブジェクト型情報の格納およびアクセス

注意 : この章で説明されている機能性は、オブジェクト・オプションのある Oracle8 Enterprise Editionを購入された場合にのみ使用可能です。

Page 250: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

概要

9-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

概要OCIデータ型マッピングおよび操作関数を使用すると、事前定義済みの Oracle8 Cデータ型のインスタンスを操作できます。 これらのデータ型は、Oracle8のオブジェクト型など、ユーザー定義のデータ型の属性を表現するために使用します。

OCIの各関数グループは、特定の命名規則によって区別されています。 たとえば、データ型マッピングおよび操作関数は、関数名が "OCI"接頭辞で始まり、その後にデータ型が続くため、簡単に認識できます (例 :OCIDateFromText()および OCIRawSize())。後述するように、名前はさらに、特定の型のデータを操作する関数グループに分類できます。

また、これらの関数を操作する事前定義済みの Oracle8 C型は、"OCI"の接頭辞で始まる名前でも区別できます (例 :OCIDateや OCIString)。

データ型マッピングおよび操作関数は、アプリケーションで、Oracle8データベースに格納されたオブジェクト、または SQL問合せで検索されたオブジェクトの属性を操作またはバインド、定義する必要がある場合に使用します。 第 6章で説明したとおり、検索したオブジェクトはクライアント側のオブジェクト・キャッシュに格納されます。

この章では、OCIデータ型マッピングおよび操作関数で操作できる各データ型の用途と構造について説明します。 また、関数をグループ別にまとめ、使用可能な関数とその目的のリストを示します。

この章では、OCIアプリケーションのバインド操作と定義操作でこれらのデータ型を使用する方法も説明します。

これらの関数は、OCIアプリケーションがオブジェクト・モードで稼動している間にのみ有効です。 OCIのオブジェクト・モードでの初期化、またオブジェクトにアクセスおよび操作する OCIアプリケーションの作成については、8-9ページの「環境およびオブジェクト・キャッシュの初期化」を参照してください。

オブジェクト型および属性、コレクション・データ型に関する詳細は、『Oracle8 Server概要』を参照してください。

Page 251: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8データ型の Cへのマッピング

オブジェクト・リレーショナル・データ型 9-3

Oracle8データ型の CへのマッピングOracle8には、表を作成し、ユーザー定義のデータ型(オブジェクト型を含む)を指定できる、一連の事前定義済みのデータ型があります。 オブジェクト型は Oracle8の機能を拡張するものであり、オブジェクト型を使用すると、処理対象のデータのタイプを正確にモデル化したデータ型を作成できます。 そのため、プログラマは、より効率的で簡単なデータ・アクセスができます。

データベースの表およびオブジェクト型は、Oracleが供給するデータ型に基づいています。 データベースの表とオブジェクト型は、SQL文で作成し、VARCHAR2やNUMBERなどの特定の Oracle内部データ型を使用して格納します。 たとえば、次の SQL文では、ユーザー定義の addressデータ型と、そのデータ型のインスタンスを格納するオブジェクト表を作成します。

CREATE TYPE address AS OBJECT(street1 varchar2(50),street2 varchar2(50),city varchar2(30),state char(2),zip number(5));CREATE TABLE address_table OF address;

この新しい address型を使用して、次のようなオブジェクト列を持つ標準表を作成したとします。

CREATE TABLE employees(name varchar2(30),birthday date,home_addr address);

OCIアプリケーションでは、SQL文に対応付けられた、簡単なバインドおよび定義操作を使って、情報を employees表の nameおよび birthdayの列で操作できます。 オブジェクトの属性として格納されている情報にアクセスするには、いくつかの追加ステップが必要です。

OCIアプリケーションでは、まずオブジェクトを C言語形式で表現する手段が必要です。 そのためには、オブジェクト型トランスレータ (OTT)を使用して、ユーザー定義型の C構造体表現を生成します。 生成した構造体の要素は、Oracle8のデータ型を C言語にマッピングしたデータ型を持ちます。 オブジェクト属性の型として使用できる Oracleの型と、対応するCマッピングを次の表に示します。

表 9–1 オブジェクト型属性の C言語マッピング

属性の型 Cマッピング

VARCHAR2(N) OCIString *

VARCHAR(N) OCIString *

Page 252: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8データ型の Cへのマッピング

9-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

その他の C型としてOCIIndがあります。これは、オブジェクト型の属性に対応するNULL標識情報を表現するために使用します。

関連項目 : OTTの使用方法に関する情報および例は、第 12章を参照してください。

OCI型マッピングの方法論Oracleでは、事前定義済みの Oracle型のマッピングを指定するとき、固有の設計方針に従ってきました。 現行のシステムには次の利点があります。

■ OCINumberのようなデータ型の実際の表現は、クライアントのアプリケーションでは不明確で、データ型は事前に定義済みの一連の関数によって操作される。 これによって、将来改善する際にも、ユーザー・コードをブレークせずに内部表現を変更できます。

■ オブジェクト指向パラダイムに従った実装がなされている。このパラダイムではクラスの実装の詳細は隠され、見えるのは必要な操作だけです。

CHAR(N)、CHARACTER(N) OCIString *

NUMBER、NUMBER(N)、NUMBER(N,N) OCINumber

NUMERIC、NUMERIC(N)、NUMERIC(N,N) OCINumber

REAL OCINumber

INT、INTEGER、SMALLINT OCINumber

FLOAT、FLOAT(N)、DOUBLE PRECISION OCINumber

DEC、DEC(N)、DEC(N,N) OCINumber

DECIMAL、DECIMAL(N)、DECIMAL(N,N) OCINumber

DATE OCIDate

BLOB OCILobLocator * またはOCIBlobLocator *

CLOB OCILobLocator * またはOCIClobLocator *

BFILE OCIBFileLocator*

REF OCIRef *

RAW(N) OCIRaw *

VARRAY(可変長配列 ) OCIArray *

ネストした表 OCITable *

表 9–1 オブジェクト型属性の C言語マッピング

属性の型 Cマッピング

Page 253: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでの Cデータ型の操作

オブジェクト・リレーショナル・データ型 9-5

■ この実装方法はプログラマにとって有利。 Oracleの数値で提供される Oracle数値変数を、精度を落とすことなく操作する場合の Cプログラムを考えてみます。 これをOracle7で行うには、"SELECT...FROM DUAL"文の発行が必要でした。Oracle8では、OCINumber*()関数を呼び出すだけです。

OCIでの Cデータ型の操作OCIアプリケーションで、2つの整変数を合計して結果を第 3の変数に格納するという非常に簡単なデータ操作を行うとします。

integer int_1, int_2, sum;.../* some initialization occurs */...sum = int_1 + int_2;

C言語は、整整数型のように単純な型の一連の事前定義済み操作を提供します。 ただし、表9–1にリストする Cデータ型は、単純な Cプリミティブではありません。 OCIStringおよびOCINumberのような型は、実際は特定の Oracle定義の内部構造体をもつ構造体です。 単に、2つの OCINumberを合計して、その値を第 3の変数に格納することはできません。

次は有有効ではありません。

OCINumber num_1, num_2, sum;.../* some initialization occurs */...sum = num_1 + num_2; /* NOT A VALID OPERATION */

このような新しいデータ型を操作するための関数が、OCIデータ型マッピングおよび操作関数です。 たとえば、この例で OCINumberを加算するには、OCINumberAdd()関数を使用します。

OCINumber num_1, num_2, sum;.../* some initialization occurs */...OCINumberAdd(errhp, &num_1, &num_2, &sum): /* errhp is error handle */

OCIには、新規データ型をそれぞれ操作する関数があります。 関数の名前から、その関数で操作するデータ型がわかります。 最初の 3文字 "OCI"は、関数が OCIの一部であることを示します。関数名の次の部分は、関数で操作するデータ型を示します。 次の表では、各種の関数の接頭辞、および関数名の例、関数の操作対象のデータ型を示します。

関数の接頭辞 例 操作対象

OCIDate OCIDateDaysBetween() OCIDate

Page 254: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIでの Cデータ型の操作

9-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

各データ型の構造については、そのデータ型を操作対象にする関数のリストとともに、この章で後述します。

OCINumber OCINumberAdd() OCINumber

OCIString OCIStringSize() OCIString *

OCIRef OCIRefAssign() OCIRef *

OCIRaw OCIRawResize() OCIRaw *

OCIColl OCICollGetElem() OCIColl,OCIIter,OCITable,OCIArray

OCIIter OCIIterInit() OCIIter

OCITable OCITableLast() OCITable *

関数の接頭辞 例 操作対象

Page 255: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

日付 (OCIDate)

オブジェクト・リレーショナル・データ型 9-7

Oracle数値操作の精度Oracleの数値の精度は、10進数で 38桁です。 Oracleの数値操作は、次の例外を除いて、全桁で行います。

■ 逆三角関数の精度は、10進数で 28桁。

■ 三角関数を含むその他の超越関数の精度は、およそ 10進数で 37桁。

■ 固有の浮動小数点型との間の変換では、適切な浮動小数点型の精度になり、10進数で 38桁を超えることはない。

日付 (OCIDate)Oracleの日付書式は、不明確な C構造体である OCIDate型で Cにマップされます。 構造体の要素は、日付の年および月、日、時間、分、秒を表します。 特定の要素は、適当な OCI関数を使用して、設定および検索することができます。

OCIDateデータ型は、バインド・コールまたは定義コールで、外部型コード SQLT_ODTを使用して直接バインドまたは定義できます。

OCIの日付操作関数は、機能性ごとに編成された次の表にリストされています。 指定がない限り、これらの表の用語 "日付 "は、OCIDateタイプの値を表します。

関連項目 : すべての関数のプロトタイプおよび説明は、第 15章の「OCIデータ型マッピング関数および操作関数」を参照してください。

日付変換関数次の関数は、日付変換を実行します。

日付割当ておよび日付取得関数次の関数は、日付要素の検索と割当てを行います。

関数 用途

OCIDateToText() 日付を文字列に変換する

OCIDateFromText() テキスト文字列を日付に変換する

OCIDateZoneToZone() 日付をワンタイム・ゾーンから別のゾーンに変換する

関数 用途

OCIDateAssign() OCIDateの割当て

OCIDateGetDate() OCIDateの日付部分を入手する

Page 256: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

日付 (OCIDate)

9-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

日付算術および日付比較関数次の関数は、日付算術および比較を実行します。

日付情報アクセサ関数次の関数は、日付情報にアクセスします。

日付の有効性チェック関数次の関数は、日付の妥当性を検査します。

日付の例次のコード例では、OCIコールを使用して、OCIDate型の属性を操作する方法を示します。

#define FMT "DAY, MONTH DD, YYYY"#define LANG "American"struct person{OCIDate start_date;

OCIDateSetDate() OCIDateの日付部分を設定する

OCIDateGetTime() OCIDateの時間部分を入手する

OCIDateSetTime() OCIDateの時間の部分を設定する

関数 用途

OCIDateAddDays() 日を加算する

OCIDateAddMonths() 月を加算する

OCIDateCompare() 日付を比較する

OCIDateDaysBetween() 2つの日付間の日数を計算する

関数 用途

OCIDateLastDay() 月の最終日

OCIDateNextDay() 指定の日付後最初の日

OCIDateSysDate() システム日付

関数 用途

OCIDateCheck() 指定の日付が有効かどうかを検査する

関数 用途

Page 257: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

日付 (OCIDate)

オブジェクト・リレーショナル・データ型 9-9

};typedef struct person person;

OCIError *err;person *tim;sword status; /* error status */uword invalid;OCIDate last_day, next_day;text buf[100], last_day_buf[100], next_day_buf[100];ub4 buflen = sizeof(buf); /* For this example, assume the OCIEnv and OCIError have been* initialized as described in Chapter 2. *//* Pin tim person object in the object cache. See Chapter 6 for* information about pinning. For this example, assume that* tim is pointing to the pinned object. *//* set the start date of tim */OCIDateSetTime(&tim->start_date,8,0,0);OCIDateSetDate(&tim->start_date,1990,10,5)

/* check if the date is valid */if (OCIDateCheck(err, &tim->start_date, &invalid) != OCI_SUCCESS)/* error handling code */

if (invalid)/* error handling code */

/* get the last day of start_date’s month */if (OCIDateLastDay(err, &tim->start_date, &last_day) != OCI_SUCCESS)/* error handling code */

/* get date of next named day */if (OCIDateNextDay(err, &tim->start_date, "Wednesday", strlen("Wednesday"), &next_day) != OCI_SUCCESS)/* error handling code *//* convert dates to strings and print the information out *//* first convert the date itself*/buflen = sizeof(buf);if (OCIDateToText(err, &tim->start_date, FMT, sizeof(FMT)-1, LANG,

sizeof(LANG)-1, &buflen, buf) != OCI_SUCCESS)/* error handling code */

/* now the last day of the month */buflen = sizeof(last_day_buf);if (OCIDateToText(err, &last_day, FMT, sizeof(FMT)-1, LANG, sizeof(LANG)-1, &buflen, last_day_buf) != OCI_SUCCESS)/* error handling code */

Page 258: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

数値 (OCINumber)

9-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

/* now the first Wednesday after this date */buflen = sizeof(next_day_out);if (OCIDateToText(err, &next_day, FMT, sizeof(FMT)-1, LANG,

sizeof(LANG)-1, &buflen, next_day_buf) != OCI_SUCCESS)/* error handling code */

/* print out the info */printf("For: %s\n", buf);printf("The last day of the month is: %s\n", last_day_buf);printf("The next Wednesday is: %s\n", next_day_buf);

出力は次のようになります。

For: Monday, May 13, 1996The last day of the month is: Friday, May 31The next Wednesday is: Wednesday, May 15

数値 (OCINumber)OCINumberデータ型は、Oracleの数値データ型 (NUMBER、FLOAT、DECIMALなど )を表すのに使用する不明確な構造体です。

この型は、バインド・コールまたは定義コールで、外部型コード SQLT_VNUを使用してバインドし、定義できます。

OCINumber操作関数を機能別にまとめて次の表に示します。 指定されない限り、これらの表の用語 "数値 "は、OCINumber型の値をさします。

関連項目 : すべての関数のプロトタイプおよび説明は、第 15章の「OCIデータ型マッピング関数および操作関数」を参照してください。

Page 259: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

数値 (OCINumber)

オブジェクト・リレーショナル・データ型 9-11

数値算出関数算術演算を行う関数は、次のとおりです。

数値変換関数次の関数では、実数および整数、文字列の間で変換を実行します。

関数 用途

OCINumberAbs() 数値の絶対値を入手する

OCINumberAdd() 2つの数値を合計する

OCINumberCeil() 数値の上限値を入手する

OCINumberDiv() 1つの数値を別の数値で除算する

OCINumberFloor() 数値の下限値を入手する

OCINumberMod() 2つの数値の除算からモジュラスを入手する

OCINumberMul() 2つの数値を乗算する

OCINumberNeg() 数値を否定演算する

OCINumberRound() 数値を指定の桁まで丸める

OCINumberSign() 数値の符号を入手する

OCINumberSqrt() 数値の平方根を入手する

OCINumberSub() 1つの数値を別の数値から減算する

OCINumberTrunc() 数値を指定の桁で切り捨てる

OCINumberSIgn() 指定の数値の符号を戻す

関数 用途

OCINumberToInt() 数値を整数に変換する

OCINumberFromInt() 整数を数値に変換する

OCINumberToReal() 数値を実数に変換する

OCINumberFromReal() 実数を数値に変換する

OCINumberToText() 数値を文字列に変換する

OCINumberFromText() 文字列を数値に変換する

Page 260: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

数値 (OCINumber)

9-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

指数関数および対数関数指数演算および対数演算を行う関数は、次のとおりです。

三角関数数値に対して三角関数演算を行う関数は、次のとおりです。

数値割当ておよび比較関数数値に対して代入演算および比較演算を行う関数は、次のとおりです。

関数 用途

OCINumberPower() 指定の数値指数の数値基数をとる

OCINumberExp() 基数の指数をとる

OCINumberLog() 指定の基数の対数をとる

OCINumberLn() 自然対数(基数)をとる

OCINumberIntPower() 指定の整数累乗の数値基数をとる

関数 用途

OCINumberArcCos() アーク・コサイン(弧の余弦)を計算する

OCINumberArcSin() アーク・サイン(弧の正弦)を計算する

OCINumberArcTan() / OCINumberArcTan2() 2つの数字の円弧タンジェントを演算する

OCINumberCos() コサイン(余弦)を計算する

OCINumberHypCos() コサイン・ハイパボリック(余弦双曲線)を計算する

OCINumberSin() サイン(正弦)を計算する

OCINumberHypSin() サイン・ハイパボリック(正弦双曲線)を計算する

OCINumberTan() タンジェント(正接)を計算する

OCINumberHypTan() タンジェント・ハイパボリック(正接双曲線)を計算する

関数 用途

OCINumberAssign() 1つの数値を別の数値に代入する

OCINumberCmp() 2つの数値を比較する

OCINumberIsZero() 0に等しいかテストする

Page 261: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

数値 (OCINumber)

オブジェクト・リレーショナル・データ型 9-13

数値の例次の例は、OCINumber型の属性の処理方法を示しています。

struct person{OCINumber sal;};typedef struct person person;OCIError *err;person* steve;person* scott;person* jason;OCINumber *stevesal;OCINumber *scottsal;OCINumber *debsal;sword status;int inum;double dnum;OCINumber ornum;char buffer[21];ub4 buflen;sword result;

/* For this example, assume OCIEnv and OCIError are initialized. *//* For this example, assume that steve, scott and jason are pointing to person objects which have been pinned in the object cache. */

stevesal = &steve->sal;scottsal = &scott->sal;debsal = &jason->sal;

/* initialize steve’s salary to be $12,000 */OCINumberInit(err, stevesal);inum = 12000;status = OCINumberFromInt(err, &inum, sizeof(inum), OCI_NUMBER_SIGNED,

stevesal);if (status != OCI_SUCCESS) /* handle error from OCINumberFromInt */;

/* initialize scott’s salary to be same as steve */OCINumberAssign(err, stevesal, scottsal);

/* initialize jason’s salary to be 20% more than steve’s */dnum = 1.2;

OCINumberSetZero() 数値を 0に初期化する

関数 用途

Page 262: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

数値 (OCINumber)

9-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

status = OCINumberFromReal(err, &dnum, DBL_DIG, &ornum);if (status != OCI_SUCCESS) /* handle error from OCINumberFromReal */;status = OCINumberMul(err, stevesal, &ornum, debsal);if (status != OCI_SUCCESS) /* handle error from OCINumberMul */;

/* give scott a 50% raise */dnum = 1.5;status = OCINumberFromReal(err, &dnum, DBL_DIG, &ornum);if (status != OCI_SUCCESS) /* handle error from OCINumberFromReal */;status = OCINumberMul(err, scottsal, &ornum, scottsal);if (status != OCI_SUCCESS) /* handle error from OCINumberMul */;

/* double steve’s salary */status = OCINumberAdd(err, stevesal, stevesal, stevesal);if (status != OCI_SUCCESS) /* handle error from OCINumberAdd */;

/* get steve’s salary in integer */status = OCINumberToInt(err, stevesal, sizeof(inum), OCI_NUMBER_SIGNED,

&inum);if (status != OCI_SUCCESS) /* handle error from OCINumberToInt */;

/* inum is set to 24000 *//* get jason’s salary in double */status = OCINumberToReal(err, debsal, sizeof(dnum), &dnum);if (status != OCI_SUCCESS) /* handle error from OCINumberToReal */;

/* dnum is set to 14400 *//* print scott’s salary as DEM0001,8000.00 */buflen = sizeof(buffer);status = OCINumberToText(err, scottsal, "C0999G9999D99", 13,

"NLS_NUMERIC_CHARACTERS=’.,’ NLS_ISO_CURRENCY=’Germany’", 54, &buflen, buffer);

if (status != OCI_SUCCESS) /* handle error from OCINumberToText */;printf("scott’s salary = %s\n", buffer);

/* compare steve and scott’s salaries */status = OCINumberCmp(err, stevesal, scottsal, &result);if (status != OCI_SUCCESS) /* handle error from OCINumberCmp */;

/* result is positive *//* read jason’s new salary from string */status = OCINumberFromText(err, "48,000.00", 9, "99G999D99", 9,

"NLS_NUMERIC_CHARACTERS=’.,’", 27, debsal);if (status != OCI_SUCCESS) /* handle error from OCINumberFromText */;/* jason’s salary is now 48000.00 */

Page 263: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

固定長または可変長文字列 (OCIString)

オブジェクト・リレーショナル・データ型 9-15

固定長または可変長文字列 (OCIString)固定長または可変長の文字列データは、Cプログラムに対して OCIString *として表現されます。

文字列の長さには、NULL文字は含まれていません。

OCIString *型の変数のバインドと定義には、外部型コード SQLT_VSTを使用します。

関連項目 : すべての関数のプロトタイプおよび説明は、第 15章の「OCIデータ型マッピング関数および操作関数」を参照してください。

文字列関数Cのプログラマは、次の関数を使用して文字列のインスタンスを操作できます。

文字列の例この例では、テキスト文字列を文字列に代入し、文字列の文字列部分へのポインタを文字列サイズとともに入手して、印刷します。

OCIStringAssignText()で、vstring1パラメータを渡すために二重間接指定を使用していることに注意してください。

OCIEnv *envhp;OCIError *errhp;OCIString *vstring1 = (OCIString *)0;OCIString *vstring2 = (OCIString *)0;text c_string[20];text *text_ptr;sword status;

strcpy(c_string, "hello world");/* Assign a text string to an OCIString */status = OCIStringAssignText(envhp, errhp, c_string, (ub4)strlen(c_string),&vstring1);

関数 用途

OCIStringAssign() 1つの文字列を別の文字列に代入する

OCIStringAssignText() テキスト文字列を文字列に代入する

OCIStringAllocSize() 文字列メモリーの割り当てられたサイズ(バイト単位)を入手する

OCIStringPtr() 文字列の文字列部分へのポインタを入手する

OCIStringSize() 文字列サイズを入手する

OCIStringResize() 文字列メモリーをサイズ変更する

Page 264: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

ロー (OCIRaw)

9-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

/* Memory for vstring1 is allocated as part of string assignment */

status = OCIStringAssignText(envhp, errhp, "hello again", (ub4)strlen("This is a longer string."),&vstring1);/* vstring1 is automatically resized to store the longer string */

/* Get a pointer to the string part of vstring1 */text_ptr = OCIStringPtr(envhp, vstring1);/* text_ptr now points to "hello world" */printf("%s\n", text_ptr);

ロー (OCIRaw)可変長ロー・データは、OCIRaw *データ型を使用して Cで表現されます。

OCIRaw *型の変数のバインドと定義には、外部型コード SQLT_LVBを使用します。

関連項目 : すべての関数のプロトタイプおよび説明は、第 15章の「OCIデータ型マッピング関数および操作関数」を参照してください。

ロー・ファンクションOCIRawの操作を行う関数は、次のとおりです。

ローの例この例では、RAWデータのブロックを設定し、そのデータへのポインタを取得します。

OCIRawAssignBytes()のコールで二重間接指定を使用していることに注意してください。

OCIEnv *envhp;OCIError *errhp;sword status;ub1 data_block[10000];

関数 用途

OCIRawAssignBytes() ロー・データ (ub1 *)を OCIRaw *に代入する

OCIRawAssignRaw() 1つの OCIRaw *を別の OCIRaw *に代入する

OCIRawAllocSize() ロー・メモリーの割り当てられたサイズ(バイト単位)を入手する

OCIRawPtr() ロー・データへのポインタを入手する

OCIRawSize() ロー・データのサイズを入手する

OCIRawResize() 可変長 RAWデータのメモリーのサイズ変更を行う。

Page 265: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コレクション (OCITable、OCIArray、OCIColl、OCIIter)

オブジェクト・リレーショナル・データ型 9-17

ub4 data_block_len = 10000;OCIRaw *raw1;ub1 *raw1_pointer;

/* Set up the RAW *//* assume ’data_block’ has been initialized */status = OCIRawAssignBytes(envhp, errhp, data_block, data_block_len, &raw);

/* Get a pointer to the data part of the RAW */raw1_pointer = OCIRawPtr(envhp, raw1);

コレクション (OCITable、OCIArray、OCIColl、OCIIter)Oracle8では、可変長配列 (varrays)とネストした表の 2つのタイプのコレクションが提供されます。 Cアプリケーションでは、varraysはOCIArray *として表現され、ネストした表は、OCITable *として表現されます。 これらの両方のデータ型は(後述する OCICollとOCIIterと併せて)、不明確な構造体です。

さまざまな汎用コレクション関数により、コレクション・データを操作できます。 汎用コレクション関数は、varrayとネストした表の両方に使用できます。 また、ネストした表に特有の一連の関数は、9-20ページの「ネストした表の操作関数」を参照してください。

varrayまたはネストした表のインスタンスは、OCIObjectNew()を使用して割り当て、OCIObjectFree()を使用して解放できます。

関連項目 : すべての関数のプロトタイプおよび説明は、第 15章の「OCIデータ型マッピング関数および操作関数」を参照してください。

汎用コレクション関数Oracle8では、可変長配列 (varrays)とネストした表の 2つのタイプのコレクションが提供されます。 varrayとネストした表は、どちらも総称コレクション型のサブタイプとみなすことができます。

Cでは、総称コレクションを OCIColl *として、varrayを OCIArray *として、ネストした表を OCITable *として表現します。Oracleには、総称コレクションを操作するための一連の関数群 (OCIColl *など )があります。 これらの関数は、OCICollGetElem()のように接頭辞OCICollで始まります。 OCIColl*()関数をコールして、varrayとネストした表を操作することもできます。

汎用コレクション関数は、2つの主なカテゴリにグループ化できます。

■ varrayまたはネストした表のデータを操作するグループ

■ コレクション反復子を使用してコレクションをスキャンするグループ

汎用コレクション関数は、varrayを操作する関数の完全な集合です。 その他の関数は、特にネストした表で操作するための関数です。 これらの関数は、OCITableExists()のように接頭辞

Page 266: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コレクション (OCITable、OCIArray、OCIColl、OCIIter)

9-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCITableで識別できます。 これらについては、9-20ページの「ネストした表の操作関数」で説明しています。

注意 : コレクション関数に渡された索引は、0(ゼロ )が基数です。

コレクション・データ操作関数次の汎用関数は、コレクション・データを操作します。

コレクション・スキャン・ファンクション次の汎用関数により、コレクション反復子を使用してコレクションをスキャンできます。 反復子は、OCIIter型であり、最初に OCIIterCreate()をコールして作成します。

関数 用途

OCICollAppend() 要素を追加する

OCICollAssignElem() 指定の索引位置に要素を割り当てる

OCICollAssign() 1つのコレクションを別のコレクションに割り当てる

OCICollGetElem() 指定の索引位置にある要素へのポインタを入手する

OCICollMax() コレクションの上限を入手する

OCICollSize() コレクションの現行のサイズを入手する

OCICollTrim() コレクションの終わりから n個の要素を切り捨てる

関数 用途

OCIIterCreate() コレクションをスキャンするための反復子を作成する

OCIIterDelete() 反復子を削除する

OCIIterGetCurrent() 反復子が指し示す現行の要素へのポインタを入手する

OCIIterInit() 反復子を初期化して指定のコレクションをスキャンする

OCIIterNext() 次要素へのポインタを入手する

OCIIterPrev() 前要素へのポインタを入手する

Page 267: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コレクション (OCITable、OCIArray、OCIColl、OCIIter)

オブジェクト・リレーショナル・データ型 9-19

Varray/コレクション反復子の例この例では、コレクション反復子を作成し、それを使用して varray(可変長配列 )をスキャンします。

OCIEnv *envhp; OCIError *errhp; text *text_ptr; sword status; OCIArray *clients; OCIString *client_elem; OCIIter *iterator; boolean eoc; dvoid *elem;OCIInd *elemind;

/* Assume envhp, errhp have been initialized *//* Assume clients points to a varray */

/* Print the elements of clients */ /* To do this, create an iterator to scan the varray */ status = OCIIterCreate(envhp, errhp, clients, &iterator);

/* Get the first element of the clients varray */ printf("Clients’ list:\n"); status = OCIIterNext(envhp, errhp, iterator, &elem, (dvoid **) &elemind, &eoc);

while (!eoc && (status == OCI_SUCCESS)){ client_elem = *(OCIString)**elem; /* client_elem points to the string */

/* the element pointer type returned by OCIIterNext() via ’elem’ is the same as that of OCICollGetElem(). Refer to OCICollGetElem() for details. */

/* client_elem points to an OCIString descriptor, so to print it out, get a pointer to where the text begins */ text_ptr = OCIStringPtr(envhp, client_elem);

/* text_ptr now points to the text part of the client OCIString, which is a NULL-terminated string */

Page 268: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コレクション (OCITable、OCIArray、OCIColl、OCIIter)

9-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

printf("%s\n", text_ptr); status = OCIIterNext(envhp, errhp, iterator, &elem, (dvoid **)&elemind, &eoc);}

if (status != OCI_SUCCESS){ /* handle error */}

/* destroy the iterator */status = OCIIterDelete(envhp, errhp, &iterator);

ネストした表の操作関数表は、その名前が示すとおり、変数または属性、パラメータ、列として別の表の中に入れる、つまりネストすることができます。 ネストした表には、OCITableDelete()関数で削除された要素がある場合があります。

たとえば、10個の要素を指定して作成した表があり、0から 4と 9の索引を持つ要素をOCITableDelete()で削除したとします。既存の最初の要素は要素 5になり、既存の最後の要素は要素 8になります。

前述のように、汎用コレクション関数を使用しても、ネストした表へのマッピングやネストした表の操作ができます。 さらに、次に示すネストした表専用の関数もあります。 ネストした表専用の関数は、varrayでは使用できません。

ネストした表の要素順序ネストした表がオブジェクト・キャッシュにフェッチされた場合、その要素には、0(ゼロ )から始まり要素数から 1を引いた数で終わる順序が一時的に付けられます。たとえば、40個の要素を持つ表では、0から 39まで順序付けが行われます。

関数 用途

OCITableDelete() 指定の索引位置にある要素を削除する

OCITableExists() 指定の索引位置に要素が存在するかどうかをテストする

OCITableFirst() 表の最初の既存要素の索引を戻す

OCITableLast() 表の最後の既存要素の索引を戻す

OCITableNext() 表の次の既存要素の索引を戻す

OCITablePrev() 表の前の既存要素の索引を戻す

OCITableSize() 削除した要素を除いた表のサイズを戻す

Page 269: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

コレクション (OCITable、OCIArray、OCIColl、OCIIter)

オブジェクト・リレーショナル・データ型 9-21

これらの位置序数を使用して、要素の値のフェッチと代入が行われます(たとえば、要素 iへのフェッチや、要素 jへの代入など。iと jは、指定の表の有効な位置序数です)。

表をデータベースにコピーすると、一時的な順序付けは失われます。 表の要素に対して削除の操作を行うことがあります。 操作を削除すると、一時的な "空き "が作成されます。つまり残りの表要素の配置順序は変更されません。

Page 270: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

REF (OCIRef)

9-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

REF (OCIRef)Oracle8の REF(参照 )とは、オブジェクトを識別する識別子です。 そして、一意にオブジェクトを検索する不明確な構造体です。 REFによって、オブジェクトは別のオブジェクトを指し示すことができます。

Cアプリケーションでは、OCIRef *で REFを表現します。

関連項目 : すべての関数のプロトタイプおよび説明は、第 15章の「OCIデータ型マッピング関数および操作関数」を参照してください。

REF操作関数REF操作を行う関数は、次のとおりです。

REFの例この例では、2つの REFを NULLかどうかテストし、両者が等しいか比較した後、一方のREFをもう一方の REFに代入します。

OCIRefAssign()のコールで二重間接指定を使用していることに注意してください。

OCIEnv *envhp;OCIError *errhp;sword status;boolean refs_equal;OCIRef *ref1, ref2;

/* assume refs have been initialized to point to valid objects *//*Compare two REFs for equality */refs_equal = OCIRefIsEqual(envhp, ref1, ref2);printf("After first OCIRefIsEqual:\n");if(refs_equal) printf("REFs equal\n");else

関数 用途

OCIRefToHex() REFを 16進数文字列に変換する

OCIRefAssign() 1つの REFを別の REFに代入する

OCIRefClear() REFの消去または NULL化

OCIRefIsEqual() 2つの REFが等しいか比較する

OCIRefFromHex() 16進数文字列を REFに変換する

OCIRefIsNull() REFが NULLかどうかをテストする

OCIRefHexSize() REFの 16進数文字列表現のサイズを戻す。

Page 271: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト型情報の格納およびアクセス

オブジェクト・リレーショナル・データ型 9-23

printf("REFs not equal\n");

/*Assign ref1 to ref2 */status = OCIRefAssign (envhp, errhp, ref1, &ref2);if(status != OCI_SUCCESS) /*error handling*/

/*Compare the two REFs again for equality */refs_equal = OCIRefIsEqual(envhp, ref1, ref2);printf("After second OCIRefIsEqual:\n");if(refs_equal) printf("REFs equal\n");else printf("REFs not equal\n");

オブジェクト型情報の格納およびアクセス

記述子オブジェクトある型を CREATE TYPE文で作成すると、その型はサーバーに格納され、型記述子オブジェクト (TDO)に関連付けられます。 さらに、型の各データ属性、型の各メソッド、各メソッドの各パラメータ、メソッドが戻す結果の記述子オブジェクトが、データベースに格納されます。 各型の記述子オブジェクトに関連付けられた OCIデータ型のリストを次の表に示します。

OCI関数の中には (OCIBindObject()および OCIObjectNew()を含む )、TDOを入力パラメータとして必要とする関数があります。 アプリケーションで、その型の TDDをOCIType変数で取得できる OCITypeByName()をコールして TDOを取得できます。 TDOを取得すると、必要に応じて、その TDOをその他のコールに渡すことができます。

情報の型 OCIデータ型

型 OCIType

型属性 コレクション要素メソッド・パラメータ メソッドの結果

OCITypeElem

メソッド OCITypeMethod

Page 272: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト型情報の格納およびアクセス

9-24 Oracle8コール・インタフェース・プログラマーズ・ガイド

Page 273: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・アプリケーションでのバインディングおよび定義 10-1

10オブジェクト・アプリケーションでのバイン

ディングおよび定義

バインディングおよび定義の概念は、第 2章の「OCIプログラミングの基本」および第 5章の「バインディングと定義」で紹介および説明されています。 この章では、オブジェクト・アプリケーションを開発するときに必要な追加情報を提供します。 オブジェクト・データ型のバインドと定義の方法や、オブジェクト・サポート用に新たに追加されたデータ型についても説明します。

この章は、読者が前述の章でバインドと定義の基本を理解していることを前提としています。

この章は、次のトピックで構成されています。

■ バインディング

■ 問合せの定義

■ Oracle8 Cデータ型のバインドおよび定義

注意 : この章で説明されている機能性は、オブジェクト・オプションのある Oracle8 Enterprise Editionを購入された場合にのみ使用可能です。

Page 274: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

10-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

バインディングこの項目では、名前付きデータ型(オブジェクトやコレクションなど)と REFのバインについて説明します。

名前付きデータ型のバインド名前付きデータ型(オブジェクト型やコレクション)のバインドでは、OCIBindByName()または OCIBindByPos()の後にもう 1つのバインド・コールが必要です。 OCIBindObject()という OCIオブジェクト型バインド・コールで、オブジェクト型のバインド固有の追加属性を設定します。 OCIアプリケーションでは、このコールを使用して、オブジェクト・データ型の列を持つ表からデータをフェッチします。

OCIBindObject()コールでパラメータの 1つとして、名前付きデータ型の型記述子オブジェクト (TDO)を受け取ります。 TDO(データ型 OCIType)は、名前付きデータ型の作成時に作成され、データベースに格納されます。 TDOには、型とその属性についての情報が入っています。 アプリケーションでは、OCITypeByName()をコールして TDOを取得できます。

OCIBindObject()コールでは、名前付きデータ型バインド用の標識変数または構造体も設定します。

名前付きデータ型をバインドするときは、SQLT_NTYデータ型定数を使用して、バインドするプログラム変数のデータ型を指定します。 SQLT_NTYは、名前付きデータ型を表現する C構造体をバインドすることを示します。 この構造体へのポインタをバインド・コールに渡します。

場合によっては、名前付きデータ型の操作に 3つのバインド・コールが必要になることがあります。 たとえば、名前付きデータ型の静的配列を PL/SQL表にバインドするには、次の 3つのコールを呼び出さなければなりません。それらは OCIBindByName()およびOCIBindArrayOfStruct()、OCIBindObject()です。

関連項目 : これらのデータ型を使用した、データベースからの埋込みオブジェクトのフェッチについては、8-14ページの「埋込みオブジェクトのフェッチ」を参照してください。

その他の重要な情報は、10-3ページの「名前付きデータ型および REFバインドについての追加情報」を参照してください。

記述子オブジェクトの詳細は、9-23ページの「記述子オブジェクト」を参照してください。

Page 275: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

バインディング

オブジェクト・アプリケーションでのバインディングおよび定義 10-3

REFのバインディング名前付きデータ型と同様に、REFのバインドも 2ステップで処理します。 最初にOCIBindByName()または OCIBindByPos()をコールし、次に OCIBindObject()をコールします。

REFは、SQLT_REF データ型を使ってバインドします。 SQLT_REFを使用する場合、バインドするプログラム変数は、必ず OCIRef *型の変数でなければなりません。

関連項目 : REFのオブジェクトへのバインドおよび確保については、8-10ページの「サーバーからのオブジェクト参照の取得」を参照してください。

その他の重要な情報は、10-3ページの「名前付きデータ型および REFバインドについての追加情報」を参照してください。

名前付きデータ型および REFバインドについての追加情報この項目では、名前付きデータ型定義と REF定義を扱うときに注意しなければならない重要な追加情報を示します。 メモリー割当てと標識変数の使用方法についての参照先も示します。

■ バインドするデータ型が SQLT_NTYである場合は、OCIBindObject()コールの標識構造体パラメータ (dvoid ** indpp)が使用され、スカラー標識は完全に無視される。

■ データ型が SQLT_REFの場合、スカラー標識が使われ、標識構造体パラメータOCIBindObject()は完全に無視される。

■ 標識構造体の使用はオプション。 OCIBindObject()コールに indppパラメータで NULLポインタを渡すことができます。 バインド時、これはオブジェクトがアトミック NULLではなく、オブジェクトのどの属性も NULLではないことを意味します。

■ OCIBindObject()コールの標識構造体サイズ・ポインタ indspおよびプログラム変数サイズ・ポインタ pgvspは、オプションです。 これらのパラメータが必要ない場合は、NULLを渡すことができます。

配列バインドに関する情報配列挿入または配列フェッチ用に、名前付きデータ型または REFの配列バインドを行うには、ユーザーはポインタの配列を適切な型のバッファ(事前に割当て済みか)に渡す必要があります。 同様に、スカラー標識の配列 (SQLT_REF 型 )または標識構造体へのポインタ配列(SQLT_NTY型用 )を渡す必要があります。

関連項目 : SQLT_NTYの詳細は、3-17ページの「新しい OCI 8.0外部データ型」を参照してください。

Page 276: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

問合せの定義

10-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

問合せの定義この項では、名前付きデータ型(オブジェクト、コレクションなど)と REFの定義について説明します。

名前付きデータ型出力変数の定義名前付きデータ型 (オブジェクト型、ネストした表、varray)の定義には、2つの定義コールが必要です。 アプリケーションで最初に OCIDefineByPos()をコールし、SQLT_NTYを dty パラメータに指定します。 OCIDefineByPos()に続いて、OCIDefineObject()をコールする必要があります。 この場合、OCIDefineByPos()のデータ・バッファ・ポインタは無視され、名前付きデータ型定義に関係するその他の属性は、OCIオブジェクト属性定義コールであるOCIDefineObject()を使用して設定されます。

そのコールでは名前付きデータ型定義用の SQLT_NTYデータ型定数を指定します。 この場合、アプリケーションでは結果のデータを名前付きデータ型のホスト言語表現の中にフェッチします。 通常、これはオブジェクト型トランスレータで生成する C構造体になります。

OCIDefineObject()コールを行うときは、C構造体のアドレスへのポインタ(事前割当て済みまたはそれ以外)を定義する必要があります。 オブジェクトは、OCIObjectNew()を使用して作成され、キャッシュまたはユーザー定義のメモリーに割り当てられます。

注意 : 名前付きデータ型の定義に関する、その他の重要な情報は、10-4ページの「名前付きデータ型と REF定義、および PL/SQL OUTバインドの追加情報」を参照してください。

REF出力変数の定義名前付きデータ型と同様に、REF出力変数の定義も 2ステップで処理します。 第 1ステップで OCIDefineByPos()をコールし、第 2ステップで OCIDefineObject()をコールします。 また、名前付きデータ型の場合と同様に、OCIDefineByPos()の dtyパラメータに SQLT_REFデータ型定数を渡します。

SQLT_REFでは、アプリケーションで結果として得るデータを OCIRef *型変数にフェッチすることを示します。 第 6章で説明するとおり、この REFをオブジェクト確保およびナビゲーションの一部として使えます。

注意 : REFの定義に関するその他の重要な情報は、10-4ページの「名前付きデータ型とREF定義、および PL/SQL OUTバインドの追加情報」を参照してください。

名前付きデータ型と REF定義、および PL/SQL OUTバインドの追加情報この項では、名前付きデータ型定義と REF定義を扱うときに注意しなければならない重要な追加情報を示します。 メモリー割当てと標識変数の使用方法についての参照先も示します。

PL/SQL OUTバインドとは、プレースホルダを PL/SQLブロックの出力変数にバインドすることを言います。 SQL文では出力バッファを定義コールで設定しますが、PL/SQLブロッ

Page 277: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

問合せの定義

オブジェクト・アプリケーションでのバインディングおよび定義 10-5

クでは出力バッファをバインド・コールで設定します。 詳細は、5-5ページの「PL/SQLのプレースホルダのバインディング」を参照してください。

■ 定義するデータ型が SQLT_NTYである場合は、OCIDefineObject()コールの標識構造体パラメータ (dvoid ** indpp)が使用され、スカラー標識は完全に無視される。

■ データ型が SQLT_REFの場合、スカラー標識が使われ、OCIDefineObject()の標識構造体のパラメータは完全に無視される。

■ 標識構造体の使用はオプション。 OCIDefineObject()コールの indppパラメータでNULLポインタを渡すことができます。 フェッチまたは PL/SQL OUTバインド時、ユーザーが NULL情報に関知しないことを意味します。

■ SQL定義または PL/SQL OUTバインドでは、出力変数または標識のいずれかの事前割当て済みメモリーにユーザーが渡した場合、事前割当て済みメモリーは、結果データを格納するために使用され、2次メモリー(ライン外メモリー)がある場合は割当てが解除になる。 事前に割当てるメモリーは、キャッシュ (OCIObjectNew()コールの結果 )、またはクライアントのプライベートなメモリー領域から獲得できます。

注意 : クライアント・アプリケーションで、所有するメモリー領域からメモリーを割当てる場合、オブジェクトに二次的なライン外メモリーがないことを確認する必要があります。

■ SQL定義または PL/SQL OUTバインドでは、出力変数または標識に対して NULLアドレスを渡すと、その変数または標識用のメモリーは、OCIによって暗黙的に割り当てられる。

■ SQLT_NTY型の出力オブジェクトが (SQL定義または PL/SQL OUTバインドで )アトミック NULLである場合は、NULL標識構造体だけが(必要であれば暗黙的に)割り当てられ、そこにデータが挿入されて、オブジェクトがアトミック NULLであることが示される。 トップ・レベルのオブジェクト自体は、暗黙的に割り当てられません。

■ アプリケーションでは、OCIObjectFree()をコールして標識を解放できる。 トップ・レベルのオブジェクトがある場合(アトミック NULLでないNULLオブジェクトの場合など)、OCIObjectFree()でトップ・レベルのオブジェクトを解放すると標識も解放されます。 オブジェクトがアトミック NULLである場合は、トップ・レベルのオブジェクトがないので、標識を個別に解放する必要があります。

■ OCIDefineObject()コールの標識構造体サイズ・ポインタ indsp、およびプログラム変数サイズ・ポインタ pgvspは、オプションです。 これらのパラメータが必要ない場合は、NULLを渡すことができます。

配列定義に関する情報名前付きデータ型または REFの配列定義を行うには、ユーザーはポインタ配列を適切な型のバッファ(事前に割当て済みかまたはそれ以外)に渡す必要があります。 同様に、スカラー標識の配列 (SQLT_REF 型 )またはポインタ配列を、標識構造体 (SQLT_NTY型 )に渡す必要があります。

Page 278: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 Cデータ型のバインドおよび定義

10-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

Oracle8 Cデータ型のバインドおよび定義これまでの章では、OCIのバインド操作と定義操作について説明しています。 4-5ページの「バインディング」では、OCIバインド操作の基本について説明し、4-11ページの「定義」では、OCI定義操作の基本について説明しています。名前付きデータ型および REFのバインディングおよび定義については、第 5章の「バインディングと定義」で説明しています。

バインドと定義の基本的な機能に関する章では、アプリケーションで SQL文の入力(バインド)値として、または問合せに対する出力(定義)バッファとしてスカラー変数またはスカラーの配列を使用する方法を示しています。

名前付きデータ型と REFに関する章では、オブジェクトまたは参照をバインドまたは定義する方法を示しています。 第 8章ではこれを展開させ、オブジェクト参照の確保およびオブジェクト・ナビゲーション、埋込みインスタンスのフェッチについて説明しています。

この節では、この章で説明しているデータ型マッピングに従って、個々の属性値のバインドと定義の方法を説明します。

この章で定義する型の 1つの変数 (OCINumber、OCIStringなど )は、一般にアプリケーションで宣言でき、適切なデータ型コードが指定される限り、OCIバインドまたは定義操作で直接使用できます。 次の表は、Cマッピングと共にバインドおよび定義で使えるデータ型と、バインドまたは定義コールの dty(データ型コード )で指定する必要のある、OCI外部データ型のリストです。

注 1: OCIString *型の定義変数にデータをフェッチするには、最初に OCIStringResize()ルーチンを使用して文字列のサイズを設定してください。 そのためには、記述操作によって選択リスト・データの長さを取得することが必要な場合があります。 同様に、OCIRaw *も最初に OCIRawResize()でサイズを決定する必要があります。

表 10–1 バインドおよび定義用のデータ型マッピング

データ型 Cマッピング OCIの外部データ型とコード

Oracle数値 OCINumber VARNUM(SQLT_VNU)

Oracle日付 OCIDate SQLT_ODT

VARCHAR2 OCIString * SQLT_VST(注 1を参照 )

RAW OCIRaw * SQLT_LVB(注 1を参照 )

CHAR OCIString * SQLT_VST

OBJECT struct * 名前付きデータ型 (SQLT_NTY)

REF OCIRef * REF(SQLT_REF)

VARRAY OCIArray * 名前付きデータ型 (SQLT_NTY)

ネストした表 OCITable * 名前付きデータ型 (SQLT_NTY)

Page 279: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 Cデータ型のバインドおよび定義

オブジェクト・アプリケーションでのバインディングおよび定義 10-7

次の項では、Cにマッピングしたデータ型の OCIアプリケーションでの使用例を示します。

関連項目 : OCI外部データ型についての説明、およびデータ型コードのリストは、第 3章の「データ型」を参照してください。

Page 280: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 Cデータ型のバインドおよび定義

10-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

バインドおよび定義の例この項では、OCIのバインド操作と定義操作で OCINumber型の変数を使用する例を示します。

注意 : この項の例は、特定の OCI作業を実行するのに使用されるコールのフローを説明します。 ここでは拡張擬似コードを使用しています。 実際の関数名を使用していますが、簡素化のためにパラメータと型キャストは一部だけ示します。 また、ハンドルの割当てなど、必要なその他の OCIコールも省略しています。

この例では、次のような personというオブジェクト型が作成されていると仮定します。

CREATE TYPE person AS OBJECT(name varchar2(30),salary number);

この型を使用して、person型の列を持つ employees(従業員 )表を作成します。

CREATE TABLE employees(emp_id number,job_title varchar2(30),emp person);

OTTで、personについて次の C構造体と NULL標識構造体を生成します。

struct person{ OCIString * name;

OCINumber salary;};typedef struct person person;

struct person_ind{ OCIInd _atomic;

OCIInd name;OCIInd salary;}

typedef struct person_ind person_ind;

employees表は値が入り、OCIアプリケーションは personの変数を宣言するとします。

person *my_person;

OCIアプリケーションで次のように、SELECT文によってオブジェクトをその変数にフェッチしたとします。

text *mystmt = (text *) "SELECT person FROM employeesWHERE emp.name=’ANDREA’";

これには、適切な名前付きデータ型の OCI定義コールを使って、my_personをこの文の出力変数として定義する必要があります。これは 5-15ページの「拡張バインド操作」で説明されています。 文を実行すると、‘ANDREA’という名の personオブジェクトが my_person変数内に取り出されます。

Page 281: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 Cデータ型のバインドおよび定義

オブジェクト・アプリケーションでのバインディングおよび定義 10-9

オブジェクトが my_personに取り出されると、OCIアプリケーションで my_personの名前や給与などの属性にアクセスできるようになります。

アプリケーションでは、別の従業員の給与を、次のように Andreaと同様に更新します。

text *updstmt = (text *) "UPDATE employees SET emp.salary = :newsal WHERE emp.name = ‘MONGO’"

Andreaの給与は (my_person->salaryに格納される )、プレースホルダの :newsalにバインドされ、BARNUMの外部データ型をバインド操作に指定します(データ型 code=6)。

OCIBindByName(...,":newsal",...,&my_person->salary,...,6,...);OCIStmtExecute(...,updstmt,...)

文を実行すると、データベースにあるMongの給与が、my_personに保存されているように、Andreaの給与と等しくなります。

その反対に、Mongoの給与をデータベースに問合わせてから給与に必要な割当てを行うことにより、アプリケーションで Andreaの給与をMongoの給与と同額になるよう更新できます。

text *selstmt = (text *) "SELECT emp.salary FROM employees WHERE emp.name = ‘MONGO’"

OCINumber mongo_sal;...OCIDefineByPos(...,1,...,&mongo_sal,...,6,...);OCIStmtExecute(...,selstmt,...);OCINumberAssign(...,&mongo_sal, &my_person->salary);

この場合には、アプリケーションで OCINumberの型の出力変数を宣言し、それを定義のステップで使用します。 この場合には、位置 1の出力変数を定義し、適切なデータ型コード(VARNUMには 6)を使用します。

mongo_salという OCINumberに給与の値をフェッチし、OCI関数 OCINumberAssign()を使用して、現在キャッシュ内にある Andreaオブジェクトのコピーに新しい給与を割り当てます。 データベース内にあるデータを変更するには、変更内容をサーバーにフラッシュする必要があります。

給与更新の 3つの例前の項では、Oracle8の新しいデータ型がバインド操作と定義操作にもたらす柔軟性を表す例を示しました。 この項では、同じ操作を異なる方法でどのように実行するかを説明します。 OCIアプリケーションにおける Oracle8の新しいデータ型のさまざまな使用方法を示すことが目的です。

この項の例は、特定の OCI作業を実行するのに使用されるコールのフローを説明します。 ここでは拡張擬似コードを使用しています。 実際の関数名を使用していますが、簡素化のためにパラメータと型キャストは一部だけ示します。 また、ハンドルの割当てなど、必要なその他の OCIコールも省略しています。

Page 282: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 Cデータ型のバインドおよび定義

10-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

シナリオこれから示す例のシナリオは、次のとおりです。

1. ‘BRUCE’という名の従業員が、病院の employeesデータベースに存在します(前の項の person型および employees表作成文を参照)。

2. Bruceの現在の職種は ‘RADIOLOGIST’です。

3. Bruceは ‘RADIOLOGY_CHIEF’に昇進したため、それに伴って昇給があります。

4. 次に示すように、病院の給与はドル単位の整数値とし、職務に応じて設定し、salariesという表に格納します。

CREATE TABLE salaries(job_title varchar2(20),salary integer));

5. Bruceの給与を昇進にあわせて更新します。

上記の作業を達成するには、アプリケーションで ‘RADIOLOGY_CHIEF’に該当する給与をsalaries表から取り出し、Bruceの給与を更新します。 別のステップで、Bruceの新しい職務と変更済みオブジェクトをデータベースに書き込みます。

次のように person型の変数を宣言したとします。

person *my_person;

そして、Bruceに対応するオブジェクトをこの変数にフェッチしたとします。この場合に給与更新を実行するには、次の各項に示す 3通りの方法があります。

方法 1 - フェッチ、変換、割当てこの例では次の方法をとります。

1. 整変数を使用して従来の OCI定義を行い、データベースから新しい給与を検索します。

2. 整数を OCINumberに変換します。

3. 新しい給与を Bruceに割り当てます。

#define INT_TYPE 3 /* datatype code for sword integer define */

text *getsal = (text *) "SELECT salary FROM salariesWHERE job_title=’RADIOLOGY_CHIEF’

sword new_sal;OCINumber orl_new_sal;...OCIDefineByPos(...,1,...,new_sal,...,INT_TYPE,...);

/* define int output */OCIStmtExecute(...,getsal,...);

/* get new salary as int */OCINumberFromInt(...,new_sal,...,&orl_new_sal);

Page 283: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Oracle8 Cデータ型のバインドおよび定義

オブジェクト・アプリケーションでのバインディングおよび定義 10-11

/* convert salary to OCINumber */OCINumberAssign(...,&orl_new_sal, &my_person->salary);

/* assign new salary */

方法 2 - フェッチ、割当てこの方法では、方法 1のステップを 1つ省略します。

1. OCINumber型の出力変数を定義します。そのため値を検索した後の変換は必要ありません。

2. 新しい給与を Bruceに割り当てます。

#define VARNUM_TYPE 6 /* datatype code for defining VARNUM */

text *getsal = (text *) "SELECT salary FROM salaries WHERE job_title=’RADIOLOGY_CHIEF’OCINumber orl_new_sal;...OCIDefineByPos(...,1,...,orl_new_sal,...,VARNUM_TYPE,...); /* define OCINumber output */OCIStmtExecute(...,getsal,...); /* get new salary as OCINumber */OCINumberAssign(...,&orl_new_sal, &my_person->salary); /* assign new salary */

方法 3 - 直接フェッチこの方法では、操作全体を 1回の定義とフェッチで実行します。 出力変数を介在させる必要はなく、データベースから検索した値を、キャッシュに格納されているオブジェクトの給与属性に直接フェッチします。

1. Bruceはオブジェクト・キャッシュ内に確保されているため、その給与属性の位置を定義変数として使用し、その変数に直接実行し、フェッチを行います。

#define VARNUM_TYPE 6 /* datatype code for defining VARNUM */

text *getsal = (text *) "SELECT salary FROM salaries WHERE job_title=’RADIOLOGY_CHIEF’...OCIDefineByPos(...,1,...,&my_person->salary,...,VARNUM_TYPE,...); /* define bruce’s salary in cache as output variable */OCIStmtExecute(...,getsal,...); /* execute and fetch directly */

Page 284: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQLT_NTYバインド /定義の例

10-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

まとめと注意この 3つの例に示したように、Oracle8の Cデータ型を使用すると柔軟性のあるバインドと定義を実行できます。 たとえば、整数をフェッチし、OCINumberに変換して処理できます。この方法では、OCINumberを中間的な変数として使用し、それに問合せの結果を格納します。または、目的のオブジェクトの OCINumber属性にデータを直接フェッチすることもできます。

注意 : Oracle8 OCIのこれらすべての例では、問合せの実行前に出力変数が定義される場合に、結果として得られるデータは出力バッファに直接プリフェッチされることを覚えておいてください。

この 3つの例で確実に変更をデータベースに永続的に書き込むには、追加ステップが必要です。 そのステップでは、SQLの UPDATEコールと OCIトランザクションのコミット・コールを使用することがあります。

これらの例ではすべて定義操作を処理していますが、同じような状況がバインドにも当てはまります。

同様に、これらの例では OCINumber型だけを扱いましたが、この章のこれ以降で説明するその他の Oracle8の C型についても、同様に種々の操作ができます。

SQLT_NTYバインド /定義の例次の部分的なコードは、OCIBindObject()や OCIDefineObject()などの SQLT_NTYバインド・コールおよび定義コールの使用方法を示しています。 それぞれの例で、前に定義した SQL文を処理します。

バインドの例/*** This example performs a SQL insert statement*/STATICF void insert(envhp, svchp, stmthp, errhp, insstmt, nrows)OCIEnv *envhp;OCISvcCtx *svchp;OCIStmt *stmthp;OCIError *errhp;text *insstmt;ub2 nrows;{ orttdo *addr_tdo = NULLP(orttdo); address addrs; null_address naddrs; address *addr = &addrs; null_address *naddr = &naddrs; sword custno =300; OCIBind *bnd1p, *bnd2p;

Page 285: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQLT_NTYバインド /定義の例

オブジェクト・アプリケーションでのバインディングおよび定義 10-13

ub2 i;

/* define the application request */ checkerr(errhp, OCIStmtPrepare(stmthp, errhp, (text *) insstmt, (ub4) strlen((char *)insstmt), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));

/* bind the input variable */ checkerr(errhp, OCIBindByName(stmthp, &bnd1p, errhp, (text *) ":custno", (sb4) -1, (dvoid *) &custno, (sb4) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT)); checkerr(errhp, OCIBindByName(stmthp, &bnd2p, errhp, (text *) ":addr", (sb4) -1, (dvoid *) 0, (sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT)); checkerr(errhp, OCITypeByName(envhpx, errhp, svchpx, (const text *) SCHEMA, (ub4) strlen((char *)SCHEMA), (const text *) "ADDRESS_VALUE", (ub4) strlen((char *)"ADDRESS_VALUE"), OCI_DURATION_SESSION, &addr_tdo));

if(!addr_tdo) { DISCARD printf("Null tdo returned\n"); goto done_insert; }

checkerr(errhp, OCIBindObject(bnd2p, errhp, addr_tdo, (dvoid **) &addr, (ub4 *) 0, (dvoid **) &naddr, (ub4 *) 0));

定義の例/* ** This example executes a SELECT statement from a table which includes ** an object.*/

STATICF void selectval(envhp, svchp, stmthp, errhp)OCIEnv *envhp;OCISvcCtx *svchp;OCIStmt *stmthp;OCIError *errhp;{ orttdo *addr_tdo = NULLP(orttdo);

Page 286: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

SQLT_NTYバインド /定義の例

10-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

OCIDefine *defn1p, *defn2p; address *addr = (address *)NULL; sword custno =0; sb4 status;

/* define the application request */ checkerr(errhp, OCIStmtPrepare(stmthp, errhp, (text *) selvalstmt, (ub4) strlen((char *)selvalstmt), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));

/* define the output variable */checkerr(errhp, OCIDefineByPos(stmthp, &defn1p, errhp, (ub4) 1, (dvoid *) &custno, (sb4) sizeof(sword), SQLT_INT, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) OCI_DEFAULT));

checkerr(errhp, OCIDefineByPos(stmthp, &defn2p, errhp, (ub4) 2, (dvoid *) 0, (sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) OCI_DEFAULT));

checkerr(errhp, OCITypeByName(envhpx, errhp, svchpx, (const text *) SCHEMA, (ub4) strlen((char *)SCHEMA), (const text *) "ADDRESS_VALUE", (ub4) strlen((char *)"ADDRESS_VALUE"),OROODTSES, &addr_tdo));

if(!addr_tdo) { printf("NULL tdo returned\n"); goto done_selectval; }

checkerr(errhp, OCIDefineObject(defn2p, errhp, addr_tdo, (dvoid **) &addr, (ub4 *) 0, (dvoid **) 0, (ub4 *) 0));

checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT));

Page 287: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-1

11オブジェクトのキャッシュおよびオブジェク

ト・ナビゲーション

この章では、オブジェクトを Oracle8 Serverで操作するための OCI機能について説明します。 また OCIのオブジェクト・ナビゲーショナル・ファンクション・コールについても説明します。

この章は、次のトピックで構成されています。

■ 章の概要

■ オブジェクト・キャッシュおよびメモリー管理

■ オブジェクト・ナビゲーション

■ OCIナビゲーショナル関数

注意 : この章で説明されている機能性は、オブジェクト・オプションのある Oracle8 Enterprise Editionを購入された場合にのみ使用可能です。

Page 288: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

章の概要

11-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

章の概要この章はいくつかの項目に分かれており、Oracle8のオブジェクトを操作する OCIアプリケーションの作成も含めた基本的な概念を説明します。 OCIナビゲーショナル・ファンクション・コールについても説明します。

次の項があります。

■ オブジェクト・キャッシュおよびメモリー管理 - この項では、さらに洗練されたオプションを含む OCIオブジェクト・プログラミングについて詳しく説明します。

■ オブジェクト・ナビゲーション - この項では、Oracle8 OCIを使用した基本的なオブジェクト・ナビゲーションについて説明します。

■ OCIナビゲーショナル関数 - この項では、アプリケーションでオブジェクトのグラフをナビゲートできる OCI関数について説明します。

OCIナビゲーショナル・ファンクション全体の説明は、第 14章の「OCIナビゲーショナル関数と型関数」にあります。

オブジェクト・キャッシュおよびメモリー管理オブジェクト・キャッシュは、オブジェクトのルックアップとメモリー管理のサポートを提供するクライアント側メモリー・バッファです。 これは OCIアプリケーションでフェッチしたオブジェクト・インスタンスを格納し、追跡するためのものです。

アプリケーションで SQL SELECTまたは OCI確保操作によってオブジェクトをフェッチすると、オブジェクトのコピーがオブジェクト・キャッシュに格納されます。 SELECT文で直接フェッチされたオブジェクトは、「値によって」フェッチされ、確保できない参照不能のオブジェクトです。 確保できるのは参照可能オブジェクトだけです。

オブジェクトを確保するとき、適切なバージョンのオブジェクトがすでにキャッシュ内に存在していれば、サーバーからオブジェクトをフェッチする必要はありません。

Oracle8 OCIを使用して REFを参照解除し、オブジェクトを検索する各クライアント・プログラムでは、オブジェクト・キャッシュを利用します。 クライアント側のオブジェクト・キャッシュは、オブジェクト・モードで初期化されたすべての OCI環境ハンドルで割り当てられます。 1つのプロセスの複数のスレッドで、同一の OCI環境ハンドルを共有することによって同一のクライアント側キャッシュを共有できます。

オブジェクト・キャッシュ内には接続ごとに、各参照可能オブジェクトのコピーがそれぞれ1つあります。 1つの REFを複数回参照解除するか、等価な複数の REFを参照解除した場合は、オブジェクトの同一コピーが戻されます。

キャッシュ内にあるオブジェクトのコピーを変更した場合、変更内容をその他のプロセスに見えるようにするには、変更内容をサーバーにフラッシュする必要があります。 必要のなくなったオブジェクトは、確保解除つまり解放できます。そしてキャッシュからスワップ・アウトでき、それによって、オブジェクトが使用していたメモリー領域を解放できます。

Page 289: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-3

オブジェクト・キャッシュでは、キャッシュ内のすべてのオブジェクト・コピーと、それぞれに対応するデータベース内のオブジェクトとの間の関連付けが、メンテナンスされます。

オブジェクト・キャッシュではオブジェクト・コピーの内容は管理されず、オブジェクト・コピーが自動的にリフレッシュされることもありません。 アプリケーションでは、オブジェクト・コピーの内容が正しく一貫していることを確認する必要があります。 たとえば、アプリケーションでオブジェクト・コピーに挿入または更新、削除のマークを付けた後、トランザクションが異常終了したとします。この場合、オブジェクト・キャッシュではオブジェクト・コピーがマーク解除されるだけであり、コピーの削除や無効化は行われません。 アプリケーションで "recent"または "latest"を確保するか、オブジェクトのコピーを次のトランザクションでリフレッシュします。"any"を確保すると、以前異常上終了したトランザクションから、変更をコミットしていない同じオブジェクト・コピーを取得する場合があります。

関連項目 : 確保オプションの詳細は、11-6ページの「オブジェクト・コピーの確保」を参照してください。

オブジェクト・キャッシュは、OCIInitialize()を使用して OCI環境をオブジェクト・モードで初期化するときに作成されます。 同じサーバーに対して稼動中の各アプリケーション・プロセスには、図 11–1で示すような、専用のオブジェクト・キャッシュがあります。

Page 290: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

図 11–1 オブジェクト・キャッシュ

オブジェクト・キャッシュは、メモリーに現在あるオブジェクトの追跡、そのオブジェクトへの参照のメンテナンス、自動オブジェクト・スワッピングの管理、オブジェクトのメタ属性の追跡を行います。

キャッシュの一貫性およびコヒーレンスオブジェクト・キャッシュ内のオブジェクト・コピーと、データベース内の対応するオブジェクト間の値のコヒーレンスつまり一貫性は、自動的にはメンテナンスされません。 つまり、アプリケーションでオブジェクト・コピーを変更すると、その変更内容は、データベース内の対応するオブジェクトに自動的に適用されず、その逆も同様です。 オブジェクト・キャッシュでは、変更されたオブジェクト・コピーをデータベースにフラッシュする操作

Page 291: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-5

や、古いオブジェクト・コピーをデータベースの最新値にリフレッシュする操作が可能であり、プログラムである程度のコヒーレンスをメンテナンスできます。

注意 : Oracle8は、サーバーのバッファ・キャッシュまたはデータベースとの自動キャッシュ・コヒーレンスをサポートしません。 自動キャッシュ・コヒーレンスとは、オブジェクトがサーバーのバッファ・キャッシュで変更される際に、オブジェクト・キャッシュで対応するローカル・オブジェクト・コピーをリフレッシュし、また、サーバー内の対応するすべてのオブジェクトに直接アクセスする前に、オブジェクト・キャッシュで、ローカル・オブジェクト・コピーになされた変更をバッファ・キャッシュにフラッシュする機能のことです。 直接的なアクセスには、SQLまたはトリガー、ストアド・プロシージャを使用した、サーバーのオブジェクトの読込みや変更が含まれます。

オブジェクト・キャッシュ・パラメータオブジェクト・キャッシュには、環境ハンドルの属性である、2つの重要なパラメータが関連付けられています。

■ OCI_ATTR_CACHE_MAX_SIZEキャッシュの最大サイズ

■ OCI_ATTR_CACHE_OPT_SIZEキャッシュの最適サイズ

これらのパラメータは、キャッシュのメモリー使用量レベルを示し、削除してもよいオブジェクトをいつ自動的にキャッシュから削除してメモリーを解放するかを判断するのに役立ちます。

現在キャッシュにあるオブジェクトのメモリー使用量が高水位標に達するかそれを超えると、キャッシュ内では確保カウントが 0であるマーク解除されたオブジェクトの自動解放が始まります。 キャッシュのメモリー使用量が最適サイズに達するか、解放対象オブジェクトがなくなるまで、オブジェクトの解放が続きます。

OCI_ATTR_CACHE_MAX_SIZEは、OCI_ATTR_CACHE_OPT_SIZEのパーセントで指定します。 オブジェクト・キャッシュの最大サイズ(バイト単位)は、OCI_ATTR_CACHE_OPT_SIZEを OCI_ATTR_CACHE_MAX_SIZEのパーセントで増分して計算します。

maximum_cache_size = optimal_size + optimal_size * max_size_percentage / 100

または

maximum_cache_size = OCI_ATTR_CACHE_OPT_SIZE + OCI_ATTR_CACHE_OPT_SIZE * OCI_ATTR_CACHE_MAX_SIZE / 100

OCI_ATTR_CACHE_MAX_SIZEのデフォルト値は 10%です。

OCI_ATTR_CACHE_OPT_SIZEのデフォルト値は 200KBです。

詳細は、B-3ページの「環境ハンドルの属性」を参照してください。

Page 292: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

オブジェクト・キャッシュ操作この項では、オブジェクト・コピーを操作するためにオブジェクト・キャッシュで提供される重要な関数について説明します。 OCIのナビゲーショナルおよびキャッシュ /オブジェクト管理関数のすべては、11-19ページの「OCIナビゲーショナル関数」にリストされています。

確保と確保解除 オブジェクト・コピーを確保すると、アプリケーションでそのコピーへのREFを参照解除することによって、キャッシュ内のコピーにアクセスできるようになります。

オブジェクトを確保解除すると、オブジェクトが現在使用中でないことがキャッシュに対して示されます。 不要になったオブジェクトは確保解除し、暗黙的なキャッシュからの解放の対象とすることで、メモリーを解放する必要があります。

解放 オブジェクト・コピーを解放すると、オブジェクト・コピーはキャッシュから削除され、使用されていたメモリーが解放されます。

マークとマーク解除 オブジェクトをマークすることで、キャッシュ内のオブジェクト・コピーが更新されており、オブジェクト・コピーをフラッシュするときにサーバー内の対応するオブジェクトを更新する必要があることが、キャッシュに通知されます。

オブジェクトをマーク解除すると、オブジェクトが更新されたという指示が削除されます。

フラッシュ オブジェクトをフラッシュすると、キャッシュ内のマークされたオブジェクト・コピーに対して行ったローカルな変更が、サーバー内の対応するオブジェクトに書き込まれます。 それによって、オブジェクト・キャッシュ内のコピーのマークが解除されます。

リフレッシュ キャッシュ内のオブジェクト・コピーをリフレッシュすると、そのコピーは、サーバー内の対応するオブジェクトの最新値に置き換わります。

注意 : 最上位のオブジェクト・メモリーへのポインタは、リフレッシュ後も有効です。 2次レベル・メモリーへのポインタ(文字列テキスト・ポインタ、コレクションなど)は、リフレッシュ後に無効になる場合があります。

オブジェクト・コピーをロードおよび削除するための操作この項では、確保および確保解除、解放の各操作を説明します。

オブジェクト・コピーの確保アプリケーションがオブジェクト・キャッシュ内の REFを参照解除する必要がある場合、OCIObjectPin()をコールします。 このコールによって REFが参照解除され、オブジェクト・コピーがキャッシュ内に確保されます。 オブジェクト・コピーは、確保されているかぎり、アプリケーションからアクセス可能であることが保証されます。 OCIObjectPin()のバリエーションとして OCIObjectPinArray()があります。これは REFの配列を取得し、REFを参照解除し、オブジェクト・コピーを確保します。 OCIObjectPin()と OCIObjectPinArray()の両方

Page 293: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-7

で、確保オプションである "any"、"recent"、"latest"などを受け付けます。 確保オプションのデータ型は OCIPinOptです。

■ "any" (OCI_PIN_ANY)オプションが指定される場合で、キャッシュ内にオブジェクト・コピーがすでにある場合は、それをオブジェクト・キャッシュでただちに戻します。キャッシュ内にオブジェクト・コピーがない場合、オブジェクト・キャッシュでは最新のオブジェクト・コピーをデータベースからロードして、そのオブジェクト・コピーが戻されます。 "any"オプションは、読取り専用や情報、事実、メタ・オブジェクト(製品、販売員、ベンダー、領域、部分、事務所など)に適します。これらのオブジェクトは、通常は頻繁に変更されることはなく、変更されてもその変更内容はアプリケーションに影響しません。

■ "latest" (OCI_PIN_LATEST)オプションが指定される場合、オブジェクト・キャッシュでは、データベースからの最新のオブジェクト・コピーをキャッシュにロードし、オブジェクト・コピーがキャッシュにロックされていない限りは、そのコピーが戻されます。キャッシュにロックされている場合には、マークされたオブジェクト・コピーがただちに戻されます。オブジェクトがすでにキャッシュ内にあり、ロックされていない場合は、最新のオブジェクト・コピーがロードされ、既存のコピーが上書きされます。 "latest"オプションは、操作オブジェクトに適します(購入注文書、バグ、行項目、銀行勘定、株価など)。これらのオブジェクトは通常頻繁に変更され、プログラムではこれらのオブジェクトをできるだけ最新の状態でアクセスしようと試みます。

■ "recent" (OCI_PIN_RECENT)オプションが指定される場合、2つの可能性が考えられます。

a. 同じトランザクションにおいて、"latest"または "recent"オプションを使って、オブジェクト・コピーが以前に確保されている場合は、"recent"オプションは "any"オプションと同等になります。

b. そうでない場合、"recent"オプションは、"latest"と同等になります。

プログラムでオブジェクトが確保される場合、プログラムでは "session"または "transaction"という 2つの可能な値の内の 1つが確保継続時間に指定されます。 確保期間のデータはOCIDurationです。

■ 確保継続時間が "session" (OCI_DURATION_SESSION)の場合、セッションを終了するまで(つまり接続の終わりまで)、またはプログラムで明示的に確保解除されるまで(OCIObjectUnpin()をコールする )オブジェクト・コピーは確保されたままとなります。

■ 確保継続時間が "transaction" (OCI_DURATION_TRANS)の場合、トランザクションの終わり、または明示的に確保解除されるまで、オブジェクト・コピーは確保されたままとなります。

オブジェクト・コピーをデータベースからキャッシュにロードするとき、実際にはキャッシュで次の命令が実行されます。

SELECT VALUE(t) FROM t WHERE REF(t) = :r

Page 294: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

tはオブジェクトを格納しているオブジェクト表であり、rは REFです。フェッチされた値はキャッシュ内のオブジェクト・コピー値になります。

オブジェクト •キャッシュでは、実質的には別個の SELECT文が実行され、読込みコミット済みトランザクションで各オブジェクト・コピーがキャッシュにロードされます。オブジェクト・コピー相互の読込み整合性は保証されません。

直列可能なトランザクションでは、オブジェクト・コピーをロードする SELECT文は、同じデータベース・スナップショットに基づき実行されるため、オブジェクト・コピー(確保された "recent"または "latest")の読込みには相互に一貫性が保たれます。

オブジェクト・キャッシュのモデルは、Oracleトランザクション・モデルに対して独立しています。 オブジェクト・キャッシュの動作は、トランザクション・モデルによって変わることはありません。ただし、同じプログラムを異なる複数のトランザクション・モデル(読込みコミット済みと直列可能など)のもとで実行した場合、オブジェクト・キャッシュを介してサーバーから検索したオブジェクトは、異なることがあります。

オブジェクト・コピーの確保解除プログラムで使用しないオブジェクト・コピーは、確保解除できます。 確保解除したオブジェクト・コピーは、解放できます。 キャッシュのメモリーが残り少なくなった場合は、オブジェクト・コピーを完全に確保解除すると同時にマーク解除し、キャッシュ内のそのコピーを暗黙的解放の対象にする必要があります。 オブジェクト・コピーを完全に確保解除するには、N回確保した場合は N回確保解除する必要があります。

確保解除済みでマーク未解除のオブジェクト・コピーは、フラッシュするか、ユーザーが明示的にマーク解除しないと暗黙的解放の対象になりません。 ただし、オブジェクト・キャッシュのメモリーが残り少なくなると、オブジェクト・キャッシュのオブジェクト・コピーは暗黙的に解放されるので、確保解除したオブジェクト・コピーを必ずしも解放する必要はありません。 暗黙的に解放されていないオブジェクト・コピーをプログラムで(「任意」または「最近」オプションを指定して)再度確保した場合、同一のオブジェクト・コピーを入手することになります。

アプリケーションでオブジェクト・コピーを確保解除するには、OCIObjectUnpin()またはOCIObjectPinCountReset()をコールします。 さらに、プログラムでは、特定の接続に対してキャッシュ内のすべてのオブジェクト・コピーを完全に確保解除するために、OCICacheUnpin()をコールできます。

オブジェクト・コピーの開放オブジェクト・コピーの解放とは、オブジェクト・キャッシュからオブジェクト・コピーを削除し、そのコピーが使用していたメモリーを解放することです。 キャッシュのメモリーを解放するには、次の 2通りの方法があります。

1. 明示的解放 - プログラムで OCIObjectFree()をコールして、キャッシュからオブジェクト・コピーを明示的に解放または削除します。この関数は、マークまたは確保されたオブジェクト・コピーのいずれかを強制的に解放するオプションがあります。

Page 295: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-9

OCICacheFree()をコールしてキャッシュ内のすべてのオブジェクトを解放することもできます。

2. 暗黙的解放 - キャッシュのメモリーが残り少なくなった場合は、確保解除済みのオブジェクト・コピーとマーク解除済みのオブジェクト •コピーの両方が、暗黙的に解放されます。 マークされた、確保解除済みのオブジェクトは、オブジェクト・コピーをフラッシュまたはマーク解除した場合にのみ、暗黙的解放の対象になります。 詳細は、11-5ページの「オブジェクト・キャッシュ・パラメータ」を参照してください。

メモリー管理の目的では、不要になったオブジェクトをアプリケーションで確保解除することが重要です。 確保解除したオブジェクトはキャッシュから削除される対象になるので、必要なときにキャッシュのメモリーをスムーズに解放できます。

OCIでは、クライアント側キャッシュにある参照されていないオブジェクトを解放する関数は提供していません。

オブジェクト・コピーを変更するための操作この項では、オブジェクト・コピーをマークする関数とマークを解除する関数を説明します。

オブジェクト・コピーのマーク オブジェクト・コピーはキャッシュ内でローカルに作成、更新、削除できます。 (OCIObjectNew()をコールすることによって )キャッシュ内にオブジェクト・コピーを作成すると、オブジェクト・キャッシュでオブジェクト・コピーに挿入のマークが付けられます。そのため、このオブジェクト・コピーをフラッシュすると、オブジェクトがサーバーに挿入されます。

オブジェクト・コピーがキャッシュ内で更新されると、ユーザーは、オブジェクト・コピーに更新のマークを付ける (OCIObjectMarkUpdate()をコールする )ことによって、オブジェクト・キャッシュに通知する必要があります。 オブジェクト・コピーをフラッシュすると、サーバー内の対応するオブジェクトが、オブジェクト・コピーの値に更新されます。

オブジェクト・コピーが削除された場合、そのオブジェクト・コピーはOCIObjectMarkDelete()をコールすることにより、オブジェクト・キャッシュ内で削除のマークが付けられます。 オブジェクト・コピーをフラッシュすると、サーバー内の対応するオブジェクトが削除されます。 マークされたオブジェクト・コピーのメモリーは、そのコピーをフラッシュして確保解除しないかぎり解放されません。 プログラムで削除マーク付きのオブジェクトを確保すると、参照先のない参照を参照解除した場合と同様のエラーになります。

1つのオブジェクト・コピーを複数回変更した場合、そのコピーをフラッシュしたときにサーバーのオブジェクトに適用されるのは、最後の変更結果です。 たとえば、オブジェクト・コピーを更新した後で削除した場合、オブジェクト・コピーをフラッシュすると、サーバーのオブジェクトは単に削除されます。 同様に、オブジェクト・コピーの属性を複数回更新した場合、オブジェクト・コピーをフラッシュしたときにサーバーで更新されるのは、属性の最終的な値です。

Page 296: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

プログラムでは、オブジェクト・コピーがオブジェクト・キャッシュにロードされている場合だけ、オブジェクト・コピーを更新済みまたは削除済みとしてマークすることができます。

オブジェクト・コピーのマーク解除オブジェクト・キャッシュ内のマークされたオブジェクト・コピーは、マーク解除できます。 マークされたオブジェクト・コピーをマーク解除すると、オブジェクト・コピーに対して行った変更内容はサーバーにフラッシュされません。 オブジェクト・キャッシュのオブジェクト・コピーに対してすでに行ったローカルな変更内容は、取り消されません。

プログラムでオブジェクトをマーク解除するには、OCIObjectUnmark()をコールします。 さらに、OCICacheUnmark()をコールして、特定の接続に対して、キャッシュ内のすべてのオブジェクト・コピーをマーク解除することもできます。

オブジェクト・コピーをサーバーと同期化するための操作この項では、キャッシュとサーバーの同期化操作(フラッシュ、リフレッシュ)を説明します。

変更をサーバーにフラッシュキャッシュ内のマークされたオブジェクト・コピーに対するローカルな変更は、オブジェクト・コピーをフラッシュしたときにサーバーに書き込まれます。 プログラムで単一のオブジェクト・コピーをフラッシュするには、OCIObjectFlush()をコールします。または、OCICacheFlush()をコールして、キャッシュ内のすべてのマークされたオブジェクト・コピーをフラッシュするか、選択されているマークされたオブジェクト・コピーのリストをフラッシュできます。 OCICacheFlush()は、特定のサービス・コンテキストに関連付けられたオブジェクトをフラッシュします。

オブジェクト・コピーをフラッシュすると、そのオブジェクト・コピーはマーク解除されます。(フラッシュ後にオブジェクトはサーバーでロックされます。そのため、キャッシュ内のオブジェクト・コピーはロック状態とマークされます)。

注意 : OCICacheFlush()操作は、複数のオブジェクトがフラッシュされる場合でも、単一のサーバー往復にのみ発生します。

アプリケーションで、ある型のダーティ・オブジェクトだけをフラッシュする場合、OCICacheFlush()コールのオプションの引数であるコールバック関数を通して、この機能が使用できます。 アプリケーションで、目的のオブジェクトだけを戻すコールバックを定義できます。 この場合でも、フラッシュのための操作では、サーバー往復が 1回発生するだけです。

オブジェクト・コピーのリフレッシュオブジェクト・コピーをリフレッシュすると、サーバー内の対応するオブジェクトの最新値が、オブジェクト・コピーに再ロードされます。 最新値は、その他のコミット済みトランザクションでの変更や、同じトランザクションで(オブジェクト・キャッシュを介さないで)

Page 297: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-11

直接サーバー内で行った変更を含む場合があります。 プログラムでは、SQL DMLまたはトリガー、ストアド・プロシージャを使用して、サーバー内のオブジェクトを直接変更できます。

プログラムで、マークされたオブジェクト・コピーをリフレッシュするには、まずオブジェクト・コピーをマーク解除する必要があります。 確保解除したオブジェクト・コピーは、リフレッシュすると(つまりキャッシュ全体をリフレッシュすると)単に解放されます。

プログラムで単一のオブジェクト・コピーをリフレッシュするには、OCIObjectRefresh()をコールします。または、OCICacheRefresh()をコールして、キャッシュ内のすべてのオブジェクト・コピー、トランザクションでロードしたすべてのオブジェクト・コピー(つまり、「最近」または「最新」オプションを指定して確保したオブジェクト・コピー)、選択したオブジェクト・コピーのリストのいずれかをリフレッシュできます。

オブジェクトをサーバーにフラッシュするときに、トリガーを起動してさらに多くのサーバー内のオブジェクトを変更できます。 その場合、オブジェクト・キャッシュ内の(トリガーによって変更したオブジェクトと)同一のオブジェクトは最新の状態ではなくなり、リフレッシュしないとロックまたはフラッシュできません。

各種のメタ属性フラグおよびオブジェクトの継続時間は、表 11–1で説明するとおり、リフレッシュされた後で変更されます。

リフレッシュ実行時、オブジェクト・キャッシュでは新しいデータがオブジェクト・コピーのトップ・レベル・メモリーにロードされます。つまりトップ・レベル・メモリーは再使用されます。 オブジェクト・コピーのトップ・レベル・メモリーには、オブジェクトのインライン属性が入っています。 その反対に、ライン外属性はサイズ変更ができるので、オブジェクト・コピーのライン外属性のメモリーは解放して再配置できます。

関連項目 : オブジェクト・メモリーに関する詳細は、11-15ページの「インスタンスのメモリー・レイアウト」を参照してください。

表 11–1 リフレッシュ後のオブジェクト属性

オブジェクト属性 リフレッシュ後の状態

既存 適切な値に設定

確保済み 未変更

フラッシュ済み リセット

割当て継続時間 未変更

確保継続時間 未変更

Page 298: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

その他の操作この項では、関係するその他の OCI関数を説明します。

更新するためのオブジェクトのロックプログラムでは、オプションで OCIObjectLock()をコールして、更新するオブジェクトをロックできます。 このコールは、データベースのオブジェクトに対する行ロックの獲得をオブジェクト・キャッシュに指示します。 これは、次のようにして実行します。

SELECT NULL FROM t WHERE REF(t) = :r FOR UPDATE

tはロックするオブジェクトを格納しているオブジェクト表であり、rはオブジェクトを識別する REFです。 OCIObjectLock()をコールすると、オブジェクト・キャッシュ内のオブジェクト・コピーがロック状態とマークされます。

オブジェクトのグラフまたはオブジェクトの集合をロックするには、オブジェクトごとに 1回ずつ OCIObjectLock()のコールが必要です。配列確保の OCIObjectArrayPin()コールを使用すると、もっと効率よく実行できます。

オブジェクトをロックすることにより、キャッシュのオブジェクトが最新のものであることをアプリケーションで保証します。 オブジェクトがアプリケーションでロックされている間は、その他のトランザクションはそのオブジェクトを変更できません。

トランザクションの最後には、すべてのロックがサーバーによって自動的に解放されます。 オブジェクト・コピーのロック状態標識はリセットされます。

最適ロックの実現トランザクションを直列可能レベルで実行している場合、OCIアプリケーションで最適ロックを実現することができます。

Oracle8 OCIでは、オブジェクト・キャッシュ内のオブジェクトをロックせずに参照解除して確保し、キャッシュ内でそのオブジェクトを変更し(ロックなしで)、ダーティになったオブジェクトをデータベースにフラッシュするコールをサポートしています。

トランザクションの開始以降、ダーティ・オブジェクトがコミットされた別のトランザクションによって変更された場合、フラッシュの間、直列不能トランザクションのエラーが戻されます。 トランザクションの開始以降、別のトランザクションで変更されたダーティ・オブジェクトがない場合は、変更内容は、データベースに正常に書き込まれます。

注意 : OCITransCommit()で、トランザクションをコミットする前に、まずダーティ・オブジェクトをデータベースにフラッシュします。

上記のメカニズムにより、最適ロック・モデルが効果的に実現します。

Page 299: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-13

オブジェクト・アプリケーションでのコミットおよびロールバックトランザクションをコミットすると (OCITransCommit())、すべてのマークされたオブジェクトがサーバーにフラッシュされます。 トランザクション継続時間を指定して確保したオブジェクト・コピーは、確保解除されます。

トランザクションをロールバックすると、すべてのマークされたオブジェクトがマーク解除されます。 トランザクション継続時間を指定して確保したオブジェクト・コピーは、確保解除されます。

オブジェクトの継続時間メモリーにフリー・スペースを維持するため、オブジェクト・キャッシュでは、可能な限りオブジェクトのメモリーの再使用を試みます。 オブジェクトの寿命 (割当て継続時間 ) またはオブジェクトの確保継続時間が期限切れとなると、オブジェクト・キャッシュでオブジェクトのメモリーを再使用します。 割当て継続時間は、OCIObjectNew()でオブジェクトを作成するときに設定されます。確保継続時間は、OCIObjectPin()でオブジェクトを確保するときに設定されます。 継続時間値のデータ型は OCIDurationです。

注意 : オブジェクトの確保継続時間は、オブジェクトの割当て継続時間より長くできません。

オブジェクトの割当て継続時間が終わりに達すると、オブジェクトは自動的に削除され、メモリーが再利用可能になります。 確保継続時間はオブジェクトのメモリーを再使用できる時期を示し、キャッシュが満杯になるとメモリーは再使用されます。

OCIでは、次の 2つの事前定義済みの継続時間をサポートします。

1. トランザクション (OCI_DURATION_TRANS)

2. セッション (OCI_DURATION_SESSION)

トランザクション継続時間は、トランザクションが終了(コミットまたは異常終了)した時点で終わりです。 セッション継続時間は、セッションまたは接続が終了した時点で終わりです。

アプリケーションでは、OCIObjectUnpinを使用するオブジェクトを明示的に確保解除できます。 個々のオブジェクトの明示的な確保解除を最小限にするには、アプリケーションで関数 OCICacheUnpinを使用し、オブジェクト・キャッシュ内で現在確保済みであるすべてのオブジェクトを確保解除します。 デフォルトでは、すべてのオブジェクトは、確保継続時間終了時に確保を解除されます。

Page 300: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

継続時間例表 11–2は、アプリケーションでの異なる継続時間の使用方法を示します。 このアプリケーションでは、1つの接続と 3つのトランザクションで、4つのオブジェクトを作成または確保しています。 最初の列はデータベースで実行されるアクションを示し、2番目の列はそのアクションを実行する関数を示しています。 残りの列はアプリケーションの各ポイントでの各種オブジェクトの状態を示しています。

たとえば、オブジェクト 1は、T2で接続継続時間で作成され、接続を終了すると T19まで存在します。 オブジェクト 2は、T6でフェッチされた後、トランザクション継続時間ではT7で確保され、トランザクションがコミットされた際に T9まで確保されたままとなります。

表 11–2 割当ておよび確保継続時間の例

時間アプリケーションのアクショ

ン 関数オブジェクト 1

オブジェクト 2

オブジェクト 3

オブジェクト 4

T1 接続を確立する

T2 オブジェクト 1を作成する - 割当て継続時間 = 接続

OCIObjectNew() 既存

T5 トランザクション 1を開始する

OCITransStart() 既存

T6 SQL - REFをオブジェクト 2にフェッチ

既存

T7 オブジェクト 2を確保する - 確保継続時間 = トランザクション

OCIObjectPin() 既存 確保済み

T8 アプリケーション・データを処理する

既存 確保済み

T9 トランザクション 1をコミットする

OCITransCommit() 既存 確保解除

T10 Transaction2を開始する OCITransStart() 既存

T11 オブジェクト 3を作成する - 割当て継続時間 = トランザクション

OCIObjectNew() 既存 既存

T12 SQL - REFをオブジェクト 4にフェッチする

既存 既存

T13 オブジェクト 4を確保する -確保継続時間 = 接続

OCIObjectPin() 既存 既存 確保済み

T14 Transaction2をコミットする OCITransCommit() 既存 削除済み 確保済み

Page 301: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-15

関連項目 : これらの関数に渡せるパラメータ値についての情報は、OCIObjectNew()および OCIObjectPin()(第 14章 )の説明を参照してください。

割当て継続時間が期限切れとなった後の、オブジェクト・メモリーの開放に関する情報は、8-30ページの「オブジェクトの作成および開放、コピー」を参照してください。

インスタンスのメモリー・レイアウトメモリーのインスタンスは、インスタンスのトップ・レベル・メモリー・チャンク、およびNULL標識構造体のトップ・レベル・メモリー、オプションとして多数の 2次メモリー・チャンクで構成されています。 たとえば、次のような DEPARTMENTという行の型があるとします。

CREATE TYPE department AS OBJECT( dep_name varchar2(20),budget number, manager person, /* person is an object type */employees person_array ); /* varray of person objects */

この C表現は次のようになります。

struct department{OCIString * dep_name;OCINumber budget;struct person manager;OCIArray * employees;);typedef struct department department;

DEPARTMENTの各インスタンスは、dep_name、budget、manager、employeesなどのトップ・レベル属性が入ったトップ・レベル・メモリー・チャンクを持ちます。 dep_name属性と employees属性は、実際にはそれ自体が追加メモリー (2次メモリー・

T15 セッション 1を終了する OCIDurationEnd() 既存 確保済み

T16 Transaction3を開始する OCITransStart() 既存 確保済み

T17 アプリケーション・データを処理する

既存 確保済み

T18 トランザクション 3をコミットする

OCITransCommit() 既存 確保済み

T19 接続を終了する 削除済み 確保解除

表 11–2 割当ておよび確保継続時間の例 (続き )

時間アプリケーションのアクショ

ン 関数オブジェクト 1

オブジェクト 2

オブジェクト 3

オブジェクト 4

Page 302: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・キャッシュおよびメモリー管理

11-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

チャンク )へのポインタです。 2次メモリーは、埋込みインスタンスの実データを入れるために使用されます (employeesの varrayや dep_nameの文字列など )。

NULL標識構造体のトップ・レベル・メモリーには、インスタンスのトップ・レベル・メモリー・チャンクにある属性の NULL状態が入っています。 この例では、NULL構造体のトップ・レベル・メモリーに、属性 dep_name、budget、manager、employeesのNULL状態と属性 employeesのアトミック NULLが入っています。

Page 303: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・ナビゲーション

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-17

オブジェクト・ナビゲーションこの項では、OCIアプリケーションでオブジェクト・キャッシュ内のオブジェクトのグラフをナビゲートする方法を説明します。

単純なオブジェクト・ナビゲーションこれまでの項に示した例では、アプリケーションで検索したオブジェクトは単純なオブジェクトであり、その属性はすべてスカラー値でした。 アプリケーションで、別のオブジェクトへの REFである属性を持つオブジェクトを検索する場合は、OCIコールを使用してオブジェクト・グラフを走査し、参照されているインスタンスにアクセスできます。

たとえば、次の宣言でデータベースに新しい型を定義したとします。

CREATE TYPE person_t AS OBJECT( name VARCHAR2(30), mother REF person_t, father REF person_t);

person_tオブジェクトのオブジェクト表は、次の文を使用して作成します。

CREATE TABLE person_table OF person_t;

これで person_t型のインスタンスをこの型指定表に格納できます。 person_tの各インスタンスには、同じ表に格納される他の 2つのオブジェクトへの参照が含まれています。 NULL参照は、親に関する情報がないことを表します。

オブジェクト・グラフは、オブジェクト・インスタンス間の REFリンクを視覚的に表現したものです。 たとえば、次のページに、1オブジェクトから別のオブジェクトへのリンクを示す person_tインスタンスのオブジェクト・グラフを示します。 円はオブジェクトを表し、矢印は他のオブジェクトへの参照を表しています。

Page 304: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト・ナビゲーション

11-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

図 11–2 person_tインスタンスのオブジェクト・グラフ

この場合、各オブジェクトは、同一オブジェクトの他の 2つのインスタンスへのリンクを持ちます。 これ以外のケースも考えられます。 オブジェクトがその他のオブジェクト型へのリンクを持つ場合もあります。 その他の型のグラフも可能です。 たとえば、オブジェクトの集合を連係リストとして組み込む場合は、オブジェクト・グラフを単純な連鎖とみなすことができます。この場合、各オブジェクトは、連係リストの前にあるオブジェクトまたは次にあるオブジェクト(あるいはその両方)を参照します

この章の前半で説明した方法を使って、person_tインスタンスへの参照を取り出し、次にそのインスタンスを確保できます。 OCIには、1つのオブジェクトから別のオブジェクトをたどることでオブジェクト・グラフを走査できる機能があります。

一例として、アプリケーションで、上記グラフの person1インスタンスをフェッチし、pers_1として確保すると想定します。 それができたら、アプリケーションで person1の母インスタンスにアクセスし、2次確保操作を通じてそれを pers_2に確保できます。

OCIObjectPin(env, err, pers_1->mother, OCI_PIN_ANY, OCI_DURATION_TRANS, OCI_LOCK_X, (OCIComplexObject *) 0, &pers_2);この場合、2つ目のインスタンスを検索するための OCIのフェッチ操作は必要ありません。

person1

M F

person2

M F

person3

M F

person4

M F

person5

M F

person6

M F

NULL

Page 305: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIナビゲーショナル関数

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-19

アプリケーションでは、次に、person1の父インスタンスを確保するか、person2の参照リンクで操作できます。

注意 : NULLを確保しようとすると、ぶら下がり REFで OCIObjectPin()コールにエラーが生じます。

OCIナビゲーショナル関数この項では、OCIナビゲーショナル関数をまとめて簡単に説明します。 関数は一般的な機能別にグループ化してあります。 これらの各関数の詳細は、第 14章の「OCIナビゲーショナル関数と型関数」で説明します。

これらの関数の使用方法は、この章の最初にいくつかの項目で説明しています。

ナビゲーショナル・ファンクションは、機能の種類に応じて異なる接頭辞が付く命名体系に従っています。

OCICache*() - キャッシュ操作の関数

OCIObject*() - 個々のオブジェクトを操作する関数

確保 /確保解除 /開放関数オブジェクトの確保または確保解除、解放を行うには、次の関数を使用します。

フラッシュおよびリフレッシュ関数変更したオブジェクトをサーバーにフラッシュするには、次の関数を使用します。

関数 用途

OCIObjectPin() オブジェクトを確保する

OCIObjectUnpin() オブジェクトを確保解除する

OCIObjectPinCountReset() オブジェクトを確保解除して確保カウントをゼロにする

OCICacheUnpin() キャッシュまたは接続で永続オブジェクトを確保解除する

OCIObjectArrayPin() 参照の配列を確保する

OCIObjectPinTable() 継続時間を指定して表オブジェクトを確保する

OCICacheFree() キャッシュの全インスタンスを解放する

OCIObjectFree() スタンドアロン・インスタンスを解放し、確保解除する

Page 306: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIナビゲーショナル関数

11-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

マークおよびマーク解除関数アプリケーションで、メタ属性の 1つを変更してオブジェクトのマークまたはマーク解除を行うには、次の関数を使用します。

オブジェクトのメタ属性アクセサ関数アプリケーションでオブジェクトのメタ属性にアクセスするには、次の関数を使用します。

関数 用途

OCICacheFlush() キャッシュ内の変更済み永続オブジェクトをサーバーにフラッシュする

OCIObjectFlush() 単一の変更済み永続オブジェクトをサーバーにフラッシュする

OCICacheRefresh() キャッシュ内の確保済み永続オブジェクトをリフレッシュする

OCIObjectRefresh() 単一の永続オブジェクトをリフレッシュする

関数 用途

OCIObjectMarkDelByRef() REFを指定してオブジェクトを削除済みをマークする

OCIObjectMarkUpd() オブジェクトを更新済み /ダーティとマークする

OCIObjectMarkDel() オブジェクトを削除済みとマークする /値インスタンスを削除する

OCICacheUnmark() キャッシュ内の全オブジェクトをマーク解除する

OCIObjectUnmark() 指定のオブジェクトを更新済みとマークする

OCIObjectUnmarkByRef() REFを指定してオブジェクトに更新済みのマークを付ける

関数 用途

OCIObjectExists() インスタンスの既存状態を入手する

OCIObjectFlushStatus() インスタンスのフラッシュ状態を取得する

OCIObjectGetInd() インスタンスの NULL構造体を入手する

OCIObjectIsDirtied() オブジェクトに更新済みのマークが付いていますか ?

OCIObjectIsLocked() オブジェクトはロック状態ですか ?

Page 307: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIナビゲーショナル関数

オブジェクトのキャッシュおよびオブジェクト・ナビゲーション 11-21

その他の関数次の関数は、OCIアプリケーションにその他のオブジェクト機能を提供します。

関数 用途

OCIObjectCopy() 1つのインスタンスを別のインスタンスにコピーする

OCIObjectGetObjectRef() 指定のオブジェクトへの参照を戻す

OCIObjectGetTypeRef() インスタンスの TDOへの参照を入手する

OCIObjectLock() 永続オブジェクトをロックする

OCIObjectNew() 新規インスタンスを作成する

Page 308: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIナビゲーショナル関数

11-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

Page 309: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト型トランスレータの使用 12-1

12オブジェクト型トランスレータの使用

この章では、オブジェクト型トランスレータ (OTT)ついて説明します。これはデータベース・オブジェクト型をマップしたり、名前付きコレクション型を OCIおよび Pro*C/C++アプリケーションで使うために C 構造体にマップするのに使われます。

この章は、次のトピックで構成されています。

■ OTT概要

■ オブジェクト型トランスレータの使用方法

■ OCIアプリケーションでの OTTの使用方法

■ OTTの参照

注意 : Pro*C/C++に特定の情報は、『Pro*COBOLプリコンパイラ・プログラマーズ・ガイド』を参照してください。

注意 : この章で説明されている機能性は、オブジェクト・オプションのある Oracle8 Enterprise Editionを購入された場合にのみ使用可能です。

Page 310: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTT概要

12-2 Oracle8コール・インタフェース・プログラマーズ・ガイド

OTT概要OTT(オブジェクト型トランスレータ )は、Oracle8と共にリリースされた新しい製品です。これは、Oracle8 Serverでユーザー定義型を利用する、C言語アプリケーションの開発を支援します。

SQL CREATE TYPE文を使用して、オブジェクト型を作成できます。 これらの型の定義をデータベースに格納しておき、データベースの表を作成するときに使用できます。 これらの表を作成すると、OCIまたは Pro*C/C++のプログラマは、表に格納されたオブジェクトにアクセスできます。

オブジェクト・データにアクセスするアプリケーションでは、データをホスト言語形式で表現できなければなりません。 これは、オブジェクト型を C構造体として表現することによって実現できます。 プログラマがデータベース・オブジェクト型を表す構造体宣言を、手入力でコーディングすることは可能です。しかし、多くの型がある場合、この作業は時間がかかり、エラーを生む原因になることも少なくありません。 OTTを使用して適切な構造体宣言を自動的に生成することにより、このステップを単純化できます。 Pro*C/C++のアプリケーションでは OTTで生成したヘッダー・ファイルを組み込むだけですみます。 また、OCIでは、アプリケーションが OTTで生成された初期化関数をコールする必要があります。

OTTは、格納済みのデータ型を表す構造体を作成するだけでなく、オブジェクト型またはそのフィールドが NULLかどうかを示すパラレル標識構造体も生成します。

オブジェクト型トランスレータの使用方法オブジェクト型トランスレータ (OTT)は、オブジェクト型と名前付きコレクション型のデータベース定義を、OCIまたは Pro*C/C++アプリケーションに組み込める C構造体宣言に変換します。

OTTを明示的に起動し、データベース型を C表現に変換しなければなりません。 さらに、プログラムで必要なユーザー定義型に関する情報を使用して、型バージョン表と呼ばれるデータ構造を初期化する必要があります。 この初期化を実行するコードは、OTTで生成します。

ほとんどのオペレーティング・システムでは、コマンド行から OTTを起動します。 「Intypeファイル」を入力とし、「Outtypeファイル」および C「ヘッダー・ファイル」、オプションの「インプリメンテーション・ファイル」を生成します。 OTTを起動するコマンドの例を次に示します。

ott userid=scott/tiger intype=demoin.typ outtype=demoout.typ code=c hfile=demo.h

このコマンドで、OTTをユーザー名が scottでパスワードが tigerのデータベースに接続し、intypeファイル (demoin.typ)の指示にしたがって、データベース型を C構造体に変換します。その結果生成された構造体は、codeパラメータで指定したホスト言語 (C言語 )用として headerファイル (demo.h)に出力されます。 Outtypeファイル (demoout.typ)では、その変換についての情報を受け取ります。

各パラメータについては、この章のこの後の項目で詳しく説明します。

demoin.typファイルの例

Page 311: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト型トランスレータの使用方法

オブジェクト型トランスレータの使用 12-3

CASE=LOWERTYPE employee

demoout.typファイルの例

CASE=LOWERTYPE EMPLOYEE AS employee VERSION = "$8.0" HFILE = demo.h

この例では、demoin.typファイルに、TYPEが前に付く変換対象の型 (たとえば、TYPE employee)があります。 Outtypeファイルの構造体は、Intypeファイルに似ており、OTTで取得した情報が追加されます。

OTTによる変換が終了すると、ヘッダー・ファイルには、intypeファイルで指定した各型の C構造体表現と、各型に対応したNULL標識構造体が入っています。 たとえば、Intypeファイルにリストされた employee型が次のように定義されたとします。

CREATE TYPE employee AS OBJECT( name VARCHAR2(30), empno NUMBER, deptno NUMBER, hiredate DATE, salary NUMBER);

OTTで生成されたヘッダー・ファイル (demo.h)には、その他の項目の中に、次の宣言が含まれます。

struct employee{ OCIString * name; OCINumber empno; OCINumber deptno; OCIDate hiredate; OCINumber salary;};typedef struct emp_type emp_type;

struct employee_ind{ OCIInd _atomic; OCIInd name; OCIInd empno; OCIInd deptno; OCIInd hiredate; OCIInd salary;

Page 312: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト型トランスレータの使用方法

12-4 Oracle8コール・インタフェース・プログラマーズ・ガイド

};typedef struct employee_ind employee_ind;

注意 : intypeファイルのパラメータで、生成済み構造体の命名方法を制御します。 この例では、構造体名の employeeはデータベース型名の employeeと合致します。 構造体名には小文字を用います。Intypeファイルの行が CASE=lowerのためです。

構造体の宣言に表れるデータ型は (OCIString、OCIIndなど )、Oracle8には新しい特殊なデータ型です。これらのデータ型についての詳細は、12-9ページの「OTTデータ型マッピング」を参照してください。

次の各項では、OTTの使用方法をそれぞれの局面から説明します。

■ データベースでの型の作成

■ OTTの起動

■ OTTのコマンド行

■ Intypeファイル

■ OTTデータ型マッピング

■ NULL標識の構造体

■ Outtypeファイル

この章の残りの各項では、OCIでの OTTの使用方法を説明します。その後に続くリファレンスの項目では、コマンド行構文、およびパラメータ、Intypeファイルの構造体、ネストした #includeファイルの生成、スキーマ名の使用方法、デフォルトの名前マッピング、制限事項を説明します。

データベースでの型の作成OTTを使用するとき、最初のステップは、オブジェクト型または名前付きコレクション型を作成してデータベースに格納することです。 そのためには、SQL CREATE TYPE文を使用します。

関連項目 : CREATE TYPE文に関する詳細は、『Oracle8 Server SQLリファレンス』を参照してください。

OTTの起動次のステップは、OTTの起動です。 OTTパラメータは、コマンド行で、または構成ファイルをコールしたファイルで指定できます。 一部のパラメータは Intypeファイルでも指定できます。

1つのパラメータを複数箇所に指定した場合、コマンド行の値が INTYPEファイルの値より優先されます。INTYPEファイルの値はユーザー定義の構成ファイルの値より優先されます。ユーザー定義の構成ファイルの値は、デフォルトの構成ファイルの値より優先されます。

Page 313: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

オブジェクト型トランスレータの使用方法

オブジェクト型トランスレータの使用 12-5

コマンド行コマンド行に設定されたパラメータ(オプションとも呼ばれます)は、他で設定されたパラメータを上書きします。 詳細は、次の項の「OTTのコマンド行」を参照してください。

構成ファイル構成ファイルは、OTTパラメータが入っているテキスト・ファイルです。 ファイル内の空白以外の各行には、1つのオプションと、それに対応付けられた 1つ以上の値が入っています。 1行に 2つ以上のパラメータを指定した場合は、最初のパラメータだけが使用されます。 構成ファイルの空白以外の行では、空白は使用できません。

構成ファイルは、コマンド行で名前を付けることができます。 さらに、デフォルトの構成ファイルは常に読み込まれます。 このデフォルトの構成ファイルは、常に存在しなければなりませんが、空でも構いません。 デフォルトの構成ファイルの名前は ottcfg.cfgであり、構成ファイルの位置はシステム固有です。 たとえば、Solarisのファイル指定は$ORACLE_HOME/precomp/admin/ottcfg.cfgです。 詳細は、プラットフォーム固有のマニュアルを参照してください。

INTYPEファイルINTYPEファイルは、変換する OTTの型のリストです。

パラメータの CASEおよび HFILE、INITFUNC、INITFILEは INTYPEファイルに入れ ることができます。 詳細は 12-8ページの「Intypeファイル」を参照してください。

Page 314: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTのコマンド行

12-6 Oracle8コール・インタフェース・プログラマーズ・ガイド

OTTのコマンド行ほとんどのプラットフォームでは、コマンド行から OTTを起動します。入出力ファイルやデータベース接続情報などを指定できます。 プラットフォームでの OTTの起動方法については、プラットフォーム固有のドキュメンテーションを参照してください。

例 1 コマンド行から OTTを起動する例を次に示します。

ott userid=bren/bigkitty intype=demoin.typ outtype=demoout.typ code=c hfile=demo.h

注意 : 等価の符号 (=)の両側には空白を挿入しません。

次の各項では、この例で使用しているコマンド行の要素を説明します。

さまざまな OTTコマンド行のオプションについての詳細は、12-21ページの「OTTの参照」を参照してください。

OTTOTTを起動します。 必ずコマンド行の先頭に置きます。

useridOTTが使用するデータベース接続情報を指定します。

例 1では、OTTはユーザー名 brenおよびパスワード bigkittyへの接続を試みます。

intype使用する intypeファイルの名前を指定します。

例 1では、intypeファイルの名前を demoin.typと指定しています。

outtypeouttypeファイルの名前を指定します。 OTTで Cヘッダー・ファイルを生成すると、変換された型の情報が Outtypeファイルに書き込まれます。 このファイルには、変換された各型のエントリが、バージョン文字列および C表現を書き込んだヘッダー・ファイルとともに含まれます。

12-6ページの「例 1」では、outtypeファイルの名前は demoout.typのように指定されます。

注意 : outtypeのキーワードで指定されるファイルがすでに存在する場合、OTTが稼動する際にそれが上書きされます。 Outtypeファイル名が Intypeファイル名と同じであれば、Outtypeファイル内の情報によって Intypeファイルが上書きされます。

Page 315: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTのコマンド行

オブジェクト型トランスレータの使用 12-7

コード変換の目標言語を指定します。 次のオプションがあります。

■ C(ANSI_Cと等価 )

■ ANSI_C(ANSI C対応 )

■ KR_C (Kernighan & Ritchie C対応 )

現在はデフォルト・オプションがないため、このパラメータは必須です。

構造体の宣言は、両方の Cダイアレクトにおいて同一です。 INITFILEファイルで定義された初期化関数が定義されるスタイルは、KR_Cが使用されるかどうかによります。 INITFILEオプションを使用しない場合、3つのオプションはすべて等価です。

hfile生成された構造体を書き込む Cヘッダー・ファイルの名前を指定します。

12-6ページの「例 1」では、生成される構造体は demo.hと呼ばれるファイルに格納されます。

注意 : hfileキーワードで指定されるファイルがすでに存在する場合、次の例外を除いては、OTTが稼動する際に上書きされます。 OTTによって生成されるファイルの内容が、ファイルの前の内容と同一の場合、OTTは実際にはファイルへ書き込みをしません。 これにより、ファイルの変更時間を節約でき、UNIX makeおよび他のプラットフォームでの類似の機能で、不必要な再コンパイルを実行しません。

initfile型初期化関数を書き込む Cソース・ファイルの使用を指定します。

注意 : initfileキーワードで指定されるファイルがすでに存在する場合、次の例外を除いては、OTTが稼動する際にこれが上書きされます。 OTTによって生成されるファイルの内容が、ファイルの前の内容と同一の場合、OTTは実際にはファイルへ書き込みをしません。 これにより、ファイルの変更時間を節約でき、UNIX makeおよび他のプラットフォームでの類似の機能で、不必要な再コンパイルを実行しません。

initfileinitfileに定義する初期化関数の名前を指定します。

このパラメータを使用せず初期化関数を生成すると、初期化関数の名前は、initfileの基本名と同一になります。

Page 316: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Intypeファイル

12-8 Oracle8コール・インタフェース・プログラマーズ・ガイド

IntypeファイルOTTの実行時に、INTYPEファイルは、どのデータベース型が変換されるかを OTTに通知し、生成された構造体の名前付けを制御します。 ユーザー作成ファイル、または前回 OTTを起動したときの outtypeファイルを intypeファイルにすることができます。 INTYPEパラメータを使用しない場合、OTTが接続するスキーマにあるすべての型が変換されます。

簡単なユーザー作成 intypeファイルの例を次に示します。

CASE=LOWERTYPE employee TRANSLATE SALARY$ AS salary DEPTNO AS departmentTYPE ADDRESSTYPE itemTYPE "Person"TYPE PURCHASE_ORDER AS p_o

第 1行では、CASEキーワードによって、生成された C識別子を小文字にすることを指示しています。 ただし、この CASEオプションは、intypeファイルに明示的に記述されていない識別子にだけ適用されます。 そのため、常に employeeは employee、ADDRESSはADDRESSという C構造体になります。 これらの構造体のメンバーは、小文字で名前が付けられます。

関連項目 : CASEオプションに関する詳細は、12-26ページの「case」の説明を参照してください。

TYPEキーワードで始まる行は、データベースで変換する型を指定します。 この例では、EMPLOYEE型および ADDRESS型、ITEM型、PERSON型、PURCHASE_ORDER型です。

TRANSLATE...ASキーワードでは、オブジェクト型を C構造体に変換するときに、オブジェクト属性の名前を変更することを指定しています。 この場合は、employee型のSALARY$属性が salaryに変換されます。

最終行の ASキーワードでは、オブジェクト型を構造体に変換するとき、名前を変更することを指定しています。 この例では、purchase_orderというデータベース型を p_oという構造体に変換します。

ASキーワードが、型または属性名の変換に使用されない場合、その型または属性のデータベース名は、C識別子名として使用されます。例外として、CASEオプションが有効で、有効な C識別子文字にマップできない文字は、アンダースコアに置き換わります。 型または属性名を変換する理由は、次のとおりです。

■ 名前に、アルファベットおよび数字、アンダースコア以外の文字が含まれる。

■ 名前が Cキーワードと競合する。

■ 型名が、同一の有効範囲内で別の識別子と競合する。たとえば、プログラムで、異なるスキーマにある同じ名前の 2つの型を使用する場合に発生します。

■ プログラマが別の名前に変更する。

Page 317: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTデータ型マッピング

オブジェクト型トランスレータの使用 12-9

OTTでは、intypeファイルにリストしていないその他の型の変換が必要になる場合があります。 OTTでは変換前に intypeファイルの型の依存関係が分析され、必要に応じてその他の型が変換されるからです。 たとえば、ADDRESS型が intypeファイルにリストされていなくても、"Person"型が ADDRESS型の属性を所有している場合、"Person"型の定義は必須のため、OTTでは ADDRESSを変換します。

通常の大 /小文字の区別がない SQL識別子は、INTYPEファイルで、大 /小文字のどのような組合わせのつづりでも構いません。引用符は付けません。

CREATE TYPE"Person"のように大 /小文字を区別して作成した SQL識別子を参照するには、TYPE "Person"のように引用符を使用します。 SQL識別子は、宣言の際に引用した場合は、大 /小文字が区別されます。 引用符は、また、TYPE "CASE"のような OTT予約語である SQL識別子を参照するためにも使用できます。 その SQL識別子が CREATE TYPE Caseのように大 /小文字を区別しないで作成されている場合、名前に引用符を付けるときは、その名前は大文字である必要があります。 OTT予約語を SQL識別子の名前を参照するのに使用し、しかし引用符を付けていない場合は、OTTは INTYPEファイルに構文エラーをレポートします。

関連項目 : intypeファイル構造体の仕様および使用可能なオプションについては、12-27ページの「Intypeファイルの構造体」を参照してください。

OTTデータ型マッピングOTTでデータベース型から生成した C構造体には、オブジェクト型の属性ごとに 1つずつ対応する要素が含まれています。 属性のデータ型は、Oracle8のオブジェクト・データ型で使われる型にマップされます。オブジェクト型やコレクションなどのユーザー定義型の作成をサポートするために、Oracle8のデータ型には、事前定義済みのプリミティブな型の集合が組み込まれています。

Oracle8の事前定義済みの型の集合には、数値型や文字型を含む、プログラマによく知られている標準の型があります。 また、Oracle8で新たに導入されたデータ型 (BLOB、CLOBなど )も含まれています。

また、Oracle8には、オブジェクト型属性を C構造体で表現するための事前定義済みの型の集合も含まれています。 たとえば、次のようなオブジェクト型定義と、OTTで生成した対応する構造体宣言があるとします。

CREATE TYPE employee AS OBJECT( name VARCHAR2(30), empno NUMBER, deptno NUMBER, hiredate DATE, salary$ NUMBER);

CASE=LOWERで、型または属性名の明示的なマッピングがないと仮定すると、OTT出力は次のようになります。

struct employee

Page 318: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTデータ型マッピング

12-10 Oracle8コール・インタフェース・プログラマーズ・ガイド

{ OCIString * name; OCINumber empno; OCINumber department; OCIDate hiredate; OCINumber salary_;};typedef struct emp_type emp_type;struct employee_ind{ OCIInd _atomic; OCIInd name; OCIInd empno; OCIInd department; OCIInd hiredate; OCIInd salary_;}typedef struct employee_ind employee_ind;

標識の構造体 (struct employee_ind)については、12-15ページの「NULL標識の構造体」で説明します。

構造体宣言のデータ型 (OCIString、OCINumber、OCIDate、OCIInd)は、Oracle8で紹介されたオブジェクト型の新しい Cマッピングです。これらは、ここではオブジェクト型属性のデータ型をマップするのに使われます。 たとえば、empno属性の数値データ型は、新しいOCINumberデータ型にマップします。 また、これらの新しいデータ型は、バインド変数および定義変数の型としても使用します。

オブジェクト・データ型を Cにマッピングこの項目では、Oracle8のオブジェクト属性型と OTTで生成される Cの型とのマッピングを説明します。 次の 12-12ページの「OTT型マッピングの例」では、さまざまなマッピングの例を示します。次の表には、属性として使える型から、OTTで生成されるオブジェクト・データ型へのマッピングをリストします。

表 12–1 オブジェクト型属性のオブジェクト・データ型マッピング

オブジェクト属性の型 Cマッピング

VARCHAR2(N) OCIString *

VARCHAR(N) OCIString *

CHAR(N)、CHARACTER(N) OCIString *

NUMBER、NUMBER(N)、NUMBER(N,N) OCINumber

NUMERIC、NUMERIC(N)、NUMERIC(N,N) OCINumber

REAL OCINumber

Page 319: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTデータ型マッピング

オブジェクト型トランスレータの使用 12-11

名前付きコレクション型と、OTTで生成される Oracle8のオブジェクト・データ型とのマッピングを次の表に示します。

注意 : REFおよび VARRAY、NESTED TABLE型に対して、OTTでは typedefを生成します。 この typedefで宣言された型は、構造体 (struct)の宣言でデータ・メンバーの型として使われます。 次の項「OTT型マッピングの例」を参照してください。

オブジェクト型に REFまたはコレクション型の属性が含まれる場合、最初に REFまたはコレクション型の typedefが生成されます。 次に、オブジェクト型に対応する構造体宣言が生

INT、INTEGER、SMALLINT OCINumber

FLOAT、FLOAT(N)、DOUBLE PRECISION OCINumber

DEC、DEC(N)、DEC(N,N) OCINumber

DECIMAL、DECIMAL(N)、DECIMAL(N,N) OCINumber

日付 OCIDate

BLOB OCIBlobLocator *

CLOB OCIClobLocator *

BFILE OCIBfileLocator *

ネスト・オブジェクト型 ネスト・オブジェクト型の Cの名前

REF typedefを使用して宣言される ;OCIRef *と等価以下の例を参照。

RAW(N) OCIRaw *

表 12–2 コレクション型のオブジェクト・データ型マッピング

名前付きコレクション型 Cマッピング

VARRAY typedefを使用して宣言。

OCIArray *と等価

次の例を参照

NESTED TABLE typedefを使用して宣言。

OCITable *と等価

次の例を参照

表 12–1 オブジェクト型属性のオブジェクト・データ型マッピング

オブジェクト属性の型 Cマッピング

Page 320: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTデータ型マッピング

12-12 Oracle8コール・インタフェース・プログラマーズ・ガイド

成されます。 構造体には、REFまたはコレクション型へのポインタを型に持つ要素が含まれます。

あるオブジェクト型の中に含まれる属性が、別のオブジェクト型を型として持っている場合、OTTではネストした型が最初に生成されます。 次に、オブジェクト型属性が、ネストしたオブジェクト型である型のネストした構造体にマッピングされます。

OTTがオブジェクト以外のデータベースをマップする Oracle8の Cデータ型は構造体で、OCIDate以外は不明確です。

OTT型マッピングの例次の例では、OTTで作成される各種のマッピングを示します。

次のようなデータベース型があるとします。

CREATE TYPE my_varray AS VARRAY(5) of integer;

CREATE TYPE object_type AS OBJECT(object_name VARCHAR2(20));

CREATE TYPE my_table AS TABLE OF object_type;

CREATE TYPE many_types AS OBJECT( the_varchar VARCHAR2(30), the_char CHAR(3), the_blob BLOB, the_clob CLOB, the_object object_type, another_ref REF other_type, the_ref REF many_types, the_varray my_varray, the_table my_table, the_date DATE, the_num NUMBER, the_raw RAW(255));

次のような intypeファイルがあるとします。

CASE=LOWERTYPE many_types

OTTによって次の C構造体が生成されます。

注意 : 構造体についての補足説明として、ここではコメントを付け加えています。 これらのコメントは、実際の OTT出力の一部ではありません。

#ifndef MYFILENAME_ORACLE#define MYFILENAME_ORACLE

Page 321: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTデータ型マッピング

オブジェクト型トランスレータの使用 12-13

#ifndef OCI_ORACLE#include <oci.h>#endif

typedef OCIRef many_types_ref;typedef OCIRef object_type_ref;typedef OCIArray my_varray; /* part of many_types */typedef OCITable my_table; /* part of many_types*/typedef OCIRef other_type_ref;struct object_type /* part of many_types */{ OCIString * object_name;};typedef struct object_type object_type;

struct object_type_ind /*indicator struct for*/{ /*object_types*/ OCIInd _atomic; OCIInd object_name;};typedef struct object_type_ind object_type_ind;

struct many_types{ OCIString * the_varchar; OCIString * the_char; OCIBlobLocator * the_blob; OCIClobLocator * the_clob; struct object_type the_object; other_type_ref * another_ref; many_types_ref * the_ref; my_varray * the_varray; my_table * the_table; OCIDate the_date; OCINumber the_num; OCIRaw * the_raw;};typedef struct many_types many_types;

struct many_types_ind /*indicator struct for*/{ /*many_types*/ OCIInd _atomic; OCIInd the_varchar; OCIInd the_char; OCIInd the_blob; OCIInd the_clob;

Page 322: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTデータ型マッピング

12-14 Oracle8コール・インタフェース・プログラマーズ・ガイド

struct object_type_ind the_object; /*nested*/ OCIInd another_ref; OCIInd the_ref; OCIInd the_varray; OCIInd the_table; OCIInd the_date; OCIInd the_num; OCIInd the_raw;};typedef struct many_types_ind many_types_ind;

#endif

Intypeファイルでは変換対象として 1つの項目しか指定していませんが、2つのオブジェクト型と 2つの名前付きコレクション型が変換されていることに注意してください。 12-6ページの「OTTのコマンド行」で説明しているとおり、リストされた型の変換を完了するため、OTTでは変換する型の属性に使われた型はすべて自動的に変換します。

これは、オブジェクト型属性の中のポインタまたは REFによって アクセスするだけの型には適用しません。 たとえば、many_types型には属性として another_ref REF other_typeがありますが、struct other_typeは生成されません。

また、この例では、VARRAYおよびNESTED TABLE、REFの各型を宣言するためのtypedefsの使用方法を示しています。

typedefsは始めにきます。

typedef OCIRef many_types_ref;typedef OCIRef object_type_ref;typedef OCIArray my_varray; typedef OCITable my_table; typedef OCIRef other_type_ref;

struct many_typesでは、次のように VARRAYおよび NESTED TABLE、REF属性が宣言されています。

struct many_types{ ... other_type_ref * another_ref; many_types_ref * the_ref; my_varray * the_varray; my_table * the_table; ...}

Page 323: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Outtypeファイル

オブジェクト型トランスレータの使用 12-15

NULL標識の構造体OTTでデータベースのオブジェクト型を表現する C構造体が生成されるたびに、対応するNULL標識構造体も生成されます。 C構造体にオブジェクト型を選択するとき、パラレル構造体の中に NULL標識情報を選択できます。

たとえば、前の項目の例では次の NULL標識構造体が生成されます。

struct many_types_ind{OCIInd _atomic;OCIInd the_varchar;OCIInd the_char;OCIInd the_blob;OCIInd the_clob;struct object_type_ind the_object;OCIInd another_ref;OCIInd the_ref;OCIInd the_varray;OCIInd the_table;OCIInd the_date;OCIInd the_num;OCIInd the_raw;};typedef struct many_types_ind many_types_ind;NULL構造体のレイアウトは重要です。 構造体の第 1要素 (_atomic)は、アトミック NULL標識です。 この値は、オブジェクト型全体の NULL状態を示します。 このアトミック NULL標識の後に、OTTで生成した、オブジェクト型を表現する構造体の各要素に対応する標識要素が続きます。

あるオブジェクト型の定義の一部として別のオブジェクト型が含まれる場合(この例ではobject_type属性)、その属性の標識エントリは、ネストしたオブジェクト型に対応するNULL標識構造体 (object_type_ind)です。

VARRAYとNESTED TABLEには、要素の NULL情報が含まれます。

NULL標識構造体のその他の要素のデータ型は、すべて OCIIndです。

関連項目 : アトミック NULLについての詳細は、8-27ページの「NULL」を参照してください。

OuttypeファイルOuttypeファイルは、OTTコマンド行で名前が付けられます。 OTTで Cヘッダー・ファイルを生成すると、変換の結果が outtypeファイルに書き込まれます。 このファイルには、変換された各型のエントリが、バージョン文字列および C表現を書き込んだヘッダー・ファイルとともに含まれています。

Page 324: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

Outtypeファイル

12-16 Oracle8コール・インタフェース・プログラマーズ・ガイド

OTTを 1度実行して生成した outtypeファイルは、それ以降に OTTを起動する際の intypeファイルとして使用できます。

たとえば、この章の前半の例で使用した単純な intypeファイルを考えてみます。

CASE=LOWERTYPE employee TRANSLATE SALARY$ AS salary DEPTNO AS departmentTYPE ADDRESSTYPE itemTYPE personTYPE PURCHASE_ORDER AS p_o

この例では、OTTで生成する C識別子の大 /小文字の区別を指定し、変換する型をリストして指定しています。 そのうち 2つの型については、命名規則を指定しています。

OTT実行後の outtypeファイルは、次のようになります。

CASE=LOWERTYPE EMPLOYEE AS employee VERSION = "$8.0" HFILE = demo.h TRANSLATE SALARY$ AS salary DEPTNO AS departmentTYPE ADDRESS AS ADDRESS VERSION = "$8.0" HFILE = demo.hTYPE ITEM AS item VERSION = "$8.0" HFILE = demo.hTYPE "Person" AS Person VERSION = "$8.0" HFILE = demo.hTYPE PURCHASE_ORDER AS p_o VERSION = "$8.0" HFILE = demo.h

intypeで指定しなかった型が outtypeファイルにリストされる場合があります。 たとえば、intypeファイルで person型だけの変換を指定したとします。

CASE=LOWERTYPE PERSON

そして、person型の定義に address型の属性があり、Outtypeファイルに PERSONとADDRESSの両方のエントリがあるとします。 person型を完全に変換するには、最初にaddressを変換しなければなりません。

Page 325: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIアプリケーションでの OTTの使用方法

オブジェクト型トランスレータの使用 12-17

12-6ページの「OTTのコマンド行」で説明するように、OTTでは、変換する前に、型の依存性について intypeファイルの型を分析し、必要に応じてその他の型を変換します。

OCIアプリケーションでの OTTの使用方法OTTで生成した Cヘッダー・ファイルとインプリメンテーション・ファイルは、Oracle8 Server内のオブジェクトにアクセスする OCIアプリケーションで使用できます。 ヘッダー・ファイルは、#include文で OCIコードに取り込みます。

OCIアプリケーションでは、ヘッダー・ファイルを組み込んだ後、ホスト言語形式のオブジェクト・データにアクセスし、操作できます。

OCIで OTTを使用する際のステップを示します。

1. SQLを使用してデータベースに型定義を作成する。

2. OTTで、オブジェクト型と名前付きコレクション型の C表現を含むヘッダー・ファイルを生成する。 また、INITFILEオプションを使用して名前が付けられたインプリメンテーション・ファイルも生成します。

3. アプリケーションを記述する。 OCIアプリケーションでユーザーが記述したコードで、INITFUNC関数を宣言してコールします。

4. ヘッダー・ファイルを OCIソース・コード・ファイルに組み込みます。

5. OTTで生成されたインプリメンテーション・ファイルを含めて、OCIアプリケーションがコンパイルされ、OCIライブラリにリンクされます。

6. OCI実行可能ファイルを Oracle8 Serverに対して実行します。

Page 326: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIアプリケーションでの OTTの使用方法

12-18 Oracle8コール・インタフェース・プログラマーズ・ガイド

図 12–1 OCIでの OTTの使用方法

OCIでのオブジェクトへのアクセスおよび操作アプリケーション内部では、OCIプログラムでバインド操作と定義操作を実行できます。そのためには、OTTで生成したヘッダー・ファイルに示されている型で宣言したプログラム変数を使用します。

たとえば、アプリケーションで SQLの SELECT文を使用してオブジェクトへの REFをフェッチし、適切な OCI関数を使用してそのオブジェクトを確保します。 オブジェクトを確保した後、その他の OCI関数を使用してそのオブジェクトの属性データにアクセスし、操作できます。

Page 327: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIアプリケーションでの OTTの使用方法

オブジェクト型トランスレータの使用 12-19

OCIには、オブジェクト型の属性と名前付きコレクション型で操作するために特別に設計された、一連のデータ型マッピングおよび操作関数が組み込まれています。

使用可能な関数の例を次に示します。

■ OCIStringSize()は、OCIString文字列のサイズを入手。

■ OCINumberAdd()は、2つの OCINumber数値を加算。

■ OCILobIsEqual()は、2つの LOBロケータが等しいか比較。

■ OCIRawPtr()は、OCIRawのロー・データ型へのポインタを入手。

■ OCICollAppend()は、コレクション型 (OCIArrayまたはOCITable)に要素を追加。

■ OCITableFirst()は、ネストした表 (OCITable)の最初の既存要素の索引を戻す。

■ OCIRefIsNull()は、REF(OCIRef)がNULLかどうかテスト。

これらの関数の詳細は、このマニュアルの他の章に記載されています。

初期化関数のコールOTTは、必要に応じて C初期化関数を生成します。 初期化関数では、プログラムで使用されている各オブジェクト型について、どのバージョンの型が使用されているかを環境に通知します。 INITFUNCオプションで OTTを起動する場合、初期化関数の名前を指定するか、初期化関数が入ったインプリメンテーション・ファイル (INITFILE)の名前に基づいてデフォルト名を選択できます。

初期化関数には、環境ハンドル・ポインタとエラー・ハンドル・ポインタの 2つの引数があります。 一般的に、使用する初期化関数は 1つですが、必ずしもそうである必要はありません。 プログラムに、コンパイル済みの個別のピースがあり、異なる型を要求する場合、各ピースに対して、初期化関数を含む 1つの初期化ファイルをそれぞれ要求して、OTTを個別に実行することができます。

たとえば、OCIEnvInit()をコールし、明示的な OCIオブジェクト・コールによって環境ハンドルを作成した後、必ず初期化関数も明示的にコールする必要があります。 明示的に作成した環境ハンドルそれぞれに対して、必ずすべての初期化関数をコールする必要があります。 これによって、各ハンドルは、プログラム全体で使用しているすべての Oracle8データ型にアクセスできます。

EXEC SQL CONTEXT USEや EXEC SQL CONNECTなどの埋込み SQL文を使用して環境ハンドルを暗黙的に作成する場合、ハンドルは暗黙的に初期化され、初期化関数をコールする必要はありません。 これは、Pro*C/C++を OCIアプリケーションと結合している場合にのみ適用します。

次に、初期化関数の例を示します。

Intypeファイルの ex2c.typを指定します。これには以下を含みます。

TYPE BREN.PERSONTYPE BREN.ADDRESS

Page 328: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OCIアプリケーションでの OTTの使用方法

12-20 Oracle8コール・インタフェース・プログラマーズ・ガイド

そして、次のコマンド行を含みます。

ott userid=bren/bigkitty intype=ex2c outtype=ex2co hfile=ex2ch.h initfile=ex2cv.c

OTTでは、ファイル ex2cv.cに対して、次のように生成します。

#ifndef OCI_ORACLE#include <oci.h>#endif

sword ex2cv(OCIEnv *env, OCIError *err){ sword status = OCITypeVTInit(env, err); if (status == OCI_SUCCESS) status = OCITypeVTInsert(env, err, "BREN", 5, "PERSON", 6, "$8.0", 4); if (status == OCI_SUCCESS) status = OCITypeVTInsert(env, err, "BREN", 5, "ADDRESS", 7, "$8.0", 4); return status;}

関数 ex2cvでは型バージョン表を作成し、BREN.PERSON型と BREN.ADDRESS型を挿入します。

プログラムで明示的に環境ハンドルを作成する場合、明示的に作成するハンドルごとに初期化関数をコールする必要があるので、すべての初期化関数を生成し、コンパイルし、リンクしなければなりません。 プログラムが明示的に環境ハンドルを作成しない場合、初期化関数は必要ありません。

OTTで生成したヘッダー・ファイルを使用するプログラムでは、同時に生成された初期化関数も使用する必要があります。 より正確にいえば、OTTで生成したヘッダ・ファイルが、Pプログラムへの連結コードを生成するコンパイルに含まれる場合で、環境ハンドルが Pプログラムのどこかほかの場所で明示的に作成される場合は、OTTの同じ起動によって生成されるインプリメンテーション・ファイルも、Pプログラムにコンパイルおよび連結される必要があります。これが正確に行われるかどうかは、ユーザーしだいです。

初期化関数の作業C初期化関数は、OTTで処理する型のバージョン情報を提供します。 C初期化関数は、OTTで処理する各オブジェクト・データ型の名前とバージョン識別子を型バージョン表に追加します。

Page 329: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-21

Oracleの型マネージャで型バージョン表を使って、特定のプログラムで使用する型のバージョンを判断します。別々のときに OTTで生成した異なる複数の初期化関数によって、型バージョン表に同じ型が複数回追加される可能性があります。 型が複数回追加される場合、Oracleでは、毎回同じバージョンの型が確実に登録されるようにします。

初期化関数の関数プロトタイプを宣言し、関数をコールするのは、OCIプログラマの責任です。

注意 : Oracle8の現行のリリースでは、型ごとにバージョンは 1つだけです。 型バージョン表の初期化は、Oracle8の将来のリリースとの互換性のためだけに必要です。

OTTの参照OTTの動作は、OTTコマンド行または CONFIGファイルに指定するパラメータによって制御します。 また、一部のパラメータは、INTYPEファイルにも指定できます。

この項目では、次の内容を詳しく説明します。

■ OTTコマンド行の構文

■ OTTパラメータ

■ OTTパラメータの指定可能な場所

■ Intypeファイルの構造体

■ ネストされた #includeファイルの生成

■ SCHEMA_NAMESの使用方法

■ デフォルトの名前のマッピング

■ 制限

この章では、次の規則を使用して OTTの構文を説明します。

■ 山カッコ(<...>)で囲んだ文字列は、ユーザーが指定する文字列。

■ 大文字の文字列は、そのとおりに入力する文字列。ただし、大 /小文字の区別はされないので、小文字で入力しても有効。

■ OTTキーワードは、例やヘッダーでは小文字の単一スペース・フォントでリストされていますが、テキストでは、目立つように大文字で印刷されています。

■ 大カッコ [...]で囲んだ項目は、オプション項目。

■ 1つの項目(あるいはカッコで囲まれた複数の項目)のすぐ後の省略記号 (...)は、その項目を何度も繰り返し指定できることを示す。

■ これ以外の句読点記号は、示されているとおりに入力。 これらには、’.’、’@’などが含まれます。

Page 330: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-22 Oracle8コール・インタフェース・プログラマーズ・ガイド

OTTコマンド行の構文OTTコマンド行インタフェースは、OTTを明示的に起動してデータベース型を C構造体に変換するときに使用します。 オブジェクトを使用する OCIアプリケーションを開発する場合は、必ずこのインタフェースが必要です。

OTTコマンド行文は、キーワード OTTと、その後に続く OTTパラメータのリストによって構成されます。

OTTコマンド行文に指定できるパラメータは、次のとおりです。

[userid=<username>/<password>[@<db_name>]]

[intype=<in_filename>]

outtype=<out_filename>

code=<C|ANSI_C|KR_C>

[hfile=<filename>]

[errtype=<filename>]

[config=<filename>]

[initfile=<filename>]

[initfunc=<filename>]

[case=<SAME|LOWER|UPPER|OPPOSITE>]

[schema_name=<ALWAYS|IF_NEEDED|FROM_INTYPE>]

注意 : 一般に、OTTコマンドに続くパラメータの順番は問わず、OUTTYPEおよびCODEパラメータだけが常に要求されます。

HFILEパラメータは、ほとんどいつも使用されます。 省略すると、INTYPEファイルのそれぞれの型について、個別に HFILEを指定する必要があります。 OTTでは、INTYPEファイルにリストされていない型を変換する必要があると判断すると、エラーをレポートします。 したがって、INTYPEファイルが以前に OTT OUTTYPEファイルとして生成された場合のみ、HFILEパラメータは省略できます。

INTYPEファイルを省略すると、スキーマ全体が変換されます。 詳細は、この次の項目にあるパラメータの説明を参照してください。

OTTコマンド行文の例を次に示します。

OTT userid=marc/cayman intype=in.typ outtype=out.typ code=c hfile=demo.h errtype=demo.tls case=lower

OTTコマンド行の各パラメータについては、この後の各項で説明します。

Page 331: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-23

OTTパラメータOTTコマンド行にパラメータを入力するときの書式は、次のとおりです。

parameter=value

parameterはリテラル・パラメータ文字列であり、valueは有効なパラメータ設定値です。 リテラル・パラメータ文字列は大 /小文字を区別しません。

コマンド行のパラメータは、空白またはタブのいずれかを使用して区切ります。

また、パラメータは構成ファイル内でも指定できます。ただし、この場合、行の中に空白を入れることはできないので、各パラメータは独立した行に指定しなければなりません。 さらに、パラメータの CASEおよび HFILE、INITFUNC、INITFILEは INTYPEファイルに入れることができます。

useridUSERIDパラメータでは、Oracleユーザー名およびパスワード、オプションのデータベース名 (Net8のデータベース指定文字列 )を指定します。 データベース名を省略すると、デフォルトのデータベースが想定されます。 このパラメータの構文は、次のとおりです。

userid=<username/password[@db_name]>

これが第 1パラメータである場合は、"USERID="を省略して、次のように指定できます。

OTT username/password...

USERIDパラメータはオプションです。 これが省略されると、OTTは、usernameがユーザーのオペレーティング・システムのユーザー名である、ユーザー OPS$usernameとして、自動的にデフォルトのデータベースへの接続を試行します。

intypeINTYPEパラメータでは、オブジェクト型指定のリストを読み込む元のファイルの名前を指定します。 読み込んだリストにある型が、OTTによって変換されます。

このパラメータの構文は、次のとおりです。

intype=<filename>

USERIDが第 1パラメータ、INTYPEが第 2パラメータで、"USERID="を省略した場合は、"INTYPE="も省略できます。 INTYPEが指定されない場合、ユーザーのスキーマの型すべてが変換されます。

OTT username/password filename...

INTYPEファイルは、型宣言のMakeファイルと考えることができます。 C構造体宣言の必要な型を INTYPEファイルにリストします。 INTYPEファイルの書式については、12-27ページの「Intypeファイルの構造体」で説明します。

Page 332: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-24 Oracle8コール・インタフェース・プログラマーズ・ガイド

コマンド行または INTYPEファイルのファイル名に拡張子を付けないと、"TYP"または".typ"のようなプラットフォーム固有の拡張子が追加されます。

outtypeOTTで処理されるすべてのオブジェクト・データ型の型情報を書き込むファイルの名前です。 OUTTYPEファイルには、INTYPEファイルで明示的に指定したすべての型が含まれます。それに加えて、変換の対象である他の型の宣言で使用しているために変換された型が含まれる場合もあります。 OUTTYPEファイルは、以後 OTTを起動するときに INTYPEファイルとして使用できます。

outtype=<filename>

INTYPEパラメータと OUTTYPEパラメータが同一のファイルを参照している場合、INTYPEファイルの古い情報は、新しい INTYPEの情報に置き換えられます。 このことは、型の変更から型宣言の生成、ソースコードの編集、プリコンパイル、コンパイル、デバッグまでのサイクルで、同一の INTYPEファイルを繰返し使用するときに便利です。

OUTTYPEは必ず指定してください。

コマンド行または INTYPEファイルのファイル名に拡張子を付けないと、"TYP"または".typ"のようなプラットフォーム固有の拡張子が追加されます。

codeCODE=Cまたは CODE=KR_C、CODE=ANSI_Cとして、OTT出力の目的ホスト言語を指定します。"CODE=C"は、"CODE=ANSI_C"と等価です。

CODE= C|KR_C|ANSI_C

このパラメータは、デフォルト値がないので必ず指定する必要があります。

initfileINITFILEパラメータでは、OTTで生成した初期化ファイルを書き込むファイルの名前を指定します。 このパラメータを省略すると、初期化関数は生成されません。

Pro*C/C++プログラムの場合、必要な初期化は SQLLIB実行時ライブラリによって 実行されるので、INITFILEは必要ありません。 OCIプログラムのユーザーは、INITFILEファイルをコンパイルおよびリンクし、環境ハンドルの作成時に初期化関数をコールする必要があります。

コマンド行または INTYPEファイルで指定した INITFILEファイル名に拡張子を付けないと、"C"または ".c""のようなプラットフォーム固有の拡張子が追加されます。

initfile=<filename>

Page 333: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-25

initfuncINITFUNCパラメータは、OCIプログラムだけで使用します。 OTTで生成する初期化関数の名前を指定します。 このパラメータを省略すると、INITFILEの名前から初期化関数の名前が付けられます。

initfunc=<filename>

hfile組込み (.h)ファイルの名前を指定します。これは、INTYPEファイルで、型を記述して型の組込みファイルを指定していない場合に、その型を宣言するために OTTによって生成される組込みファイルです。 INTYPEファイルで各型の組込みファイルを個々に指定していない場合は、このパラメータが必要です。 INTYPEファイルに記述していない型を、2つ以上の異なるファイルで宣言した他の型で使用する場合は、INTYPEファイルに記述していない型も生成する必要があります。そのような場合もこのパラメータが必要です。

コマンド行または INTYPEファイルで指定した HFILEファイル名に拡張子を付けなかった場合、"H"や ".h"のようなプラットフォーム固有の拡張子が追加されます。

hfile=<filename>

configCONFIGパラメータでは、共通で使用するパラメータ指定をリストした OTT構成ファイルの名前を指定します。 また、パラメータ指定は、プラットフォームによって異なる位置にあるシステム構成ファイルから読み込まれます。 残りのすべてのパラメータ指定は、コマンド行または INTYPEファイルで指定する必要があります。

config=<filename>

注意 : CONFIGパラメータは、CONFIGファイルでは使えません。

errtypeこのパラメータを指定すると、INTYPEファイルのリストが、すべての情報メッセージおよびエラー・メッセージとともに ERRTYPEファイルに書き込まれます。 情報メッセージおよびエラー・メッセージは、ERRTYPEを指定したかどうかに関係なく、標準出力に送信されます。

実質的に、ERRTYPEファイルはエラー・メッセージが追加された INTYPEファイルのコピーです。 ほとんどの場合、エラー・メッセージにはエラーの原因となったテキストへのポインタが示されます。

コマンド行または INTYPEファイルで指定した ERRTYPEファイル名に拡張子を付けないと、"TLS"や ".tls"のようなプラットフォーム固有の拡張子が追加されます。

errtype=<filename>

Page 334: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-26 Oracle8コール・インタフェース・プログラマーズ・ガイド

caseこのパラメータは、OTTで生成する一部の C識別子の大 /小文字の区別に影響します。 CASEの可能な値は、SAME、LOWER、UPPER、OPPOSITEです。 CASE = SAMEの場合は、データベース型と属性名を C識別子に変換するとき、文字の大 /小文字は変更されません。 CASE=LOWERとすると、大文字はすべて小文字に変換されます。 CASE=UPPERとすると、小文字はすべて大文字に変換されます。 CASE=OPPOSITEとすると、大文字はすべて小文字に変換され、小文字はすべて大文字に変換されます。

CASE=[SAME|LOWER|UPPER|OPPOSITE]

このオプションは、INTYPEファイルに記述されていない識別子(明示的にリストされていない属性または型)だけに影響します。 大 /小文字の変換は、正当な識別子が生成された後で行われます。

注意 : INTYPEで特定した型の C構造体識別子の大 /小文字は、INTYPEファイルの大/小文字と同じです。 たとえば、INTYPEファイルに次の行が含まれるとします。

TYPE Worker

次に、OTTで生成します。

struct Worker {...};

一方で、INTYPEファイルに次のように記述したとします。

TYPE wOrKeR

OTTで生成します。

struct wOrKeR {...};

これは INTYPEファイルの大 /小文字区別どおりです。

INTYPEファイルに記述されていない、大 /小文字の区別のない SQL識別子は、CASE=SAMEの場合は大文字で、CASE=OPPOSITEの場合は小文字で指定します。 宣言されるとき引用符が付けられていない場合に SQL識別子は、大 /小文字の区別はありません。

schema_namesデフォルト・スキーマに基づいて付けた型のデータベース名を、OUTTYPEファイル内のスキーマ名で修飾する場合、このオプションで制御できます。 OTTで生成される OUTTYPEファイルには、型名をはじめ OTTで処理された型の情報が含まれます。

詳細は、12-31ページの「SCHEMA_NAMESの使用方法」を参照してください。

OTTパラメータの指定可能な場所OTTパラメータは、コマンド行、またはコマンド行で名前が付けられた CONFIGファイル、あるいはその両方で指定できます。 パラメータの一部は、INTYPEファイルでも指定できます。

Page 335: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-27

OTTは、次のように起動します。

OTT username/password <parameters>

コマンド行のパラメータの 1つが次の場合、

config=<filename>

構成ファイル <filename>からその他のパラメータが読み込まれます。

さらに、パラメータは、プラットフォームによって異なる位置にあるデフォルトの構成ファイルから読み込まれます。 このファイルは、常に存在しなければなりませんが、空でも構いません。 構成ファイルのパラメータは、スペースなしで、1行につき 1つ表示されなければなりません。

引数を指定しないで OTTを実行すると、オンライン・パラメータ・リファレンスが表示されます。

翻訳される OTTの型は、INTYPEパラメータで指定するファイルで命名されます。 パラメータの CASE および INITFILE、INITFUNC、HFILEは、INTYPEファイルに入れることもできます。 OTTで生成された OUTTYPEファイルには CASEパラメータ、および INITFILEが含まれます。初期化ファイルが生成されている場合は、INITFUNCパラメータも含まれます。 OUTTYPEファイルでは、型ごとにそれぞれ HFILEを指定します。

OTTコマンドの大 /小文字区別は、プラットフォームによって異なります。

Intypeファイルの構造体intypeおよび outtypeファイルは、OTTで変換する型をリストし、型名や属性名を有効な C識別子に変換する方法を判断するのに必要な情報すべてを提供します。 これらのファイルには、1つ以上の型指定を記述します。 また、次のオプションを指定する場合もあります。

■ CASE

■ HFILE

■ INITFILE

■ INITFUNC

CASEまたは INITFILE、INITFUNCオプションを指定する場合は、すべての型指定よりも前に指定しなければなりません。 これらのオプションをコマンド行と intypeファイルの両方に指定した場合は、コマンド行の値が使用されます。

簡単なユーザー定義の intypeファイルの例、および intypeファイルから OTTで生成される完全な outtypeファイルの例は、12-15ページの「Outtypeファイル」を参照してください。

Page 336: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-28 Oracle8コール・インタフェース・プログラマーズ・ガイド

Intypeファイルの型指定INTYPEでの型指定によって、これから変換するオブジェクト・データ型の名前を指定します。 また、OUTTYPEでの型指定によって、すでに変換したオブジェクト・データ型の名前を指定します。

TYPE PERSON AS PERSON VERSION = "$8.0" HFILE = demo.hThe structure of a type specification is as follows:TYPE <type_name> [AS <type_identifier>][VERSION [=] <version_string>][HFILE [=] <hfile_name>][TRANSLATE{<member_name> [AS <identifier>]}...]

The syntax of type_name is:[<schema_name>.]<type_name>

schema_nameは、指定のオブジェクト・データ型を所有するスキーマの名前です。type_nameは、その型の名前です。 デフォルト・スキーマは、OTTを実行するユーザーのデフォルト・スキーマです。 デフォルト・データベースは、ローカル・データベースです。

型指定の構成要素を次に説明します。

■ <type_name>。オブジェクト・データ型の名前です。

■ <type_identifier>。型を表わすのに使用する C識別子です。省略すると、デフォルトの名前マッピング・アルゴリズムが使用されます。

■ <version_string>。OTTの前の起動でコードが生成した際に使用した型のバージョン文字列です。 バージョン文字列は、OTTによって生成され、OUTTYPEファイルに書き込まれます。その OUTTYPEファイルは、後で OTTを実行するときに INTYPEファイルとして使用します。 バージョンの文字列は OTT操作に影響を与えませんが、最終的には稼動中のプログラムで使われるオブジェクト・データ型のバージョンを選択するのに使われます。

■ <type_identifier>。型を表わすのに使用する C識別子です。省略すると、デフォルトの型マッピング・アルゴリズムが使用されます。 詳細は、12-33ページの「デフォルトの名前のマッピング」を参照してください。

■ <member_name>。次の <identifier>に翻訳される属性(データ番号)の名前です。

■ <identifier>。ユーザーのプログラムで属性を表現する C識別子です。 識別子は、任意の数の属性に対してこの方法で指定できます。 指定していない属性については、デフォルトの名前マッピング・アルゴリズムが使用されます。

■ <hfile_name>。該当する構造体の宣言またはクラスが現れるヘッダファイルの名前です。<hfile name>を省略すると、宣言の生成時にはコマンド行の HFILEパラメータで指定したファイルが使用されます。

オブジェクト・データ型は、次のいずれかの場合に変換する必要があります。

Page 337: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-29

■ INTYPEファイルに指定されている。

■ 変換が必要な別の型の宣言で使用されている。

明示的に記述していない型があり、その型が、正確に 1つのファイルだけに宣言した型で必要だとします。この場合、明示的に記述していない型の変換結果は、それを必要とする明示的に宣言した型と同じファイルに書き込まれます。

明示的に記述していない型があり、その型が、複数の異なるファイルに宣言した型で必要だとします。この場合、要求された型の変換結果は、グローバルな HFILEファイルに書き込まれます。

ネストされた #includeファイルの生成OTTで生成した各 HFILEファイルに、その他の必要なファイルを #includeで組み込み、ファイル名から構成された記号を #defineで定義します。この記号は、HFILEがすでに組み込まれているかどうかを判断するために使用します。 たとえば、データベースに次の型があるとします。

create type px1 AS OBJECT (col1 number, col2 integer);create type px2 AS OBJECT (col1 px1);create type px3 AS OBJECT (col1 px1);

intypeファイルは次のとおりです。

CASE=LOWERtype pxl hfile tott95a.htype px3 hfile tott95b.h

次のようにして OTTを起動します。

ott scott/tiger tott95i.typ outtype=tott95o.typ code=c

この場合、次の 2つのヘッダー・ファイルが生成されます。

ファイル tott95b.hは次のとおりです。

#ifndef TOTT95B_ORACLE#define TOTT95B_ORACLE#ifndef OCI_ORACLE#include <oci.h>#endif#ifndef TOTT95A_ORACLE#include "tott95a.h"#endiftypedef OCIRef px3_ref;struct px3{

Page 338: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-30 Oracle8コール・インタフェース・プログラマーズ・ガイド

struct px1 col1;};typedef struct px3 px3;struct px3_ind{ OCIInd _atomic; struct px1_ind col1};typedef struct px3_ind px3_ind;#endif

ファイル tott95a.hは次のとおりです。

#ifndef TOTT95A_ORACLE#define TOTT95A_ORACLE#ifndef OCI_ORACLE#include <oci.h>#endiftypedef OCIRef px1_ref;struct px1{ OCINumber col1; OCINumber col2;}typedef struct px1 px1;struct px1_ind{ OCIInd _atomic; OCIInd col1; OCIInd col2;}typedef struct px1_ind px1_ind;#endif

このファイルでは、TOTT95B_ORACLEという記号を最初に定義しています。そのため、プログラマは、次の構造体を使用して tott95b.hを条件付きで組み込むことができます。その際、tott95b.hが組込みファイルに依存しているかどうかを考慮する必要はありません。

#ifndef TOTT95B_ORACLE#include "tott95b.h"#endif

この方法によって、プログラマは、適当なファイル (たとえば foo.h)から tott95b.hを組み込むことができます。その際、tott95b.hが、foo.hに組み込まれるその他のファイルにも組み込まれるかどうかは、わかっていなくてもかまいません。

記号 TOTT95B_ORACLEの定義の後に、ファイル oci.hが #includeによって組み込まれています。 oci.hは、OTTで生成した各 HFILEに組み込まれます。oci.hには、Pro*C/C++また

Page 339: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-31

は OCIプログラマにとって便利な型と関数の宣言が入っています。 OTTの #includeでダブルクォーテーション (" ")が使用されるのは、この場合だけです。

次に、ファイル tott95a.hを組み込みます。 このファイルを組み込む理由は、tott95b.hに必要な "struct px1"の宣言が入っているからです。 ユーザーの INTYPEファイルで、1つ以上のファイルに型宣言を書き込むよう要求すると、OTTではその他のファイルの内どれを各HFILEに組み込むかを判断し、必要な #includesを生成します。

この OTTの #includeで、引用符が使用されていることに注意してください。 tott95b.hを組み込むプログラムをコンパイルするとき、tott95a.hの検索は、ソース・プログラムが検出された場所から始まり、それ以降は処理系定義の検索規則に従います。 この方法で tott95a.hを検索できない場合は、INTYPEファイルで tott95a.hの位置を指定する際に、完全なファイル名 (/で始まる UNIXの絶対パス名など )を使用する必要があります。

SCHEMA_NAMESの使用方法このパラメータは、OTTが接続されたデフォルト・スキーマに基づいて付けた型の名前を、OUTTYPEファイル内のスキーマ名で修飾するかどうかを決定します。

デフォルト・スキーマ以外のスキーマに基づく型の名前は、OUTTYPEファイル内のスキーマ名で常に修飾されます。

スキーマ名で修飾するかしないかで、プログラム実行中に型がどのスキーマで検索されるかが決定します。

次の 3通りの設定があります。

■ schema_names=ALWAYS(デフォルト )

OUTTYPEファイル内のすべての型名をスキーマ名で修飾します。

■ schema_names=IF_NEEDED

デフォルト・スキーマに属する OUTTYPEファイル内の型名はスキーマ名で修 飾しません。 デフォルト・スキーマ以外のスキーマに属する型名は、スキーマ名で修飾します。

■ schema_names=FROM_INTYPE

INTYPEファイルに記述されている型は、INTYPEファイル内のスキーマ名で修飾されている場合だけ、OUTTYPEファイル内のスキーマ名で修飾されます。 INTYPEファイルで記述していない、デフォルト・スキーマに属する型を、型の依存関係があるために生成しなければならない場合があります。このような型は、その型に依存している、OTTで最初に検出された型がスキーマ名付きで書かれている場合にだけ、スキーマ名付きで書かれます。 ただし、OTTを接続したデフォルト・スキーマにない型は常に、明示的に指定したスキーマ名付きで書かれます。

OTTで生成する OUTTYPEファイルは、Pro*C/C++への入力パラメータです。Pro*C/C++の観点からいえば、これは Pro*C/C++の INTYPEファイルです。 このファイルは、データベース型名を C構造体名と対応付けます。 この情報は、構造体内で正しいデータベース型が確実に選択されるようにするために、実行時に使用されます。 OUTTYPEファイル (Pro*C/

Page 340: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-32 Oracle8コール・インタフェース・プログラマーズ・ガイド

C++ INTYPEファイル )内のスキーマ名で型が指定される場合、その型は、プログラム実行中に名前付きスキーマ内で検索されます。 型がスキーマ名なしで指定される場合、プログラムが接続するデフォルト・スキーマ内で検索されます。デフォルト・スキーマは、OTTが使用するデフォルト・スキーマと異なる場合があります。

例 SCHEMA_NAMESに FROM_INTYPEを設定し、INTYPEファイルで読み込みます。

TYPE PersonTYPE david.DeptTYPE eric.Company

OTTで生成した構造体を使用して、Pro*C/C++アプリケーションで sam.Companyおよびdavid.Dept、Personの各型を使用します。 スキーマ名のない Personを使用して、アプリケーションを接続するスキーマの Person型を表します。

OTTとアプリケーションの両方がスキーマ davidに接続する場合、アプリケーションは、OTTが使用した型と同じ型 (david.Person)を使用します。 OTTがスキーマ davidに接続していても、アプリケーションがスキーマ janaに接続している場合は、アプリケーションは型 jana.Personを使用します。 この動作は、スキーマ davidとスキーマ janaで、同じ"CREATE TYPE Person"文を実行済みの場合だけ、適切です。

一方、アプリケーションでは、どのスキーマに接続するかに関係なく型 david.Deptを使用します。 この動作のためには、INTYPEファイルに型名とともにスキーマ名を必ず記述する必要があります。

明示的に指定していない型が、OTTによって変換される場合があります。 たとえば、次のSQL宣言があるとします。

CREATE TYPE address AS OBJECT( street VARCHAR2(40),city VARCHAR(30),state CHAR(2),zip_code CHAR(10) );

CREATE TYPE Person AS OBJECT( name CHAR(20),age NUMBER,addr ADDRESS );

OTTがスキーマの davidに接続されると仮定すると、SCHEMA_NAMES=FROM_INTYPEが指定され、ユーザーの INTYPEファイルには次のいずれかが組み込まれます。

TYPE Person

または

TYPE david.Person

Page 341: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-33

しかし、ネストしたオブジェクト型として型 david.Personで使用している型david.Addressは、記述していないとします。 INTYPEファイルに "TYPE david.Person"を記述してある場合は、"TYPE david.Person"および "TYPE david.Address"が OUTTYPEファイルに書かれます。 INTYPEファイルに "Type Person"を記述してある場合は、"TYPE Person"および "TYPE Address"が OUTTYPEファイルに書かれます。

OTTで変換する複数の型に david.Address型を埋め込んであり、INTYPEファイルにはdavid.Address型を明示的に記述していない場合、スキーマ名を使用するかどうかは、埋込み david.Address型が OTTで最初に検出された時点で決まります。 なんらかの理由で、david.Address型にはスキーマ名を付け、Person型には付けないようにするには、明示的に次の要求をする必要があります。

TYPE david.Address

これは INTYPE FILEで要求します。

各型を単一のスキーマ内に宣言する通常の場合は、すべての型名を INTYPEファイル内のスキーマ名で修飾するのが最も安全です。

デフォルトの名前のマッピングOTTでオブジェクト型または属性の C識別子名を作成する場合、OTTは、その名前をデータベースのキャラクタ・セットから有効な C識別子に変換します。 まず、名前は、データベースのキャラクタ・セット から OTTで使用しているキャラクタ・セットに変換されます。 次に、その変換された名前の変換内容が INTYPEファイルに供給される場合は、その変換内容が使用されます。 それ以外の場合、OTTでは、CASEオプションを適用して、その名前を文字ごとにコンパイラのキャラクタ・セットに変換します。 このプロセスについての詳細は、次のとおりです。

OTTがデータベース・エンティティの名前を読み込む場合、その名前は、データベースのキャラクタ・セットから OTTで使用しているキャラクタ・セットに自動的に変換されます。 OTTがデータベース・エンティティの名前を正常に読み込むため、名前の文字のコードが 2つのキャラクタ・セットで異なりますが、すべての文字は OTTのキャラクタ・セットにある必要があります。

OTTで使用されるキャラクタ・セットが、必要なすべての文字を確実に含むようにする最も簡単な方法は、データベースのキャラクタ・セットと同一に作成することです。 ただし、OTTのキャラクタ・セットは、コンパイラのキャラクタ・セットのスーパーセットでなければなりません。 つまり、コンパイラのキャラクタ・セットが 7-bit ASCIIの場合、OTTのキャラクタ・セットはサブセットとして 7-bit ASCIIを含む必要があります。コンパイラのキャラクタ・セットが 7-bit EBCDICの場合は、OTTのキャラクタ・セットはサブセットとして 7-bit EBCDICを含む必要があります。 ユーザーは、OTTで使用するキャラクタ・セットを、NLS_LANG環境変数を設定して、またはその他のプラットフォーム固有のメカニズムによって指定します。

Page 342: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-34 Oracle8コール・インタフェース・プログラマーズ・ガイド

OTTがデータベース・エンティティの名前を読み込むと、その名前は、OTTで使用されるキャラクタ・セットからコンパイラのキャラクタ・セットに変換されます。 その名前の変換内容が INTYPEファイルで指定される場合、OTTはその変換内容を使用します。

それ以外の場合、OTTでは、次のように名前の変換を行います。

1. 最初に、OTTのキャラクタ・セットがマルチバイト・キャラクタ・セットの場合、その名前にある、等価のシングルバイト文字を持つマルチバイト文字をシングルバイト文字に変換する。

2. 次に、その名前は、OTTのキャラクタ・セットからコンパイラのキャラクタ・セットに変換する。 コンパイラのキャラクタ・セットは、US7ASCIIのように、シングルバイト・キャラクタ・セットです。

3. 最後に、有効になっている CASEオプションに従って、文字の大 /小文字を設定する。C識別子で無効な文字、またはコンパイラのキャラクタ・セットに変換内容がない文字は、アンダースコアに置き換えられます。 1文字でもアンダースコアに置き換えられた場合、OTTは警告メッセージを出します。 名前の中のすべての文字がアンダースコアに置き換えられた場合、OTTはエラー・メッセージを出します。

文字単位の名前の変換では、コンパイラのキャラクタ・セットにあるアンダースコアまたは数字、シングルバイト文字は変更されません。したがって、有効な C識別子は変更されません。

名前の変換ではたとえば、ウムラウトの付いた "o"、アクサングラーブの付いた "a" などのアクセントの付いたシングルバイトの文字をそれぞれ "o"や "a"に変換したり、またマルチバイト文字をシングルバイトと等価に変換する場合があります。名前の変換は、その名前に等価のシングルバイトがないマルチバイト文字がある場合、通常は失敗します。 この場合、ユーザーは、INTYPEファイルで名前の変換を指定する必要があります。

複数のデータベース識別子が同一の Cの名前にマッピングされている場合に生じる名前の競合は、OTTでは検出されません。そして、データベース識別子が Cキーワードにマッピングされるときの名前の問題も検出されません。

制限OTTの使用に影響のある制限は、次のとおりです。

ファイル名比較現在、OTTでは、コマンド行または INTYPEファイルに指定したファイル名を比較することによって、2つのファイルが同一かどうかが判別されます。 OTTで 2つのファイル名が同一のファイルを参照しているかどうかを判別する必要がある場合は、1つの潜在的な問題が生じます。 たとえば、OTTで生成されたファイル foo.hで、foo1.hに記述された型宣言と、/private/elias/foo1.hに記述された別の型宣言が必要な際に、OTTでは、2つのファイルが同一の場合は 1つの #include、2つのファイルが異なる場合は 2つの#includeを生成する必要があります。 しかし、実際には 2つのファイルは異なるという結論が出され、次のように 2つの #includeが生成されます。

Page 343: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

オブジェクト型トランスレータの使用 12-35

#ifndef FOO1_ORACLE#include "foo1.h"#endif#ifndef FOO1_ORACLE#include "/private/elias/foo1.h"#endif

foo1.hと /private/elias/foo1.hが別々のファイルである場合は、最初のファイルだけが組み込まれます。 foo1.hと /private/elias/foo1.hが同一ファイルである場合は、#includeが重複して書かれます。

そのため、コマンド行または INTYPEファイルでファイルを複数回記述するときは、各記述で正確に同じファイル名を使用しなければなりません。

Page 344: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

OTTの参照

12-36 Oracle8コール・インタフェース・プログラマーズ・ガイド

Page 345: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -1

索引数字3層アーキテクチャスレッド・セーフティ , 7-13

AADO. 「属性記述子オブジェクト」を参照ADT. 「抽象データ型」を参照AQ. 「アドバンスト・キューイング」を参照

BBFILEデータ型 , 3-20

BFILEデータ型 , 3-20BLOBデータ型 , 3-20

BLOBデータ型 , 3-20

CCASE OTTパラメータ , 12-26CHAR外部データ型 , 3-16

CHARZ外部データ型 , 3-17

checkerr()関数コード・リスト , 2-24

CLOBデータ型 , 3-21

CLOBデータ型 , 3-21CODE OTTパラメータ , 12-24CONFIG OTTパラメータ , 12-25COR, 「複合オブジェクト検索」を参照Cデータ型

OCIでの操作 , 9-5

DDATE外部データ型 , 3-14

DDL.「データ定義言語(DDL)」を参照DML.「データ操作言語(DML)」を参照

EERRTYPE OTTパラメータ , 12-25

FFILE

OSファイルとの関連付け , 7-25データ型 , 3-20ロケータ , 7-25

FLOAT外部データ型 , 3-11

GGTRID. 「トランザクション識別子」を参照

HHFILE OTTパラメータ , 12-25

IINITFILE OTTパラメータ , 12-24INITFUNC OTTパラメータ , 12-25INTEGER外部データ型 , 3-10

INTYPE OTTパラメータ , 12-23intypeファイル , 12-27

Page 346: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -2

OTTの実行時に提供 , 12-8構造 , 12-27

LLOB, 7-23

OCI関数 , 7-27OCI操作 , 7-23外部データ型 , 3-19作成 , 7-25定義 , 5-15データのフェッチ , 4-12バインディング , 5-9変更 , 7-25ロケータ , 2-12

LOB関数サーバーとの通信の往復

LOB操作コード例 , D-74コールバック , 7-30バッファリング , 7-27

LOB操作のバッファリング , 7-27LOB属性一時オブジェクト , 7-26

LOBのバッファリング , 7-27LOBバッファリングコード例 , D-94

LOBロケータ , 2-12, 7-23属性 , B-25

LONG外部データ型 , 3-13

LONG RAW外部データ型 , 3-15

LONG VARCHAR外部データ型 , 3-15

LONG VARRAW外部データ型 , 3-16

MMDO. 「メソッド記述子オブジェクト」を参照MLSLABEL外部データ型 , 3-17

NNCHAR問題 , 5-23

NCLOB

データ型 , 3-21NCLOBデータ型 , 3-21no-op定義 , 14-57

NULLアトミック , 8-27オブジェクトの , 8-27検出 , 2-29挿入 , 2-28データベースに挿入 , 2-27標識変数を使用して挿入 , 2-27

NULL標識構造体 , 8-27OTTで生成された , 8-8

NUMBER外部データ型 , 3-10

OOCIオブジェクト・サポート , 1-8概要 , 1-2部分 , 1-10リリース 8.0の新機能 , 1-10

OCI_ATTR_ALLOC_DURATION環境ハンドルの属性 , B-4

OCI_ATTR_CACHE属性 , 6-15

OCI_ATTR_CACHE_MAX_SIZE環境ハンドルの属性 , B-3

OCI_ATTR_CACHE_OPT_SIZE環境ハンドルの属性 , B-3

OCI_ATTR_CHAR_COUNT使用 , 5-25定義ハンドルの属性 , B-22バインド・ハンドルの属性 , B-19

OCI_ATTR_CHARSET_FORM属性 , 6-11, 6-14, 6-16定義ハンドルの属性 , B-23バインド・ハンドルの属性 , B-19

OCI_ATTR_CHARSET_ID属性 , 6-11, 6-14, 6-16, 6-18定義ハンドルの属性 , B-22バインド・ハンドルの属性 , B-19

OCI_ATTR_CLUSTERED属性 , 6-7

OCI_ATTR_COLLECTION_ELEMENT属性 , 6-9

OCI_ATTR_COLLECTION_TYPECODE属性 , 6-9

Page 347: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -3

OCI_ATTR_COMPLEXOBJECT_COLL_OUTOFLINECORハンドルの属性 , B-26

OCI_ATTR_COMPLEXOBJECT_LEVELCORハンドルの属性 , B-26

OCI_ATTR_COMPLEXOBJECTCOMP_TYPECOR記述子の属性 , B-27

OCI_ATTR_DATA_SIZE属性 , 6-10, 6-13, 6-15, 6-17

OCI_ATTR_DATA_TYPE属性 , 6-10, 6-13, 6-15, 6-17

OCI_ATTR_DBA属性 , 6-7

OCI_ATTR_ENCAPSULATION属性 , 6-11

OCI_ATTR_ENVサーバー・ハンドルの属性 , B-11サービス・コンテキスト・ハンドルの属性 , B-7

OCI_ATTR_EXTERNAL_NAMEサーバー・ハンドルの属性 , B-11

OCI_ATTR_FNCODE環境ハンドルの属性 , B-4サーバー・ハンドルの属性 , B-11ステートメント・ハンドルの属性 , B-15定義ハンドルの属性 , B-22バインド・ハンドルの属性 , B-19

OCI_ATTR_FOCBKサーバー・ハンドルの属性 , B-12

OCI_ATTR_HAS_DEFAULT属性 , 6-17

OCI_ATTR_HAS_FILE属性 , 6-9

OCI_ATTR_HAS_LOB属性 , 6-9

OCI_ATTR_HAS_NESTED_TABLE属性 , 6-9

OCI_ATTR_HW_MARK属性 , 6-15

OCI_ATTR_IN_V8_MODEサーバー・ハンドルの属性 , B-12サービス・コンテキスト・ハンドルの属性 , B-9

OCI_ATTR_INCR属性 , 6-15

OCI_ATTR_INDEX_ONLY属性 , 6-7

OCI_ATTR_INTERNAL_NAMEサーバー・ハンドルの属性 , B-12

OCI_ATTR_IOMODE属性 , 6-17

OCI_ATTR_IS_CONSTRUCTOR属性 , 6-12

OCI_ATTR_IS_DESTRUCTOR属性 , 6-12

OCI_ATTR_IS_INCOMPLETE_TYPE属性 , 6-9

OCI_ATTR_IS_MAP属性 , 6-12

OCI_ATTR_IS_NULL属性 , 6-16, 6-18

OCI_ATTR_IS_OPERATOR属性 , 6-12

OCI_ATTR_IS_ORDER属性 , 6-12

OCI_ATTR_IS_PREDEFINED_TYPE属性 , 6-9

OCI_ATTR_IS_RNDS属性 , 6-12

OCI_ATTR_IS_RNPS属性 , 6-12

OCI_ATTR_IS_SELFISH属性 , 6-12

OCI_ATTR_IS_SYSTEM_GENERATED_TYPE属性 , 6-9

OCI_ATTR_IS_SYSTEM_TYPE属性 , 6-9

OCI_ATTR_IS_TRANSIENT_TYPE属性 , 6-9

OCI_ATTR_IS_WNDS属性 , 6-12

OCI_ATTR_IS_WNPS属性 , 6-12

OCI_ATTR_LEVEL属性 , 6-17

OCI_ATTR_LINK属性 , 6-14, 6-18

OCI_ATTR_LIST_ARGUMENTS属性 , 6-7, 6-11

OCI_ATTR_LIST_COLUMNS属性 , 6-7

OCI_ATTR_LIST_SUBPROGRAMS属性 , 6-8

OCI_ATTR_LIST_TYPE属性 , 6-19

OCI_ATTR_LIST_TYPE_ATTRS属性 , 6-10

OCI_ATTR_LIST_TYPE_METHODS属性 , 6-10

OCI_ATTR_LOBEMPTYLOBロケータの属性 , B-25

OCI_ATTR_MAP_METHOD属性 , 6-10

Page 348: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -4

OCI_ATTR_MAX属性 , 6-15

OCI_ATTR_MAXDATA_SIZEバインドで使用 , 5-24バインド・ハンドルの属性 , B-20

OCI_ATTR_MIN属性 , 6-15

OCI_ATTR_NAME属性 , 6-8, 6-10, 6-11, 6-13, 6-14, 6-15, 6-17

OCI_ATTR_NUM_ATTRS属性 , 6-6

OCI_ATTR_NUM_COLS属性 , 6-7

OCI_ATTR_NUM_ELEMENTS属性 , 6-13

OCI_ATTR_NUM_HANDLES属性 , 6-19

OCI_ATTR_NUM_PARAMS属性 , 6-6

OCI_ATTR_NUM_TYPE_ATTRS属性 , 6-10

OCI_ATTR_NUM_TYPE_METHODS属性 , 6-10

OCI_ATTR_OBJECT環境ハンドルの属性 , B-3

OCI_ATTR_OBJID属性 , 6-7, 6-14, 6-15

OCI_ATTR_ORDER属性 , 6-15

OCI_ATTR_ORDER_METHOD属性 , 6-10

OCI_ATTR_OVERLOAD属性 , 6-8

OCI_ATTR_PARAM_COUNT記述ハンドルの属性 , B-24ステートメント・ハンドルの属性 , B-17

OCI_ATTR_PARTITIONED属性 , 6-7

OCI_ATTR_PASSWORDユーザー・セッション・ハンドルの属性 , B-13

OCI_ATTR_PDFMT定義ハンドルの属性 , B-23バインド・ハンドルの属性 , B-21

OCI_ATTR_PDSCL定義ハンドルの属性 , B-23バインド・ハンドルの属性 , B-20

OCI_ATTR_PIN_DURATION環境ハンドルの属性 , B-6

OCI_ATTR_PINOPTION環境ハンドルの属性 , B-4

OCI_ATTR_POSITION属性 , 6-17

OCI_ATTR_PRECISION属性 , 6-10, 6-13, 6-15, 6-17

OCI_ATTR_PREFETCH_MEMORYステートメント・ハンドルの属性 , B-18

OCI_ATTR_PREFETCH_ROWSステートメント・ハンドルの属性 , B-18

OCI_ATTR_PTYPE属性 , 6-6

OCI_ATTR_RADIX属性 , 6-17

OCI_ATTR_REF_TDO属性 , 6-9, 6-11, 6-14, 6-16, 6-18

OCI_ATTR_ROWIDステートメント・ハンドルの属性 , B-17

OCI_ATTR_ROWS_RETURNEDコールバックに使用 , 5-23バインド・ハンドルの属性 , B-21

OCI_ATTR_SCALE属性 , 6-11, 6-13, 6-16, 6-17

OCI_ATTR_SCHEMA属性 , 6-14

OCI_ATTR_SCHEMA_NAME属性 , 6-11, 6-13, 6-16, 6-18

OCI_ATTR_SEQ属性 , 6-14

OCI_ATTR_SERVERサービス・コンテキスト・ハンドルの属性 , B-7

OCI_ATTR_SESSIONサービス・コンテキスト・ハンドルの属性 , B-9

OCI_ATTR_SQLCODEサービス・コンテキスト・ハンドルの属性 , B-7

OCI_ATTR_STMT_TYPEステートメント・ハンドルの属性 , B-16

OCI_ATTR_SUB_NAME属性 , 6-18

OCI_ATTR_TABLESPACE属性 , 6-7

OCI_ATTR_TIMESTAMP属性 , 6-6

OCI_ATTR_TRANSサービス・コンテキスト・ハンドルの属性 , B-9

OCI_ATTR_TRANS_NAMEトランザクション・ハンドルの属性 , B-14

OCI_ATTR_TYPE_NAME属性 , 6-11, 6-13, 6-16, 6-18

OCI_ATTR_TYPECODE属性 , 6-9, 6-10, 6-13, 6-17

OCI_ATTR_USRNAME

Page 349: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -5

ユーザー・セッション・ハンドルの属性 , B-13OCI_ATTR_VERSION属性 , 6-9

OCI_ATTR_XIDトランザクション・ハンドルの属性 , B-14

OCI_PTYPE_ARG属性 , 6-17

OCI_PTYPE_COL属性 , 6-15

OCI_PTYPE_COLL属性 , 6-13

OCI_PTYPE_FUNC属性 , 6-7

OCI_PTYPE_LIST属性 , 6-19

OCI_PTYPE_PKG属性 , 6-8

OCI_PTYPE_PROC属性 , 6-7

OCI_PTYPE_SYN属性 , 6-14

OCI_PTYPE_TABLE属性 , 6-7

OCI_PTYPE_TYPE属性 , 6-9

OCI_PTYPE_TYPE_ATTR属性 , 6-10

OCI_PTYPE_TYPE_FUNC属性 , 6-11

OCI_PTYPE_TYPE_PROC属性 , 6-11

OCI_PTYPE_VIEW属性 , 6-7

OCI_TYPECODE値 , 3-23, 3-24

OCIAQDeq(), 13-8OCIAQEnq(), 13-11OCIArray, 9-17バインディングと定義 , 9-17, 10-6

OCIArrayの操作コード例 , 9-19

OCIAttrGet(), 13-23記述用に使用 , 4-8

OCIAttrSet(), 13-25OCIBindArrayOfStruct(), 13-27OCIBindByName(), 13-29OCIBindByPos(), 13-33OCIBindDynamic(), 13-37OCIBindObject(), 13-41OCICacheFlush(), 14-11

OCICacheFree(), 14-13OCICacheRefresh(), 14-14OCICacheUnmark(), 14-16OCICacheUnpin(), 14-17OCIColl, 9-17バインディングと定義 , 9-17

OCICollAppend(), 15-9OCICollAssign(), 15-11OCICollAssignElem(), 15-13OCICollGetElem(), 15-15OCICollMax(), 15-18OCICollSize(), 15-19OCICollTrim(), 15-21OCIComplexObjectの使用 , 8-22

OCIComplexObjectCompの使用 , 8-22

OCIDate, 9-7バインディングと定義 , 9-7, 10-6

OCIDateAddDays(), 15-22OCIDateAddMonths(), 15-23OCIDateAssign(), 15-24OCIDateCheck(), 15-25OCIDateCompare(), 15-27OCIDateDaysBetween(), 15-28OCIDateFromText(), 15-29OCIDateGetDat(), 15-31OCIDateGetTime(), 15-32OCIDateLastDay(), 15-33OCIDateNextDay(), 15-34OCIDateSetDate(), 15-36OCIDateSetTime(), 15-37OCIDateSysDate(), 15-38OCIDateToText(), 15-39OCIDateZoneToZone(), 15-41OCIDateの操作コード例 , 9-8

OCIDefineArrayOfStruct(), 13-44OCIDefineByPos(), 13-46OCIDefineDynamic(), 13-50OCIDefineObject(), 13-53OCIDescAlloc(), 13-58OCIDescFree(), 13-60OCIDescribeAny(), 13-55使用 , 6-2使用例 , 6-20

OCIDuration使用 , 11-7, 11-13

OCIEnvInit(), 13-61OCIErrorGet(), 13-63

Page 350: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -6

OCIExtProcAllocCallmemory(), 16-4OCIExtProcGetEnv(), 16-8OCIExtProcRaiseExcp(), 16-5OCIExtProcRaiseExcpWithMsg(), 16-6OCIHandleAlloc(), 13-66OCIHandleFree(), 13-68OCIInd使用 , 8-28

OCIInitialize(), 13-70OCIIter, 9-17使用例 , 9-19バインディングと定義 , 9-17

OCIIterCreate(), 15-43OCIIterDelete(), 15-44OCIIterGetCurrent(), 15-45OCIIterInit(), 15-46OCIIterNext(), 15-47OCIIterPrev(), 15-49OCILdaToSvcCtx(), 13-73OCILobAppend(), 13-74OCILobAssign(), 13-76OCILobCharSet(), 13-78, 13-79OCILobCopy(), 13-80OCILobDisableBuffering(), 13-82OCILobEnableBuffering(), 13-83OCILobErase(), 13-84OCILobFileClose(), 13-86OCILobFileCloseAll(), 13-87OCILobFileExists(), 13-88OCILobFileIsOpen(), 13-91OCILobFileOpen(), 13-93OCILobFlushBuffer(), 13-96OCILobGetFile(), 13-89OCILobGetLength(), 13-98OCILobIsEqual(), 13-100OCILobLoadFromFile(), 13-101OCILobLocatorIsInit(), 13-103OCILobRead(), 13-105OCILobSetFile(), 13-94OCILobTrim(), 13-108OCILobWrite(), 13-109OCILockOpt可能な値 , 14-32

OCILogoff(), 13-113OCILogon(), 13-114使用 , 2-17

OCINumber, 9-10定義の例 , 10-8バインディングと定義 , 9-10, 10-6バインドの例 , 10-8

OCINumberAbs(), 15-51OCINumberAdd(), 15-52OCINumberArcCos(), 15-53OCINumberArcSin(), 15-54OCINumberArcTan(), 15-55OCINumberArcTan2(), 15-56OCINumberAssign(), 15-57OCINumberCeil(), 15-58OCINumberCompare(), 15-59OCINumberCos(), 15-60OCINumberDiv(), 15-61OCINumberExp(), 15-62OCINumberFloor(), 15-63OCINumberFromInt(), 15-64OCINumberFromReal(), 15-66OCINumberFromText(), 15-67OCINumberHypCos(), 15-69OCINumberHypSin(), 15-70OCINumberHypTan(), 15-71OCINumberIntPower(), 15-72OCINumberIsZero(), 15-73OCINumberLn(), 15-74OCINumberLog(), 15-75OCINumberMod(), 15-76OCINumberMul(), 15-77OCINumberNeg(), 15-78OCINumberPower(), 15-79OCINumberRound(), 15-80OCINumberSetZero(), 15-81OCINumberSign(), 15-82OCINumberSin(), 15-83OCINumberSqrt(), 15-84OCINumberSub(), 15-85OCINumberTan(), 15-86OCINumberToInt(), 15-87OCINumberToReal(), 15-89OCINumberToText(), 15-90OCINumberTrunc(), 15-92OCINumberの操作コード例 , 9-13, 8-12

OCIObjectArrayPin(), 14-18OCIObjectCopy(), 14-20OCIObjectExists(), 14-22OCIObjectFlush(), 14-23OCIObjectFree(), 14-24OCIObjectGetAttr(), 14-26OCIObjectGetInd(), 14-28OCIObjectGetObjectRef(), 14-29OCIObjectGetTypeRef(), 14-34OCIObjectIsDirty(), 14-35

Page 351: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -7

OCIObjectIsLocked(), 14-36OCIObjectLifetime可能な値 , 14-31

OCIObjectLock(), 14-37OCIObjectMarkDelete(), 14-38OCIObjectMarkDeleteByRef(), 14-40OCIObjectMarkStatus可能な値 , 14-32

OCIObjectMarkUpdate(), 14-41OCIObjectNew(), 14-43OCIObjectPin(), 14-46OCIObjectPinCountReset(), 14-49OCIObjectPinTable(), 14-51OCIObjectRefresh(), 14-53OCIObjectSetAttr(), 14-55OCIObjectUnmark(), 14-57OCIObjectUnmarkByRef(), 14-58OCIObjectUnpin(), 14-59OCIParamGet(), 13-116記述用に使用 , 4-8

OCIParamSet(), 13-118OCIPasswordChange(), 13-120OCIPinOpt使用 , 11-7

OCIRaw, 9-16バインディングと定義 , 9-16, 10-6

OCIRawAllocSize(), 15-93OCIRawAssignBytes(), 15-94OCIRawAssignRaw(), 15-95OCIRawPtr(), 15-96OCIRawResize(), 15-97OCIRawSize(), 15-98OCIRawの操作コード例 , 9-16

OCIRef, 9-22使用例 , 9-22バインディングと定義 , 9-22

OCIRefAssign(), 15-99OCIRefClear(), 15-100OCIRefFromHex(), 15-101OCIRefHexSize(), 15-103OCIRefIsEqual(), 15-104OCIRefIsNull(), 15-105OCIRefToHex(), 15-106OCISBreak()使用 , 2-29

OCIServerAttach(), 13-122OCIServerDetach(), 13-124OCIServerVersion(), 13-125OCISessionBegin(), 13-126

OCISessionEnd(), 13-129OCIStmtExecute(), 13-130

itersパラメータの使用 , 4-6プリフェッチ , 4-6

OCIStmtFetch(), 13-133OCIStmtGetBind(), 13-134OCIStmtGetPieceInfo(), 13-136OCIStmtPrepare(), 13-138

SQL文の準備 , 4-4OCIStmtSetPieceInfo(), 13-140OCIString, 9-15バインディングと定義 , 9-15, 10-6

OCIStringAllocSize(), 15-108OCIStringAssign(), 15-109OCIStringAssignText(), 15-110OCIStringPtr(), 15-111OCIStringResize(), 15-112OCIStringSize(), 15-113OCIStringの操作コード例 , 9-15

OCISvcCtxBreak(), 13-43OCISvcCtxToLda(), 13-142OCITable, 9-17バインディングと定義 , 9-17, 10-6

OCITableDelete(), 15-114OCITableExists(), 15-115OCITableFirst(), 15-116OCITableLast(), 15-117OCITableNext(), 15-118OCITablePrev(), 15-120OCITableSize(), 15-122OCITransCommit(), 13-143OCITransDetach(), 13-146OCITransForget(), 13-147OCITransPrepare(), 13-148OCITransRollback(), 13-149OCITransStart(), 13-150OCIType説明 , 9-23

OCITypeArrayByName(), 14-61OCITypeArrayByRef(), 14-64OCITypeByName(), 14-66OCITypeByRef(), 14-68OCITypeElem説明 , 9-23

OCITypeMethod説明 , 9-23

OCIアプリケーション一般的構造 , 2-2オブジェクトを使用した構造体 , 8-4

Page 352: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -8

構造 , 2-2コンパイル , 1-11終了 , 2-22初期化例 , 2-18ステップ , 2-14での OTTの使用 , 12-17リンク , 1-11

OCI環境オブジェクトの初期化 , 8-9

OCI関数コールの取消し , 2-29リターン・コード , 2-24, 2-26

OCIコールの中止 , 2-29OCIコールの取消し , 2-29OCIナビゲーショナル関数 , 11-19確保 /確保解除 /解放関数 , 11-19その他の関数 , 11-21名前付けスキーム , 11-19フラッシュ関数 , 11-19マーク関数 , 11-20メタ属性アクセサ関数 , 11-20

OCIプログラム。「OCIアプリケーション」を参照OCIプロセスオブジェクトの初期化 , 8-9初期化 , 2-16モード , 2-16

OCIリリース 8オブジェクトのアクセスと操作 , 12-18

OCIリレーショナル関数クイック・リファレンス , 13-3参照項目の概要 , 13-7, 16-3

OCIリレーショナル関数へのクイック・リファレンス, 13-3

OID. 「オブジェクト識別子」を参照Oracle Security Services, 7-42Oracle8データ型バインディングと定義 , 10-6

Oracleコール・インタフェース。OCIを参照Oracleデータ型 , 3-2

Cへのマッピング , 9-3oratypes.h内容 , 3-26

ORE. 「オブジェクト・ランタイム環境」を参照OTT

intypeファイルの提供 , 12-8概要 , 12-2起動 , 12-4コマンド行 , 12-6コマンド行構文 , 12-22参照 , 12-21

使用 , 12-1使用方法制限 , 12-34データ型マッピング , 12-9データベースでの型の作成 , 12-4パラメータ , 12-23

OTT. 「オブジェクト型トランスレータ」を参照OTTパラメータ

CODE, 12-24CONFIG, 12-25ERRTYPE, 12-25HFILE, 12-25INITFILE, 12-24INITFUNC, 12-25INTYPE, 12-23SCHEMA_NAMES, 12-26USERID, 12-23表示される場所 , 12-26CASE, 12-26OUTTYPE, 12-24

OUTTYPE OTTパラメータ , 12-24OTT

outtypeファイル , 12-15outtypeファイル , 12-27

OTTの実行時 , 12-15

PPDO. 「パラメータ記述子オブジェクト」を参照PL/SQL

OCIアプリケーションでの使用 , 2-30OCIプログラムでの使用 , 5-6REFカーソルのバインディングと定義 , 5-25出力変数の定義 , 5-15ネストした表のバインディングと定義 , 5-25ピース単位操作 , 7-20プレースホルダのバインド , 2-30

RRAW外部データ型 , 3-15

REF外部データ型 , 3-19サーバーからの取得 , 8-10定義 , 5-15, 10-4バインディング , 5-9, 10-3標識変数 , 2-27, 2-29

REFカーソル

Page 353: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -9

バインディングと定義 , 5-25refカーソル変数バインディング , 5-11

RETURNING句OCIの使用REFで , 5-21エラー処理 , 5-21コード例 , D-25バインディング , 5-21

RETURNING句を使用する DML「RETURNING句」を参照

ROWID位置づけ更新および位置づけ削除に使用 , 2-30外部データ型 , 3-13

ROWID記述子 , 2-13

Ssb1定義 , 3-26

sb2定義 , 3-26

sb4定義 , 3-26

SCHEMA_NAMES OTTパラメータ , 12-26使用方法 , 12-31

SQLT_NTY記述 , 3-18定義の例 , 10-13バインドの例 , 10-12

SQLT_REF記述 , 3-19

SQLT 型コード , 3-24SQL処理コード例 , D-2

SQL問合せ , 5-12結果のフェッチ , 4-11出力変数の定義 , 4-11, 10-4出力変数の定義。「操作の定義」を参照バインディング・プレースホルダ。 「バインド操作」を

参照SQL 文処理 , 4-2

SQL文 , 1-4種類データ定義言語(DDL), 1-4

型PL/SQL, 1-6埋込み SQL, 1-7

制御文 , 1-5問合せ , 1-5

実行の準備 , 4-4種類データ操作言語(DML), 1-5

準備するタイプの決定 , 4-4バインディング・プレースホルダ , 4-5, 5-2, 10-2

STRING外部データ型 , 3-12

sword定義 , 3-26

TTDO型記述子オブジェクト。「TDO」を参照取得 , 9-23説明 , 9-23定義 , 10-2

TDO. 「型記述子オブジェクト」を参照

Uub1定義 , 3-26

ub2定義 , 3-26

ub4定義 , 3-26

UNSIGNED外部データ型 , 3-15

USERID OTTパラメータ , 12-23

VVARCHAR外部データ型 , 3-13

VARCHAR2外部データ型 , 3-9

VARNUM外部データ型 , 3-13

VARRAW外部データ型 , 3-15

Wwith_context外部プロシージャ関数の引数 , 16-2

Page 354: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -10

XXID. 「トランザクション識別子」を参照xtramem_szパラメータ使用 , 2-14

あ値 , 8-5オブジェクト・アプリケーション , 8-6

アップグレード7.x to 8.0, A-47.x to 8.0 OCI, A-6

アドバンスト・キューイングデキュー関数 , 13-8エンキュー関数 , 13-11例 , 13-12OCIおよび , 7-39OCI対 PL/SQL, 7-40説明 , 7-39用 OCI関数 , 7-39用 OCIの説明 , 7-39

アトミック NULL, 8-27アプリケーションリンク , 2-30

アプリケーション・フェイルオーバーOCIコールバック , 7-35コールバックの登録 , 7-36コールバックの例 , 7-37

移植7.x to 8.0, A-4

一時オブジェクト , 8-6LOB属性 , 7-26メタ属性 , 8-19

位置づけ更新 , 2-30位置づけ削除 , 2-30一貫性オブジェクト・キャッシュ , 11-4

埋込み SQL, 1-7OCIコールとの混在 , 1-7

埋込みオブジェクトフェッチ , 8-14

永続オブジェクト , 8-5メタ属性 , 8-16

エラーオブジェクト・アプリケーションでの処理 , 8-30ハンドル , 2-24

エラー・コードナビゲーショナル関数 , 14-5

エラーハンドル

例 , 2-24エラー・ハンドル記述 , 2-7

オブジェクトLOB属性 , 7-26NULL, 8-27OCIオブジェクト・アプリケーション構造体 , 8-4OCIでのアクセス , 12-18OCIでの使用 , 8-2OCIでの操作 , 12-18一時 , 8-5, 8-6一時オブジェクトの LOB属性 , 7-26インスタンスのメモリー・レイアウト , 11-15永続 , 8-5解放 , 8-30, 11-8確保 , 8-11, 11-6確保解除 , 8-27, 11-8確保カウント , 8-27型 , 8-5クライアント側キャッシュ , 11-2継続時間 , 11-13継続時間の確保 , 11-13コピー , 8-30作成 , 8-30属性 , 8-16操作 , 8-12

存続期間 , 14-2トップレベル・メモリー , 11-15ナビゲーション , 11-17単純 , 11-17

2次メモリー , 11-15配列確保 , 8-12フラッシュ , 11-10変更のフラッシュ , 8-13マーク , 8-13, 11-9マーク解除 , 11-10メタ属性 , 8-16メモリー管理 , 11-2用語 , 8-5リフレッシュ , 11-10ロック , 11-12割当て継続時間 , 11-13型 , 14-2用語 , 14-2

オブジェクト型トランスレータOCIでの使用方法 , 8-7「OTT」を参照

オブジェクト関数サーバーとの通信の往復 , E-4「ナビゲーショナル関数」を参照

Page 355: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -11

オブジェクト参照 , 8-30オブジェクト参照。「REF」を参照オブジェクト識別子永続オブジェクト用 , 8-5

オブジェクト付き OCIアプリケーション初期化 , 8-9

オブジェクトの解放 , 8-30, 11-8オブジェクトの確保 , 11-6オブジェクトの確保解除 , 11-8オブジェクトのコピー , 8-30オブジェクトの作成 , 8-30オブジェクトの取り出しコード例 , D-11

オブジェクトのフラッシュ , 11-10オブジェクトのマーク , 11-9オブジェクトのマーク解除 , 11-10オブジェクトのリフレッシュ , 11-10オブジェクトのロック , 11-12オブジェクト・アプリケーションコミット , 11-13データベース接続 , 8-9ロールバック , 11-13

オブジェクト・キャッシュ , 11-2一貫性 , 11-4オブジェクトの削除 , 11-6オブジェクトのロード , 11-6コヒーレンス , 11-4サイズの設定 , 11-5初期化 , 8-9操作 , 11-6メモリ・パラメータ , 11-5

オブジェクト・ランタイム環境初期化 , 8-9

オブジェクト型トランスレータサンプル出力 , 8-8

か外部データ型 , 3-4, 3-7

CHAR, 3-16CHARZ, 3-17DATE, 3-14FLOAT, 3-11INTEGER, 3-10LOB, 3-19LONG, 3-13LONG RAW, 3-15LONG VARCHAR, 3-15LONG VARRAW, 3-16

MLSLABEL, 3-17NUMBER, 3-10RAW, 3-15REF, 3-19ROWID, 3-13SQLT_BLOB, 3-19SQLT_CLOB, 3-19SQLT_NCLOB, 3-19SQLT_NTY, 3-18SQLT_REF, 3-19STRING, 3-12UNSIGNED, 3-15VARCHAR, 3-13VARCHAR2, 3-9VARNUM, 3-13VARRAW, 3-15名前付きデータ型 , 3-18変換 , 3-21

外部プロシージャOCIコールバック , 7-34

外部プロシージャ関数with_context型 , 16-2リターン・コード , 16-2

解明オブジェクトの解明のコード例 , D-54

拡張子デフォルトのファイル名 , 12-33

確保 , 11-6確保解除 , 8-27, 11-8確保カウント , 8-27型永続 , 8-5記述 , 6-2属性 , 6-9

型関数属性 , 6-11

型記述子オブジェクト , 9-23型コード , 3-23型参照 , 8-30型属性属性 , 6-10

型プロシージャ属性 , 6-11

カプセル化されたインタフェース , F-2環境ハンドル記述 , 2-7属性 , B-3

関数の初期化コール , 12-19

関連関数

Page 356: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -12

サーバーとの通信の往復 , E-7キーワード , C-2記述型の , 6-2コレクションの , 6-2シノニムの , 6-2順序の , 6-2ストアド・ファンクション , 6-2ストアド・プロシージャの , 6-2パッケージの , 6-2ビュー , 6-2表 , 6-2

記述子 , 2-11ROWID, 2-13スナップショット , 2-12パラメータ , 2-13複合オブジェクト検索 , 2-13割当て , 2-17

記述子オブジェクト , 9-23記述操作 , 4-8暗黙的 , 4-8サーバーとの通信の往復 , E-5

記述ハンドル記述 , 2-9属性 , B-24

キャッシュ関数サーバーとの通信の往復 , E-4

キャラクタ・セット ID, 5-23キャラクタ・セット・フォーム , 5-23グローバル・トランザクション , 7-4継続時間オブジェクト , 11-13例 , 11-14

継続時間の確保オブジェクト , 11-13例 , 11-14

更新位置づけ , 2-30ピース単位 , 7-16, 7-17

構成ファイルおよび OTT, 12-4

構造体配列 , 5-16

構造体の配列 , 5-16使用される OCIコール , 5-19スキップ・パラメータ , 5-17標識変数 , 5-19

コールバックLOBストリーム・インタフェース , 7-30LOB操作用 , 7-30

LOBの書込み用 , 7-32LOBの読込み用 , 7-31アプリケーション・フェイルオーバー , 7-35外部プロシージャから , 7-34パラメータ・モード , 13-50

コールバックの登録アプリケーション・フェイルオーバー , 7-36

コヒーレンスオブジェクト・キャッシュの , 11-4

コミット , 2-22オブジェクト・アプリケーション , 11-13グローバル・トランザクションの 1フェーズ , 7-8グローバル・トランザクションの 2フェーズ , 7-8

コレクション記述 , 6-2属性 , 6-13

さサーバーとの通信の往復

LOB関数オブジェクト関数 , E-4関連関数 , E-7記述操作 , E-5キャッシュ関数 , E-4データ型のマッピングおよび操作関数 , E-6

サーバー・ハンドルサービス・コンテキストでの設定 , 2-8属性 , B-11

サービス・コンテキスト・ハンドル記述 , 2-7属性 , B-7要素 , 2-7

削除位置づけ , 2-30

サーバー・ハンドル記述 , 2-7

参照。「REF」を参照実行複数サーバーに対する , 4-4モード , 4-7

シノニム記述 , 6-2属性 , 6-14出力変数の定義 , 5-12

SQL文種類データ定義言語(DDL), 1-4

順序

Page 357: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -13

記述 , 6-2属性 , 6-14

初期化関数作業 , 12-20

新機能 , F-2拡張機能 , F-2紹介 , F-2利点 , F-7

シングル・タスク・リンクサポート , A-9

スキップ・パラメータ構造体の配列 , 5-17標準配列 , 5-18

ステートメント・ハンドル属性 , B-15

ストアド・ファンクション記述 , 6-2

ストアド・プロシージャ記述 , 6-2

スナップショット実行 , 4-6

スナップショット記述子 , 2-12スナップショットの実行 , 4-6スレッド・セーフティ , 7-13

3層アーキテクチャ , 7-137.xと 8.0コールの混在 , 7-15OCIでの実現 , 7-14基本概念 , 7-14必要な OCIコール , 7-14利点 , 7-13

静的配列定義 , 5-16バインディング , 5-9

セキュリティ・ハンドル , 2-9選択リスト記述 , 4-8

操作の定義 , 4-11, 5-12, 10-4LOB, 5-15PL/SQL出力変数 , 5-15REF, 5-15, 10-4使用するステップ , 5-13静的配列 , 5-16名前付きデータ型 , 5-15, 10-4ピース単位フェッチ , 5-15例 , 5-13

挿入ピース単位 , 7-16, 7-17

属性オブジェクト , 8-16パラメータ記述子の , 6-5

パラメータの , 6-5ハンドル , 2-9

属性記述子オブジェクト , 9-23

た抽象データ型

Cアプリケーションでの表現 , 8-7ついて , 12-1通信の往復「サーバーとの通信の往復」を参照

定義OCINumber, 10-8配列 , 10-5

定義ハンドル記述 , 2-9属性 , B-22

データ型BFILE, 3-20BLOB, 3-20CLOB, 3-21Oracleから Cへのマッピング , 9-3FILE, 3-20NCLOB, 3-21OCIでの操作 , 9-5Oracle, 3-2外部 , 3-4, 3-7内部 , 3-4ピース単位操作用 , 7-17変換 , 3-21

データ型コード内部 , 3-4

データ型のマッピングおよび操作関数サーバーとの通信の往復 , E-6

データ型マッピング , 12-9Oracle方法論 , 9-4

データ構造8.0用の新規 , 2-4

データ操作言語(DML)SQL文 , 1-5

データ定義言語(DDL)SQL文 , 1-4

データベース接続オブジェクト・アプリケーション用 , 8-9

デフォルトのファイル名拡張子 , 12-33デフォルト名のマッピング , 12-33問合せ明示的記述 , 4-10

問合せ。 「SQL問合せ」を参照

Page 358: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -14

問合せ。「SQL問合せ」を参照トップレベル・メモリーオブジェクト , 11-15

トランザクションOCI関数トランザクション , 7-3

グローバル , 7-41フェーズ・コミット , 7-82フェーズ・コミット , 7-8トランザクション識別子 , 7-4ブランチ , 7-5ブランチの状態 , 7-7

グローバルな例 , 7-8コミット , 2-22初期化パラメータ , 7-10直列可能 , 7-4読込み専用 , 7-4ローカル , 7-3ローリング・バック , 2-22

トランザクション識別子 , 7-4トランザクションの複雑性

OCIでのレベル , 7-3トランザクション・ハンドル記述 , 2-8属性 , B-14

な内部データ型 , 3-4データ型コード , 3-4変換 , 3-21

ナビゲーショナル関数エラー・コード , 14-5戻り値 , 14-4用語 , 14-4

ナビゲーション , 11-17名前付きデータ型外部データ型 , 3-18定義 , 3-18, 5-15, 10-4バインディング , 5-9, 10-2バインディングと定義 , 10-6標識変数 , 2-27, 2-29

名前領域予約 , C-12

2次メモリーオブジェクト , 11-15

認証ユーザー , 7-11

ネストした表

要素順序 , 9-20

は廃止された OCIルーチン , A-2, A-4配列スキップ・パラメータ , 5-18

配列定義 , 10-5配列バインド , 10-3バインディング

OCINumber, 10-8配列 , 10-3まとめ , 5-11

バインドPL/SQLプレースホルダ , 2-30

バインド操作 , 4-5, 5-2, 10-2LOB, 5-9OCI_DATA_AT_EXECモード , 5-10OCI配列インタフェース , 5-4PL/SQL, 5-5REF, 5-9, 10-3refカーソル変数 , 5-11結合モード , 5-3使用ステップ , 5-5静的配列 , 5-9定位置対名前付き , 5-3名前付き対定位置 , 5-3名前付きデータ型 , 5-9, 10-2例 , 5-6

バインド・ハンドル記述 , 2-9属性 , B-19

パスワード管理 , 7-12パスワードの管理 , 7-11パッケージ記述 , 6-2属性 , 6-8

パラメータ属性 , 6-5モード , 13-7, 16-3文字列長 , 13-6文字列を渡す , 2-27

パラメータ記述子 , 2-13属性 , 6-5, B-24

ハンドル , 2-5Cデータ型 , 2-5エラー・ハンドル , 2-7親が解放される際に解放される子 , 2-6階層 , 2-6

Page 359: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -15

解放 , 2-5型 , 2-5環境ハンドル , 2-7記述ハンドル , 2-9サービス・コンテキスト・ハンドル , 2-7サーバー・ハンドル , 2-7定義ハンドル , 2-9トランザクション・ハンドル , 2-8バインド・ハンドル , 2-9文ハンドル , 2-9ユーザー・セッション・ハンドル , 2-8利点 , 2-6割当て , 2-5, 2-17

ハンドル属性 , 2-9設定 , 2-9読込み , 2-9

ピース単位操作 , 7-17PL/SQL, 7-20更新 , 7-16挿入 , 7-16フェッチ , 7-16, 7-21有効なデータ型 , 7-17

ピース単位フェッチ , 7-20引数属性 , 6-17

ビュー記述 , 6-2属性 , 6-7

表記述 , 6-2ぞくせい , 6-7

標識変数 , 2-28PL/SQL OUTバインド , 10-4REF定義 , 10-4REF用 , 2-27, 2-29構造体の配列 , 5-19名前付きデータ型 , 2-29名前付きデータ型定義 , 10-4名前付きデータ型バインド , 10-3名前付きデータ型用 , 2-27REFバインド , 10-3

ファンクション属性 , 6-7

フェッチピース単位 , 7-16, 7-20

フェッチ操作 , 4-11LOBデータ , 4-12プリフェッチ・カウントの設定 , 4-12

複合オブジェクト検索実現 , 8-22

ナビゲーショナル・プリフェッチ , 8-24複合オブジェクト検索 (COR)記述子属性 , B-27

複合オブジェクト検索 (COR)ハンドル属性 , B-26

複合オブジェクト検索(COR)記述子 , 2-13複合オブジェクト検索(COR)ハンドル , 2-9複合オブジェクト検索 , 8-20複数サーバー文の実行 , 4-4

フラッシュ , 11-10オブジェクトの変更 , 8-13

ブランチ再開 , 7-7連結解除 , 7-7

ブランチの再開 , 7-7ブランチの連結解除 , 7-7プリフェッチ

OCIStmtExecute()中に , 4-6行カウントの設定 , 4-12プリフェッチ・メモリー・サイズの設定 , 4-12

プロシージャ属性 , 6-7

文ハンドル記述 , 2-9

方法記述子オブジェクト , 9-23

まマーク解除 , 11-10マルチスレッド開発基本概念 , 7-14

明確でないインタフェース , F-2メタ属性一時オブジェクト , 8-19永続オブジェクト , 8-16オブジェクト , 8-16

文字列パラメータとして渡す , 2-27

戻り値ナビゲーショナル関数 , 14-4

やユーザー・セッション・ハンドルサービス・コンテキストでの設定 , 2-8記述 , 2-8属性 , B-13

ユーザー・メモリー

Page 360: Oracle8 コール・インタフェースotndnld.oracle.co.jp/document/products/iserver/oracle8/...OCI オブジェクト・アプリケーションの開発..... 8-7 オブジェクトのC

索引 -16

割当て , 2-14ユーザー認証 , 7-11用語このマニュアルで使用される , 1-7ナビゲーショナル関数 , 14-4

予約語 , C-2予約名前領域 , C-12

らリスト属性 , 6-19

リフレッシュ , 11-10リリース 8.0拡張機能 , F-2リンク , 2-30シングル・タスクのサポート , A-9発行 , A-7モード , A-7

列属性 , 6-15

ロールバック , 2-22オブジェクト・アプリケーション , 11-13

ロケータ , 2-11LOBデータ型用 , 2-12, 7-23

ロック , 11-12

わ割当て継続時間オブジェクト , 11-13例 , 11-14