プライマリ・コンテンツに移動
Pro*C/C++プログラマーズ・ガイド
12c リリース1(12.1)
B71397-03
目次へ移動
目次
索引へ移動
索引

前
次

外部プロシージャ

PL/SQLでは、外部プロシージャのC言語関数をコールできます。外部プロシージャは、Dynamic Link Library(DLL)またはSolarisの.soライブラリなどに格納されています。

外部プロシージャをサーバーで実行する場合、同一トランザクション中でSQLおよびPL/SQLが実行されるようにサーバーにコールバックできます。サーバーで外部プロシージャを実行すると、クライアントで実行した場合よりも処理速度が速く、外部システムおよびデータ・ソースと、データベース・サーバーとのインタフェースとして使用できます。

サーバー側の外部C言語関数を実行する場合は、関数内でREGISTER CONNECT埋込みSQL文を使用する必要があります。文の構文は次のとおりです。

EXEC SQL REGISTER CONNECT USING :epctx [RETURNING :host_context] ;

epctxは、OCIExtProcContextへのタイプ・ポインタの外部プロシージャ・コンテキストです。epctxはPL/SQLによってプロシージャに渡されます。

host_contextは、外部プロシージャによって戻されるランタイム・コンテキストです。現在の設定は、デフォルト(グローバル)・コンテキストです。

REGISTER CONNECT文により、カレントのOracle接続およびトランザクションに対応付けられたOCIハンドル・セット(OCIEnv、OCISvcCtxおよびOCIError)が戻されます。これらのハンドルは、グローバルSQLLIBランタイム・コンテキストのPro*C/C++デフォルトである名前なし接続の定義に使用されます。このため、REGISTER CONNECTが、CONNECT文のかわりに使用されます。

後続の埋込みSQL文では、このOCIハンドル・セットを使用します。後続の埋込みSQL文は、グローバルSQLLIBランタイム・コンテキスト、名前なし接続に対して実行されます。これは、別々にプリコンパイルされたプログラム・ユニットにある場合でも同様です。コミットされていない変更は無効です。今後のバージョンでは、(非デフォルトの)ランタイム・コンテキストはオプションのRETURNING句で返されるようになります。

グローバル・ランタイム・コンテキストのアクティブなデフォルト接続はまだありません。すでに接続が確立しているときにREGISTER CONNECTを使用すると、ランタイム・エラーが戻されます。

関連項目:

OCI関数の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。

実際の業務では、外部プロシージャは複数の異なるアプリケーションから再利用できるようにすることをお薦めします。

外部プロシージャの制限

外部プロシージャには次の規則があります。

  • 外部プロシージャを使用できるのはCのみです。C++外部プロシージャはサポートされていません。

  • 外部プロシージャ・コンテキストに接続した場合、接続を追加できません。ランタイム・エラーが発生します。

  • マルチスレッドの外部プロシージャはサポートされていません。EXEC SQL ENABLE THREADS文は使用できません。ランタイム・エラーが発生します。Pro*C/C++では、ここで説明している外部プロシージャを使用しない場合は、アプリケーションでのマルチスレッドがサポートされます。

  • DDL文を使用できません。ランタイム・エラーが発生します。

  • EXEC SQL COMMITおよびEXEC SQL ROLLBACKなどのトランザクション制御文を使用できません。

  • EXEC SQL OBJECTなどのオブジェクト・ナビゲーション文を使用できません。

  • EXEC SQL LOB文のポーリングを行うことはできません。

  • EXEC TOOLS文を使用できません。ランタイム・エラーが発生します。

外部プロシージャの作成について

外部プロシージャextp1を作成する場合の簡単な例を示します。

外部Cプロシージャを格納するには、コードのコンパイルおよびリンクを行い、DLLなどのライブラリに格納します。

NT削除済ユーザー・コメント9561への参照

次のSQLコマンドを1回実行して、外部プロシージャextp1を登録します。

CREATE OR REPLACE PROCEDURE extp1
AS EXTERNAL NAME "extp1"
LIBRARY mylib
WITH CONTEXT
PARAMETERS(CONTEXT) ;

mylibは、プロシージャextp1が格納されるライブラリです。WITH CONTEXTが指定されているため、このプロシージャは、引数型OCIExtProcContext*で暗黙的にコールされます。このコールでは、コンテキストが省略されていますが、プロシージャには渡されます。ただし、CREATE文のCONTEXTキーワードは、プレース・マーカーとして指定されています。

このコンテキスト・パラメータは、extp1の内側のEXEC SQL REGISTER CONNECT文で参照されます。

外部プロシージャのコール方法の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

外部プロシージャは、SQL*Plusから次のようにコールされます。

SQL>
BEGIN
  INSERT INTO emp VALUES(9999,'JOHNSON','SALESMAN',7782, sysdate, 1200,150,10);
  extp1;
END;

extp1.pcのリストです。

void extp1 (epctx)
OCIExtProcContext *epctx;
{
char name[15];
        EXEC SQL REGISTER CONNECT USING :epctx;
        EXEC SQL WHENEVER SQLERROR goto err;
        EXEC SQL SELECT ename INTO :name FROM emp WHERE empno = 9999;
        return;
err: SQLExtProcError(SQL_SINGLE_RCTX,sqlca.sqlerrm.sqlerrmc,sqlca.sqlerrm.sqlerrml);
        return;
}

SQLExtProcError()

SQLLIB関数SQLExtProcError()を使用すると、外部Cプロシージャでエラーが発生した場合にPL/SQLに制御を戻すことができます。関数とその引数は次のとおりです。

SQLExtProcError (ctx, msg, msglen)

説明:

ctx (IN) sql_context *

この関数は、REGISTER CONNECT文のターゲットSQLLIBランタイム・コンテキストです。REGISTER CONNECT文は、この関数が起動される前に実行する必要があります。現在、グローバル・ランタイム・コンテキストのみがサポートされています。

msg (OUT) char *

エラー・メッセージのテキスト

msglen (OUT) size_t

メッセージのバイト単位の長さ

この関数が実行されると、SQLLIBによりOCIサービス関数OCIExtProcRaiseExcpWithMsgがコールされます。

メッセージは、SQLCAの構造体sqlerrmから出力されます。SQLCAの構造およびsqlerrmの説明は、SQLCAの構造体を参照してください。

SQLExtProcError()の使用方法の例です。

void extp1 (epctx)
OCIExtProcContext *epctx;
{
   char name[15];
   EXEC SQL REGISTER CONNECT USING :epctx;
   EXEC SQL WHENEVER SQLERROR goto err;
   EXEC SQL SELECT ename INTO :name FROM emp WHERE smpno = 9999;
   return;
 err:
   SQLExtProcError (SQL_SINGLE_RCTX, sqlca.sqlerrm.sqlerrmc,
      sqlca.sqlerrm.sqlerrml);
   printf("\n%*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
   return;
}