4.4 Oracle Call Interface(OCI)

OCIとは、アプリケーションがOracleデータベース内でデータおよびスキーマを操作するために使用できる、一連のCライブラリ関数のことです。

4.4.1 Oracle Call Interface (OCI)について

OCIでは、次の項で説明するように、データベース・アクセスに従来の3GLおよびオブジェクト指向技法の両方がサポートされています。

OCIの重要なコンポーネントは、オブジェクト・キャッシュと呼ばれる作業領域を管理する一連のコールです。オブジェクト・キャッシュは、クライアント側のメモリー・ブロックで、サーバーに対しさらにラウンドトリップを行わなくても、プログラムはオブジェクト全部を格納し、オブジェクト間をナビゲートできるようになります。

オブジェクト・キャッシュは、それを使用するアプリケーションによって完全に制御および管理されます。Oracleサーバーは、オブジェクト・キャッシュにアクセスできません。オブジェクト・キャッシュを使用するアプリケーション・プログラムは、サーバーと一体となってデータ一貫性を保持し、同時発生する競合アクセスから作業領域を保護する必要があります。

OCIは、次の機能を備えています。

  • SQLを使用して、サーバー上のオブジェクトにアクセスします。

  • ポインタまたはREFを利用することによって、オブジェクト・キャッシュ内のオブジェクトにアクセスし、操作および管理します。

  • Oracleの日付、文字列および数値をCのデータ型に変換します。

  • オブジェクト・キャッシュのメモリー・サイズを管理します。

OCIは、オブジェクトを個々にロックできるようにして、同時実行性を改善します。これは、複雑なオブジェクト検索をサポートして、パフォーマンスを改善します。

OCI開発者は、Object Type Translatorを使用して、Oracleオブジェクト型に対応するCのデータ型を生成できます。

関連項目:

OCIでオブジェクトを使用する場合の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください

4.4.2 OCIプログラムにおける連想アクセス

OCIプログラムでは、オブジェクト・データを操作できるAPIを使用してオブジェクトへの連想アクセスをサポートしています。

3GLプログラムは、SQL文およびPL/SQLプロシージャを実行し、リレーショナル・データベースに格納されたデータを操作します。データは、通常サーバー上で処理されるので、クライアント側にデータを転送するコストが発生しません。OCIでは、オブジェクト・データを操作するSQL文を実行するAPIを提供することによって、この結合アクセスをサポートしています。特に、OCIでは、次のことができます。

  • オブジェクト・データおよびオブジェクト型スキーマ情報を操作するSQL文を実行します。

  • オブジェクト、オブジェクト参照(REF)およびコレクションを、SQL文の入力変数として渡します。

  • オブジェクト、REFおよびコレクションを、SQL文フェッチの出力として戻します。

  • オブジェクト、REFおよびコレクションを戻すSQL文のプロパティを記述します。

  • オブジェクトのパラメータまたは結果を持つPL/SQLプロシージャまたはファンクションを記述し実行します。

  • 拡張されたコミットおよびロールバック関数を介して、オブジェクト機能とリレーショナル機能を並用できます。

「Pro*C/C++での連想アクセス」を参照してください。

4.4.3 OCIプログラムのナビゲーショナル・アクセス

OCIプログラムでは、APIを使用したナビゲーショナル・アクセスが可能です。

オブジェクト指向のプログラミング・パラダイムでは、アプリケーションは、実社会のエンティティを、オブジェクト・グラフを形成する相互関連オブジェクトの集合としてモデル化します。オブジェクト間の関連は、参照として実装されます。アプリケーションは、いくつかのイニシャル・オブジェクトの集合から始めて、これらのイニシャル・オブジェクトの参照を使用して残りのオブジェクトにアクセスし、各オブジェクトで計算処理を実行することで、オブジェクトを処理します。OCIでは、ナビゲーショナル・アクセスとして知られる、オブジェクト参照を使用してオブジェクト間のアクセスを行うためのAPIが提供されています。特に、OCIでは、次のことができます。

  • クライアント・マシン上のメモリーにオブジェクトをキャッシュします。

  • オブジェクト参照を解除し、オブジェクト・キャッシュ内の対応するオブジェクトを確保します。確保されたオブジェクトは、ホスト言語表現に透過的にマップされます。

  • 確保されたオブジェクトが不要になった場合、キャッシュに通知します。

  • 1回のコールで、関連するオブジェクトをまとめてデータベースからクライアント・キャッシュにフェッチします。

  • オブジェクトをロックします

  • キャッシュ上でオブジェクトを作成、更新および削除します。

  • クライアント・キャッシュ上でオブジェクトに対して行われた変更を、データベースに反映します。

「Pro*C/C++でのナビゲーショナル・アクセス」を参照してください。

4.4.4 オブジェクト・キャッシュ

高パフォーマンスのオブジェクト・ナビゲーショナル・アクセスをサポートするために、OCIランタイムでは、メモリーにオブジェクトをキャッシュするためのオブジェクト・キャッシュを提供しています。

オブジェクト・キャッシュは、オブジェクト・キャッシュ内のデータベース・オブジェクトへの参照(REF)をサポートし、データベース・オブジェクトは、それらの参照を介して識別(確保)されます。オブジェクト・キャッシュは、データベース・オブジェクトに対して透過的で効率的なメモリー管理を提供するため、アプリケーションは、データベース・オブジェクトがキャッシュにロードされたときに、メモリーを割り当てたり解放する必要はありません。

さらに、データベース・オブジェクトは、キャッシュにロードされた際、ホスト言語に透過的にマップされます。たとえば、C言語では、データベース・オブジェクトは対応するC構造体へマップされます。オブジェクト・キャッシュは、キャッシュ上のオブジェクトと対応するデータベース・オブジェクトとの間の整合性を保ちます。トランザクションのコミット時にキャッシュ上のオブジェクト・コピーに対して行われた変更は、データベースに自動的に反映されます。

オブジェクト・キャッシュでは、REFをオブジェクトにマップするために、高速参照表がメンテナンスされます。アプリケーションがREFを参照解除するときに、対応するオブジェクトがオブジェクト・キャッシュにキャッシュされていない場合、オブジェクト・キャッシュは、サーバーに対して、オブジェクトをデータベースからフェッチしてオブジェクト・キャッシュにロードする要求を自動的に送信します。同一のREFに対するその後の参照解除は、ローカル・キャッシュ・アクセスになり、ネットワークのラウンドトリップが発生しないため、より高速になります。

キャッシュ内のオブジェクトにアクセス中であることをオブジェクト・キャッシュに通知するために、アプリケーションはオブジェクトを確保し、オブジェクトの処理が終わった時点で確保解除します。オブジェクト・キャッシュは、キャッシュの各オブジェクトの確保カウントをメンテナンスします。確保カウントは、確保コール(ピン・コール)で増加し、確保解除コール(アンピン・コール)で減少します。確保カウントが0になると、アプリケーションがそのオブジェクトを必要としなくなったことを意味します。

オブジェクト・キャッシュでは最低使用頻度(LRU)アルゴリズムを使用して、キャッシュのサイズが管理されます。キャッシュが最大サイズに達すると、LRUアルゴリズムによって確保カウントが0の候補オブジェクトが解放されます。

4.4.5 オブジェクトを操作するOCIプログラムの作成

型をCホスト言語形式で表してオブジェクトを操作するOCIプログラムを作成できます。

オブジェクトを操作するOCIプログラムを作成するときは、次の一般的な手順を実行する必要があります

  1. アプリケーション・オブジェクトに対応するオブジェクト型を定義します。
  2. SQL DDL文を実行して、必要なオブジェクト型をデータベースに定義します。
  3. オブジェクト型をホスト言語形式で表します。

    たとえば、Cプログラムでオブジェクト型のインスタンスを操作するには、それらの型をC言語形式で記述する必要があります。そのためには、オブジェクト型をC構造体で表します。OTTというツールを使用すると、オブジェクト型に対応するCの構造体を生成できます。OTTは、等価なC構造体をヘッダー・ファイル(*.h)に作成します。これらの*.hファイルを、アプリケーションを実装するC関数を含む*.cファイルにインポートします。

  4. アプリケーションの*.cファイルをOCIライブラリとともにコンパイルおよびリンクすることによって、アプリケーションの実行可能ファイルを作成します。

    関連項目:

    OCIプログラムをオブジェクトとともに効果的に使用するためのヒントおよび技法は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください

4.4.6 Cでのユーザー定義コンストラクタの定義

Cでユーザー定義コンストラクタを定義する場合は、PARAMETERS句にSELF(オプションで、SELF TDO)を指定する必要があります。

C関数を入力すると、オブジェクトがマップされるすべてのC構造体の属性は、NULLに初期化されます。関数により戻される値は、ユーザー定義型のインスタンスにマップされます。

例4-1に、Cでユーザー定義コンストラクタを定義する方法を示します。

例4-1 Cにおけるユーザー定義コンストラクタの定義

CREATE LIBRARY person_lib TRUSTED AS STATIC
/

CREATE TYPE person AS OBJECT
  (  name VARCHAR2(30),
     CONSTRUCTOR FUNCTION person(SELF IN OUT NOCOPY person, name VARCHAR2) 
         RETURN SELF AS RESULT);
/

CREATE TYPE BODY person IS
    CONSTRUCTOR FUNCTION person(SELF IN OUT NOCOPY person, name VARCHAR2) 
         RETURN SELF AS RESULT
    IS EXTERNAL NAME "cons_person_typ" LIBRARY person_lib WITH CONTEXT
    PARAMETERS(context, SELF, name OCIString, name INDICATOR sb4); 
END;/

SELFパラメータは、INパラメータと同様にマップされるため、NOT FINAL型の場合、(dvoid **)ではなく(dvoid *)にマップされます。戻り値のTDOは、SELFTDOと一致する必要があるため暗黙的です。戻り値はNULLになり得ないため、戻りインジケータも暗黙的です。