5 C、C++およびJavaによるデータ・カートリッジの実装
C、C++およびJavaを使用して、データ・カートリッジのメソッドを実装できます。メソッドとは、データ・カートリッジを使用して定義されたデータについて、許可される操作を定義するプロシージャおよびファンクションです。ここでは、外部プロシージャの開発とデバッグに関連する事項を重点的に取り扱います。
5.1 共有ライブラリ
共有ライブラリとは、Windows DLLやSolaris共有オブジェクトのように、外部プロシージャの実装コードを格納するオペレーティング・システム・ファイルです。Oracleから共有ライブラリへのアクセスには、別名ライブラリ(PL/SQL内でライブラリを表すスキーマ・オブジェクト)が使用されます。セキュリティ上の理由で、別名ライブラリを作成するにはDBA権限が必要です。
関連項目:
- 
                           
専用の外部プロシージャ・エージェントの使用に関する詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
 - 
                           
ディレクトリ・オブジェクトのライブラリに対するサポートの詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。
 
5.1.1 共有ライブラリの使用
別名ライブラリを作成するには、オペレーティング・システム上でのライブラリの位置を決定し、データベース管理者またはCREATE LIBRARY権限を持つユーザーとしてログインし、例5-1で示す文を入力する必要があります。これでデータベースに別名ライブラリ・スキーマ・オブジェクトが作成されます。別名ライブラリの作成後は、共有ライブラリをPL/SQLから名前DS_Libで参照できます。例5-1では、ライブラリの絶対パスを指定しています。
                     
ライブラリのコピーを複数のシステムで使用する場合は、指定(または専用)のエージェントによる外部プロシージャの分散実行をサポートするために、例5-2に示すように環境変数を使用してライブラリの相対位置を指定できます。この文では、${DS_LIB_HOME}環境変数を使用して、すべてのシステム上でライブラリを検出できる共通の参照ポイントまたはルート・ディレクトリを指定しています。AGENTキーワードに続く文字列は、ライブラリDS_Libに宣言される外部プロシージャの実行に使用するエージェント(実際にはデータベース・リンク)を指定します。
                     
Oracle Database 12cリリース1 (12.1)では、CREATE LIBRARY構文に対する2つの拡張が導入されています。1つは追加的な任意指定のCREDENTIALオプション、もう1つはDIRECTORYオブジェクト・オプションです。CREDENTIALオプションは、ライブラリを指定する外部サブプログラムの実行時にextprocエージェントが偽装するオペレーティング・システム・ユーザーの資格証明を指定します。ディレクトリ・オブジェクト・オプションは、共有ライブラリが格納されているディレクトリを指定します。
                     
例5-3では、フルパス文字列のかわりにディレクトリ・オブジェクト・オプションが指定されています。また、任意指定のCREDENTIAL引数も指定されています。extprocプロセスを通じた外部プロシージャ・コールがPL/SQLライブラリをロードするときに、extprocは、定義されたsmith_credential資格証明を認証し、これを「偽装」できます。
                     
CREATE LIBRARY文の呼び出し時にディレクトリまたは資格証明を指定しないと、ライブラリの作成でエラーが発生します。
                     
5.1.1.1 別名ライブラリの作成
例5-1 別名ライブラリの作成
CREATE OR REPLACE LIBRARY DS_Lib AS  
     '/data_cartridge_dir/libdatastream.so';
5.1.1.2 ライブラリの位置の指定
例5-2 環境変数を使用したライブラリの位置の指定
CREATE OR REPLACE LIBRARY DS_Lib AS 
  '${DS_LIB_HOME}/libdatastream.so' AGENT 'agent_link';
5.2 外部プロシージャ
PL/SQLは、データベース・プログラミングに適した強力な言語ですが、メソッドによっては複雑すぎてPL/SQLで最適にコーディングできないものがあります。たとえば、数値積分を実行するルーチンは、通常、PL/SQLではなくCで実装する方が実行速度が速くなります。
このように特化された処理をサポートするために、PL/SQLは他の言語で記述されたルーチンをコールするためのインタフェースを提供します。これにより、Cのような3GLのメリットと機能がデータベース・サーバーからのコールを介して使用可能になります。このような3GLルーチンは外部プロシージャと呼ばれ、共有ライブラリに格納され、PL/SQLに登録されてから、実行時にPL/SQLからコールされます。
外部プロシージャは、データ・カートリッジ開発者にとって重要なツールです。外部プロシージャを使用すると、カートリッジ・タイプ用の高速で効率的な計算集中型のルーチンを記述できるのみでなく、既存のコードをデータ・カートリッジとしてデータベースと統合できます。オーディオ・ファイルのフォーマット変換を実行するCのルーチンを含んだWindows NT DLLのように、その他の言語での既存の共有ライブラリは、オーディオ・カートリッジにより実装される型のメソッドから直接コールできます。同様に、外部プロシージャを使用して、信号の処理、デバイスの駆動、データ・ストリームの分析、グラフィックスのレンダリングまたは数値データの処理を行うことができます。
関連項目:
外部プロシージャおよび使用方法の詳細は、『PL/SQLユーザーズ・ガイドおよびリファレンス』を参照してください。
5.2.1 外部プロシージャの登録
外部プロシージャをコールするには、外部プロシージャを定義する別名ライブラリのみでなく、プロシージャのコール方法や渡す引数も、PL/SQLに対して指示する必要があります。
例3-1ではDataStream型が定義されており、例3-2ではDS_PackageパッケージからのファンクションをコールすることでDataStreamのメソッドが定義されています。例5-4では、このパーケージの本体を定義しています。
                        
PACKAGE BODY宣言句で、パッケージ・ファンクションが共有ライブラリ内の外部プロシージャに結合されることに注意してください。ファンクション宣言のEXTERNAL句では、名前(NAMEキーワードの後)、位置(必ず別名ライブラリ、LIBRARYキーワードの後)、外部プロシージャの記述言語(LANGUAGEキーワードの後)など、外部プロシージャに関する情報が登録されます。 
                        
この例では、EXTERNAL句の最後の部分はWITH CONTEXT指定です。ここでコンテキスト・ポインタが外部プロシージャに渡されます。コンテキスト・ポインタは外部プロシージャに対して不透明ですが、使用可能であるため、外部プロシージャはOracleサーバーにコールバックし、同じトランザクション・コンテキストでより多くのデータにアクセスできる可能性があります。
                        
この例では、オブジェクト型のメソッドからの外部プロシージャ・コールについて説明していますが、データ・カートリッジではPL/SQLの他の様々な場所から外部プロシージャを使用できます。外部プロシージャ・コールは次の場所で使用できます。
- 
                              
無名ブロック
 - 
                              
スタンドアロンおよびパッケージ・サブプログラム
 - 
                              
オブジェクト型のメソッド
 - 
                              
データベース・トリガー
 - 
                              
SQL文(パッケージ・ファンクションのコールでのみ可能)
 
関連項目:
- 
                                 
EXTERNAL句で指定できるパラメータの説明は、『PL/SQLユーザーズ・ガイドおよびリファレンス』を参照してください。外部プロシージャの概要、およびオブジェクト型をCルーチンに渡す際のコール指定の書式については、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。
 - 
                                 
WITHCONTEXT句については、「WITH CONTEXT句の使用」を参照してください。 
5.2.1.1 パッケージの本体の定義
例5-4 パーケージの本体の定義
CREATE OR REPLACE PACKAGE BODY DS_Package AS 
     FUNCTION DS_Findmin(data  CLOB) RETURN PLS_INTEGER IS EXTERNAL 
     NAME "c_findmin" LIBRARY DS_Lib LANGUAGE C WITH CONTEXT; 
     FUNCTION DS_Findmax(data CLOB) RETURN PLS_INTEGER IS EXTERNAL 
     NAME "c_findmax" LIBRARY DS_Lib LANGUAGE C WITH CONTEXT; 
   END;
5.3 PL/SQLによる外部プロシージャのコール方法
外部プロシージャをコールするには、プロシージャの常駐するDLLまたは共有ライブラリがPL/SQLで認識される必要があります。PL/SQLは、外部プロシージャを登録したサブプログラムのEXTERNAL句にある別名ライブラリを参照します。データ・ディクショナリを使用して、オペレーティング・システムの共有ライブラリまたはDLLへの実際のパスが判別されます。 
                  
PL/SQLはリスナー・プロセスにアラートを送り、リスナー・プロセスはセッション固有のエージェントを起動します。他に特定のエージェントが指定されていないかぎり、プロシージャの特定のライブラリに対するCREATE LIBRARY文、またはCREATE PROCEDURE文のエージェント引数で、デフォルト・エージェントextprocが起動されます。リスナーは、接続をエージェントに渡します。PL/SQLは、DLL名、外部プロシージャ名およびコール元から渡されたパラメータをエージェントに渡します。この説明の残りの部分では、起動されるエージェントがデフォルト・エージェントextprocであるとします。
                  
DLL名と外部プロシージャ名を受け取ったextprocは、DLLをロードして外部プロシージャを実行します。また、extprocはサービス・コール(例外の発生など)とOracleサーバーへのコールバックも処理します。最後に、extprocは外部プロシージャから戻された値をPL/SQLに渡します。図5-1に、制御フローを示します。 
                  
外部プロシージャが完了した後も、extproc はOracleセッション全体でアクティブになっています。そのため、extprocの起動コストが発生するのはコール回数に関係なく1回のみです。外部プロシージャは、計算上のメリットがコストを上回る場合にのみコールする必要があります。(ログオフ時にextprocが停止します。)
                  
リスナーは、Oracleサーバーが稼働しているシステム上でextprocを起動する必要があることに注意してください。他のシステム上でのextprocの起動はサポートされていません。
                  
関連項目:
- 
                           
専用の外部プロシージャ・エージェントを使用して外部プロシージャを実行する方法の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
 - 
                           
extprocおよび外部プロシージャ・コールの管理の詳細は、『Oracle Database管理者ガイド』を参照してください。 
5.4 外部プロシージャ用のファイルの構成
リスナーが外部プロシージャをディスパッチできるように、構成ファイルlistener.oraおよびtnsnames.oraに適切なエントリが必要です。
                  
リスナー構成ファイルlistener.oraには、例5-5で示すように外部プロシージャに関するSID_DESCエントリが必要です。
                  
例5-5では、次のことを想定しています。
- 
                        
Oracleインスタンス名が
o10であること。 - 
                        
Oracleサーバーが実行されるシステムまたはノードの名前が
unix123であること。 - 
                        
Oracleサーバーのインストール・ディレクトリが
/rdbms/u01であること。 - 
                        
Oracle TCP/IP通信のポート番号がデフォルトのリスナー・ポート
1521であること。 
ネットワーク基板構成ファイルのtnsnames.oraファイルも、例5-6で示すように、外部プロシージャを参照するように更新する必要があります。
                  
例5-6では外部プロシージャとの通信にIPCメカニズムが使用されることを想定しています。通信にはTCP/IPなども使用でき、その場合はPROTOCOLパラメータをtcpに設定する必要があります。
                  
関連項目:
listener.oraファイルおよびtnsnames.oraファイルの構成の詳細は、『Oracle Database管理者ガイド』を参照してください
                     
5.4.1 リスナー構成ファイルの更新
例5-5 リスナー構成ファイルでのSID_DESCエントリの設定
# Listener configuration file # This file is generated by stkconf.tsc CONNECT_TIMEOUT_LISTENER = 0 LISTENER = (ADDRESS_LIST= (ADDRESS=(PROTOCOL=ipc)(KEY=o10)) (ADDRESS=(PROTOCOL=tcp)(HOST=unix123)(PORT=1521)) ) SID_LIST_LISTENER = (SID_LIST= SID_DESC=(SID_NAME=o10)(ORACLE_HOME=/rdbms/u01/app/oracle/product/11.2.0.1.0) SID_DESC=(SID_NAME=extproc) (ORACLE_HOME=/rdbms/u01/app/oracle/product/11.2.0.1.0) (PROGRAM=extproc))
5.4.2 ネットワークに対する外部プロシージャ参照の指示
例5-6 外部プロシージャを参照するためのネットワーク基板構成ファイルの更新
o10 = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=unix123)(PORT=1521)) (CONNECT_DATA=(SID=o10))) extproc_connection_data = (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=o10)) CONNECT_DATA=(SID=extproc)))
5.4.3 外部プロシージャへのパラメータの受渡し
外部プロシージャへのパラメータの受渡しは、次のような状況により複雑化します。
- 
                           
PL/SQLデータ型のセットが、Cデータ型のセットと1対1で対応していない。
 - 
                           
PL/SQLのパラメータには
nullを使用できますが、Cのパラメータには使用できません。Cとは異なり、PL/SQLにはNULLかどうかというRDBMS概念が含まれる。 - 
                           
外部プロシージャで、
CHAR、LONGRAW、RAWおよびVARCHAR2パラメータの現在の長さまたは最大長が必要。 - 
                           
外部プロシージャで、
CHAR、VARCHAR2およびCLOBパラメータに関するキャラクタ・セット情報が必要。 - 
                           
PL/SQLで、外部プロシージャによって戻された値の現在の長さ、最大長またはNULL状態が必要。
 
このような状況に対処するために、パラメータ・リストをどのように指定する方法が最適かを考えます。例5-7ではパラメータの受渡しの例を示しています。ここでは、パッケージ・ファンクションDS_Findmin(data CLOB)がCルーチンc_findminをコールし、CLOB引数がOCILobLocator()としてCルーチンに渡されています。
                     
5.4.4 データ型の指定
外部プロシージャにパラメータを直接渡すことはありません。かわりに、外部プロシージャを登録したPL/SQLサブプログラムに渡します。そのため、パラメータのPL/SQLデータ型を指定する必要があります。表5-1は、各PL/SQLデータ型とデフォルトの外部データ型の対応関係を示したものです。外部データ型はCデータ型にマップされています。
PARAMETERS句を使用して、デフォルトのデータ型マッピングをオーバーライドすることができる場合もあります。たとえば、外部データ型INTから外部データ型CHARにPL/SQLデータ型のBOOLEANをマッピングしなおすことができます。
                     
Cプロトタイプ・パラメータの宣言時のエラーを回避するには、表5-2を参照してください。この表には、特定の外部データ型およびPL/SQLパラメータ・モードに指定するCデータ型が示されています。たとえば、OUTパラメータの外部データ型がCHAR型の場合は、Cプロトタイプにはデータ型char*を指定します。
                     
5.4.4.1 外部データ型への変換
表5-1 パラメータのデータ型マッピング
| PL/SQL型 | サポートされている外部型 | デフォルトの外部型 | 
|---|---|---|
BINARY_INTEGER, BOOLEAN, PLS_INTEGER  | 
                                    CHAR, UNSIGNED CHAR, SHORT, UNSIGNED SHORT, INT, UNSIGNED INT, LONG, UNSIGNED LONG, SB1, UB1, SB2, UB2, SB4, UB4, SIZE_T  | 
                                    INT  | 
                                 
NATURAL, NATURALN, POSITIVE, POSITIVEN, SIGNTYPE  | 
                                    CHAR, UNSIGNED CHAR, SHORT, UNSIGNED SHORT, INT, UNSIGNED INT, LONG, UNSIGNED LONG, SB1, UB1, SB2 ,UB2, SB4, UB4, SIZE_T  | 
                                    UNSIGNED INT  | 
                                 
FLOAT, REAL  | 
                                    FLOAT  | 
                                    FLOAT  | 
                                 
DOUBLE PRECISION  | 
                                    DOUBLE  | 
                                    DOUBLE  | 
                                 
CHAR, CHARACTER, LONG, ROWID, VARCHAR, VARCHAR2  | 
                                    STRING  | 
                                    STRING  | 
                                 
LONG RAW, RAW  | 
                                    RAW  | 
                                    RAW  | 
                                 
BFILE, BLOB, CLOB  | 
                                    OCILOBLOCATOR  | 
                                    OCILOBLOCATOR  | 
                                 
5.4.4.2 外部データ型からの変換
表5-2 外部データ型のマッピング
| 外部データ型 | IN、RETURN | 参照渡しのIN、参照渡しのRETURN | IN OUT、OUT | 
|---|---|---|---|
CHAR  | 
                                    char  | 
                                    char *  | 
                                    char *  | 
                                 
UNSIGNED CHAR  | 
                                    unsigned char  | 
                                    unsigned char *  | 
                                    unsigned char *  | 
                                 
SHORT  | 
                                    short  | 
                                    short *  | 
                                    short *  | 
                                 
UNSIGNED SHORT  | 
                                    unsigned short  | 
                                    unsigned short *  | 
                                    unsigned short *  | 
                                 
INT  | 
                                    int  | 
                                    int *  | 
                                    int *  | 
                                 
UNSIGNED INT  | 
                                    unsigned int  | 
                                    unsigned int *  | 
                                    unsigned int *  | 
                                 
LONG  | 
                                    long  | 
                                    long *  | 
                                    long *  | 
                                 
UNSIGNED LONG  | 
                                    unsigned long  | 
                                    unsigned long *  | 
                                    unsigned long *  | 
                                 
SIZE_T  | 
                                    size_t  | 
                                    size_t *  | 
                                    size_t *  | 
                                 
SB1  | 
                                    sb1  | 
                                    sb1 *  | 
                                    sb1 *  | 
                                 
UB1  | 
                                    ub1  | 
                                    ub1 *  | 
                                    ub1 *  | 
                                 
SB2  | 
                                    sb2  | 
                                    sb2 *  | 
                                    sb2 *  | 
                                 
UB2  | 
                                    ub2  | 
                                    ub2 *  | 
                                    ub2 *  | 
                                 
SB4  | 
                                    sb4  | 
                                    sb4 *  | 
                                    sb4 *  | 
                                 
UB4  | 
                                    ub4  | 
                                    ub4 *  | 
                                    ub4 *  | 
                                 
FLOAT  | 
                                    float  | 
                                    float *  | 
                                    float *  | 
                                 
DOUBLE  | 
                                    double  | 
                                    double *  | 
                                    double *  | 
                                 
STRING  | 
                                    char *  | 
                                    char *  | 
                                    char *  | 
                                 
RAW  | 
                                    unsigned char *  | 
                                    unsigned char *  | 
                                    unsigned char *  | 
                                 
OCILOBLOCATOR  | 
                                    OCILobLocator *  | 
                                    OCILobLocator *  | 
                                    OCILobLocator **  | 
                                 
5.4.5 PARAMETERS句の使用
オプションでPARAMETERS句を使用すると、PL/SQLの仮パラメータとファンクション戻り値に関する追加情報を外部プロシージャに渡すことができます。この句を使用してパラメータを再配置することもできます。 
                     
5.4.6 WITH CONTEXT句の使用
外部プロシージャは、起動時にデータベースにアクセスする必要があります。たとえば、DS_Findminは、c_findminにCLOBデータ全体をコピーしません。これを行うと、Cルーチンが必要とするスタックの量が大幅に増加するためです。かわりに、PL/SQLファンクションは、LOBロケータのみをCルーチンに渡し、実際のLOBデータを読み取るために、Cからデータベースに再度アクセスさせるようにします。 
                     
Cのルーチンは、データの読取り時に、LOBに関連付けられているOCIのバッファリングおよびストリーム化インタフェースを使用できるため、スタック量は必要に応じて段階的に増えるのみです。このように外部プロシージャからデータベースに再アクセスすることをコールバックと呼びます。
データベースへのコールバックを可能にするには、WITH CONTEXT句を使用して、データベース環境、サービスおよびエラー・ハンドルへのアクセスを外部プロシージャに付与する必要があります。WITH CONTEXTを使用して外部プロシージャをコールすると、対応するCのルーチンは自動的に最初のパラメータとしてOCIExtProcContext*型の引数を取得します。パラメータの順序はPARAMETERS句を使用して変更できます。このコンテキスト・ポインタを使用し、OCIExtProcGetEnvコールを使用してハンドルをフェッチし、データベースをコールバックできます。このプロシージャについては、例5-7を参照してください。
                     
関連項目:
OCIコールバックの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。
5.5 コールバックの使用
Oracleサーバー上で実行される外部プロシージャは、アクセス・ファンクションOCIExtProcGetEnv()をコールしてOCI環境およびサービス・ハンドルを取得できます。OCIでは、コールバックを使用してSQL文とPL/SQLサブプログラムを実行し、データをフェッチしてLOBを操作できます。さらに、コールバックと外部プロシージャは同じユーザー・セッションおよびトランザクション・コンテキストで動作するため、両者のユーザー権限も同じです。
                  
例5-7に、コールバックを示すために簡略化されたc_findminのバージョンを示します。
                  
例5-7 コールバックの使用
Static  OCIEnv   *envhp;
Static  OCISvcCtx  *svchp;
Static OCIError   *errhp;
Int   c_findmin (OCIExtProcContext *ctx, OCILobLocator  *lobl) {
sword  retval;
retval = OCIExtProcGetEnv (ctx, &envhp, &svchp, &errhp);
if ((retval != OCI_SUCCESS) && (retval !=  OCI_SUCCESS_WITH_INFO))
   exit(-1);
   /* Use lobl to read the CLOB, compute the minimum, and store the value
       in retval. */
return retval;
}5.5.1 コールバックの制限事項
コールバックを使用する場合、次のSQL文とOCIルーチンはサポートされません。
- 
                              
COMMITなどのトランザクション制御文 - 
                              
CREATEなどのデータ定義文 - 
                              
オブジェクト指向のOCIルーチン(
OCIRefClearなど) - 
                              
ポーリング・モードのOCIルーチン(
OCIGetPieceInfoなど) - 
                              
OCIルーチンは次のとおりです。
- 
                                    
OCIEnvInit() - 
                                    
OCIInitialize() - 
                                    
OCIPasswordChange() - 
                                    
OCIServerAttach() - 
                                    
OCIServerDetach() - 
                                    
OCISessionBegin () - 
                                    
OCISessionEnd () - 
                                    
OCISvcCtxToLda() - 
                                    
OCITransCommit() - 
                                    
OCITransDetach() - 
                                    
OCITransRollback() - 
                                    
OCITransStart() 
 - 
                                    
 - 
                              
また、OCIルーチン
OCIHandleAlloc()では、次のハンドル・タイプはサポートされません。- 
                                    
OCI_HTYPE_SERVER - 
                                    
OCI_HTYPE_SESSION - 
                                    
OCI_HTYPE_SVCCTX - 
                                    
OCI_HTYPE_TRANS 
 - 
                                    
 
5.6 共通の潜在的エラー
外部プロシージャの実行時に発生する可能性のあるいくつかの一般的なエラーについて考えます。
5.6.1 外部ファンクションのコール
DLLファイルのパスまたは名前を正しく指定していないか、またはネットワーク・マウント・ドライブ(リモート・ドライブ)でDLLを使用した可能性があります。
Can't Find DLL ORA-06520: PL/SQL: Error loading external library ORA-06522: Unable to load DLL ORA-06512: at "<name>", line <number> ORA-06512: at "<name>", line <number> ORA-06512: at line <number>
5.7 外部プロシージャのデバッグ
通常、外部プロシージャが失敗する場合は、Cプロトタイプに問題があります。つまり、プロトタイプがPL/SQLによって内部で生成されるプロトタイプと一致していません。これは、互換性のないCデータ型を指定した場合に発生する可能性があります。たとえば、型がREALのOUTパラメータを渡すためにfloat *を指定したとします。float、double *または他のCデータ型を指定すると、結果が不一致になります。 
                  
このような場合は、「外部プロシージャ・エージェントへのRPC接続が失われました。」エラーが発生する可能性があります。これは、外部プロシージャでコア・ダンプが発生したため、エージェントextprocが異常終了したことを意味します。Cプロトタイプ・パラメータ宣言時のエラーを回避するには、表5-2を参照してください。
                  
5.7.1 パッケージDEBUG_EXTPROCの使用
PL/SQLでは、外部プロシージャのデバッグを支援する目的でユーティリティ・パッケージDEBUG_EXTPROCが提供されています。このパッケージをインストールするには、PL/SQLデモ・ディレクトリにあるスクリプトdbgextp.sqlを実行します。
                     
このパッケージを使用するには、dbgextp.sql内の指示に従います。Oracleアカウントには、パッケージに対するEXECUTE権限とCREATE LIBRARY権限が必要です。
                     
DEBUG_EXTPROCが動作するのは、実行中のプロセスに添付できるデバッガ・ユーティリティのあるプラットフォームのみであることに注意してください。
                     
5.8 データ・カートリッジで外部プロシージャを使用するためのガイドライン
必ずスレッド・セーフな外部プロシージャを記述してください。特に、個別スレッドで実行中のルーチンにより共有される可能性があるため、静的変数は使用しないでください。
動的リンク・ライブラリ作成のヘルプは、RDBMSサブディレクトリ/publicにあります。このサブディレクトリにはテンプレートmakefileファイルがあります。 
                  
外部プロシージャのコール時には、INパラメータに書き込んだりOUTパラメータの容量をオーバーフローしないでください。PL/SQLでは、このようなエラー条件のランタイム・チェックは実行されません。同様に、OUTパラメータやファンクションの結果は読み取らないでください。また、値は必ずIN OUTおよびOUTパラメータとファンクションの結果に割り当てます。それ以外の場合、外部プロシージャで正常に値が戻されません。
                  
WITH CONTEXTおよびPARAMETERS句を挿入する場合は、パラメータ・リスト内でコンテキスト・ポインタの位置を示すCONTEXTパラメータを指定する必要があります。PARAMETERS句を省略すると、コンテキスト・ポインタは外部プロシージャに渡される最初のパラメータになります。 
                  
PARAMETERS句を挿入する場合に、外部プロシージャがファンクションであれば、最後の位置に(RETURNプロパティではなく)RETURNパラメータを指定する必要があります。
                  
各仮パラメータには、PARAMETERS句に対応するパラメータが必要です。また、PARAMETERS句のパラメータのデータ型が、Cプロトタイプのデータ型と互換性があることも確認します。これは、暗黙的変換が実行されないためです。 
                  
INDICATORまたはLENGTHを指定するパラメータのパラメータ・モードは、対応する仮パラメータと同じです。ただし、MAXLEN、CHARSETIDまたはCHARSETFORMを指定するパラメータは、BY REFERENCEをともに指定した場合も、常にINパラメータと同様に処理されます。
                  
CHAR、LONG RAW、RAWまたはVARCHAR2型のパラメータには、プロパティLENGTHを使用する必要があります。また、そのパラメータがIN OUTまたはOUTでNULLの場合は、対応するCのパラメータの長さを0(ゼロ)に設定する必要があります。
                  
関連項目:
マルチスレッディングの詳細は、『Oracle Database Heterogeneous Connectivity管理者ガイド』を参照してください。
5.9 Javaのメソッド
Javaデータ・カートリッジを利用するには、Javaクラス定義のロード方法、ストアド・プロシージャのコール方法およびコンテキスト管理の知識があることが重要です。
関連項目:
ODCIクラスについては、「C、C++およびJavaを使用したカートリッジ・サービス」を参照してください。
