Oracle Applications開発者ガイド リリース12 E06048-01 | 目次 | 前へ | 次へ |
この項では、CまたはPro*Cでのコンカレント・プログラムのコーディングについて説明します。また、使用方法の例とともに使用できるユーティリティについても説明しています。
CまたはPro*Cを使用するプログラムのコーディングには、コンカレント処理の汎用APIテンプレートEXMAIN.cおよびEXPROG.cを使用します。これらのテンプレートがオペレーティング・システム内のどこに格納されているかについては、『Oracle Applicationsシステム管理者ガイド』を参照してください。
テンプレートEXMAIN.cおよびEXPROG.cを使用すると、システムがプログラムにあわせて適切に初期化されます。これらのテンプレートを使用して作成したコンカレント・プログラム実行ファイルは、起動実行方法または即時実行方法のいずれにも使用できます。
カスタム・プログラムをコーディングするには、ファイルを自分のディレクトリにコピーし、それらに修正を加える前に、まず別の名前で保存しておきます。オリジナルのテンプレートは修正しないことをお薦めします。
EXMAIN.cは初期化を実行するメイン・プログラムで、afprcp()ファンクションを利用してサブルーチンをコールします。EXPROG.cはユーザーのアプリケーション・コードを含むサブルーチンです。
両ファイル内に出現するSUBROUTINE_NAMEをすべて、実際のサブルーチン名に置き換えます。サブルーチンの最後でafpend()をコールし、クリーン・アップしてコンカレント・プログラムから戻るようにする必要があります。ユーティリティafpend()によりデータベース接続が切断され、Application Object Libraryのメモリーが解放されて、Application Object Libraryファイルが終了し、指定したステータス・コードが返されます。ここで返すステータス・コードは次の3つから指定できます。
FDP_SUCCESS
FDP_ERROR
FDP_WARNING
また、インクルード・コードにビット・マクロの定義を次のようにインクルードします。
#define bit(a,b) ((a)&(b))
次に示すのは、EXMAINおよびEXPROGの例です。
EXMAIN.c
/*==================================================+
| Example MAIN for concurrent programs |
| File is in $FND_TOP/usrxit/EXMAIN.c |
+==================================================*/
/*--------------------------------------------------+
| Copy this file to make a main for your |
| concurrent program. Replace SUBROUTINE_NAME |
| everywhere (2 places) with the actual name of |
| your concurrent program subroutine. (This is |
| the same subroutine name you register with |
| Application Object Library.) |
| |
| Do not add or modify any other statements in |
| this file. |
+--------------------------------------------------*/
#ifndef AFPUB
#include <afpub.h>
#endif
#ifndef AFCP
#include <afcp.h>
#endif
AFP_FUNCS SUBROUTINE_NAME;
int main(argc, argv)
int argc;
char *argv[];
{
afsqlopt options;
return(afprcp(argc, argv, (afsqlopt *)NULL,
(afpfcn *)SUBROUTINE_NAME));
}
EXPROG.c
/*==================================================+
| Example SUBROUTINE for concurrent programs |
| File is in $FND_TOP/usrxit/EXPROG.c |
+==================================================*/
/*--------------------------------------------------+
| Copy this file to write a subroutine for your |
| concurrent program. Replace SUBROUTINE_NAME |
| with the actual name of your concurrent program |
| (This is the same subroutine name you register |
| with Application Object Library.) |
| |
| Remember to register your subroutine and |
| concurrent program with Application Object |
| Library and to add it to a library if you wish |
| it to be run as an immediate program. |
| |
| Add your code where indicated. |
| |
| Call afpend() to exit your subroutine. |
+--------------------------------------------------*/
#ifndef AFPUB
#include <afpub.h>
#endif
#ifndef AFCP
#include <afcp.h>
#endif
/*--------------------------------------------------+
| Add other include files you need here. |
| |
| You will need fddmsg.h if you use Message |
| Dictionary. |
+--------------------------------------------------*/
boolean SUBROUTINE_NAME(argc, argv, reqinfo)
int argc;
text *argv[];
dvoid *reqinfo;
{
/*
* This is the beginning of an example program.
* If you copied this source to create your program, delete the lines below.
*/
int i;
text buffer[241];
fdpwrt(AFWRT_LOG | AFWRT_NEWLINE, "Hello World.");
fdpwrt(AFWRT_LOG | AFWRT_NEWLINE, "Hello World.");
fdpwrt(AFWRT_OUT | AFWRT_NEWLINE, "This is a test! Take one.");
fdpwrt(AFWRT_OUT | AFWRT_NEWLINE, "This is a test! Take two.");
fdpwrt(AFWRT_OUT | AFWRT_NEWLINE,
"-------------------------");
for ( i = 0; i < argc; i++ )
{
sprintf(buffer, "argv[%d]: %s", i, argv[i]);
fdpwrt(AFWRT_OUT | AFWRT_NEWLINE, buffer);
}
/*
* This is the end of an example program.
* If you copied this source to create your program,
* delete the lines above.
*/
/*--------------------------------------------------+
| Add your code here |
+--------------------------------------------------*/
/*--------------------------------------------------+
| Finished |
| |
| Always call afpend() to clean up before |
| returning from your subroutine. |
| |
| return(afpend(status, reqinfo, message)); |
| |
| status is FDP_SUCCESS |
| FDP_ERROR |
| FDP_WARNING |
| |
| message is a completion message displayed on |
| the View Requests screen when your concurrent |
| program/request completes. Possible values are |
| "" for successful completion |
| "text" for text |
| buffer for text stored in a buffer |
| afdget() for a message stored in Message |
| Dictionary |
+--------------------------------------------------*/
return(afpend(FDP_SUCCESS, reqinfo, ""));
/* For successful completion */
}
Pro*Cコンカレント・プログラムを記述する際には、標準の引数引渡し方法を使用します。この方法は、コンカレント処理の汎用APIから提供されるもので、プログラムに渡されるパラメータを取得し、それをarvg[]にロードして、argcを設定し、データベースにログオンして、ユーザー・プロファイル・オプション値をロードします。
プログラムを標準要求発行から使用できるようにするには、最初のパラメータをargv[1]で定義します。argv[0]ではパラメータは定義しません。
プログラムが完了した後、Oracle Application Object Libraryマクロafpend()を使用してプログラムを終了し、コンカレント要求のステータスを変更する必要があります。
マクロafpend()によってデータベースからプロセスがログオフされ、プログラムが正常に終了したかどうかがコンカレント・マネージャに示され、コンカレント要求のログ・ファイルに完了メッセージが書き込まれます。マクロは括弧で囲む必要があることに注意してください。プログラムが正常に終了した場合、最後の文は次のようになります。
return(afpend(FDP_SUCCESS, reqinfo, ""));
ユーザーが「要求」フォームでこのコンカレント要求を参照する際、コンカレント・マネージャでは、このマクロを使用して「完了/標準」のフェーズ/ステータスを表示します。プログラムの終了にafpend()ではなくexit()を使用する場合は、コンカレント・マネージャはその要求を「完了/エラー」としてマークします。
プログラムでエラーが発生した際に独自のエラー・メッセージ・テキストを表示するには、最後の文を次のようにします。
return(afpend(FDP_ERROR, reqinfo, "error_message"));
「要求」フォームには「完了/エラー」のフェーズ/ステータスが表示されます。
プログラムは正常に終了したものの、注意を要する例外が検出された場合には、その状況を示すために「警告」ステータスを返すことができます。「要求」フォームでの要求の最終的なフェーズ/ステータスは「完了/警告」です。最後の文は次のようになります。
return(afpend(FDP_WARNING, reqinfo, "error_message"));
プログラムでエラーが発生した際にメッセージ・ディクショナリからのエラー・メッセージを表示するには、最後の文を次のようにします。
afdname(application_short_name, message_name);
return(afpend(FDP_FAILURE, reqinfo, afdget()));
Cルーチンafdget()およびafdname()に提供されているOracle Application Object Libraryを使用して、メッセージ・ディクショナリから必要なメッセージを取得します。
このメッセージはコンカレント・マネージャによって、「要求」フォームの「要求の詳細」ウィンドウ内にある「完了テキスト」フィールドに表示されます。
関連項目: メッセージ・ディクショナリの実装
『Oracle Applications概要』に記載されている、オペレーティング・システムに適切なファイル命名規則を使用します。オペレーティング・システムが大文字・小文字を区別する場合は、ファイル名は大文字する必要があります。オペレーティング・システムによっては、ファイル名に拡張子を必要とするものもあります。また、実行ファイル名はEXMAIN.cプログラムのコピーのコンパイル・ファイル名と一致している必要があります。
後でOracle Application Object Libraryで起動コンカレント・プログラムの実行ファイルを定義する際は、プログラムの実行ファイル名をユーザーのファイル名の拡張子を除いたものと同じ名前に定義します。たとえば、Unixでの実行ファイルがAPPOSTという名前である場合は、コンカレント・プログラムの実行ファイルの実行ファイル・フィールドをAPPOSTと定義する必要があります。
コンカレント・プログラムは、コンカレト・マネージャを通さずにオペレーティング・システムから直接実行できます。引数をプログラムに渡してデフォルトのユーザー・プロファイル・オプションを使用する場合に、この方法を行います。
構文
PROGRAM user/pwd 0 Y [parameter1] parameter2] ...
変数 | 説明 |
---|---|
PROGRAM | プログラムを含んでいる実行ファイルの名前。これは「コンカレント・プログラム実行ファイルの定義」フォームの「実行ファイル」フィールドに入力した名前です。 |
user/pwd | プログラムで使用するデータに接続するための、ORACLEユーザー名およびパスワード。または、システム管理者の職責を持つOracle Applicationsユーザー名およびパスワード。 |
parameter1, 2 ... | プログラム固有のパラメータ。パラメータに空白または二重引用符が含まれている場合は、特別な構文を使用する必要があります。使用中のオペレーティング・システム用の構文については、『Oracle Applicationsシステム管理者ガイド』を参照してください。たとえば、Unixの場合、"This is an example of a \" (double quote)"を使用して文字列を渡すことができます。 |
コンカレント・プログラム内のすべてのファイルをコンパイルした後、個別のオブジェクト・ファイルとして残しておくか、オブジェクト・ライブラリに配置できます。オブジェクト・ファイルまたはオブジェクト・ライブラリは、ユーザーのアプリケーションのトップ・ディレクトリの下にあるlibディレクトリに配置できます。実行ファイルは、そのアプリケーションのトップ・ディレクトリの下にあるbinディレクトリに配置できます。
Oracle Application Object Libraryでは次のCプログラム・ヘッダー・ファイル・システムが使用されています。C言語で記述されているあらゆるユーザー・イグジットとともに、起動Cプログラムおよび即時Cプログラムは、次のヘッダー規則に従う必要があります。
次の表には、C APIで使用されるヘッダー・ファイルがリストされています。
ヘッダー・ファイル | コメント |
---|---|
afpub.h | Oracle Application Object Library APIのプライマリ・ヘッダー・ファイル。Oracle Application Object LibraryルーチンにアクセスするすべてのCプログラムにインクルードします。 |
afcp.h | コンカレント処理のために提供されたC APIを使用するコンカレント・プログラムで使用されるヘッダー・ファイル。コンカレント処理で使用されるすべてのPro*Cプログラムが、このヘッダー・ファイルをインクルードしている必要があります。 |
afuxit.h | ユーザー・イグジットで使用されるC APIで使用されるヘッダー。すべてのPro*Cユーザー・イグジットが、このヘッダー・ファイルをインクルードしている必要があります。 |
afufld.h | フィールド値の読取り/書込み関数を含むヘッダー・ファイル。このヘッダー・ファイルは<afuxit.h>で使用します。すべてのPro*Cユーザー・イグジットが、このヘッダー・ファイルをインクルードしている必要があります。 |
fddutl.h | メッセージ・ディクショナリ・コードで使用されるヘッダー・ファイル。メッセージ・ディクショナリ機能にアクセスするすべてのPro*Cプログラムがこのヘッダーをインクルードしている必要があります。 |
fdpopt.h | プロファイル・オプションへのアクセスに使用されるヘッダー・ファイル。プロファイル・オプションにアクセスするすべてのPro*Cプログラムかこのヘッターをインクルードしている必要かあります。 |
他のヘッダー・ファイルをコールするカスタムAPIがある場合は、必ず適切なヘッダーを使用するようにします。
この項では、コンカレント・プログラムで使用するCルーチンについて説明します。これらのルーチンのうちいくつかのルーチンはオプションで、いくつかのものは必須です。これは作成するコンカレント・プログラムのタイプによって異なります。また、この項にはPro*Cコンカレント・プログラムの例も記載されています。
重要: ユーザー・イグジットからfdpscr()、fdpwrt()またはその他のコンカレント・マネージャ関数をコールしないでください。インタフェースとしてサポートされているのは、フォームからコーディング可能なPL/SQLストアド・プロシージャAPIを経由する要求発行のみです。
ユーザー・プロファイルCオプションafpoget()およびafpoput()の詳細は、「ユーザー・プロファイル」の章を参照してください。関連項目: ユーザー・プロファイルの概要
#include <afcp.h>
return(afpend(status, reqinfo, message));
コンカレント処理の汎用APIテンプレートで書かれているサブルーチンの最後で、関数afpend()をコールします。afpendは、クリーン・アップして、ステータス・コードおよび完了メッセージを表示し、コンカレント・プログラムから戻るための関数です。これにより、データベースが切断され、Application Object Libraryのメモリーが解放されて、Application Object Libraryファイルが閉じ、指定したステータス・コードが返されます。
この関数が正常に終了すると、TRUEが戻されます。エラーが発生した場合はFALSEが戻されます。
status - 戻されるステータス・コード。有効なステータス・コードはFDP_SUCCESS、FDP_WARNINGおよびFDP_ERRORです。
reqinfoメッセージ - コンカレント要求の完了時に「要求の表示」画面に表示される完了メッセージ。使用可能なメッセージ値は次のとおりです。
"" - コンテンツなし。正常に完了。
"テキスト" - テキスト。
バッファ - バッファに格納されたテキスト。
afdget() - メッセージ・ディクショナリに格納されたメッセージ。
/* use afpend to return messages with a success code */
char errbuf[241];
if (!submit())
{
/* return failure with a message */
return(afpend(FDP_ERROR, reqinfo,
"Failed in submit()"));
}
else if (!setprofiles())
{
/* return warning with a message */
return(afpend(FDP_WARNING, reqinfo,
"Failed in setprofiles()"));
}
else if (!subrequest(argc, argv, reqinfo, errbuf))
{
/* return failure with a message */
return(afpend(FDP_ERROR, reqinfo, errbuf));
}
else
{
/* Successful completion. */
return(afpend(FDP_SUCCESS, reqinfo, ""));
}
afreqstate fdpfrs (request_id, errbuf);
text request_id;
text errbuf;
fdpfrs()コマンドは特定の要求IDのステータスを返します。このコマンドは戻りステータス・マクロORAF_REQUEST_XXXとともに使用します。
この関数は引数として渡された要求IDのステータスを戻します。
request_id - 問合せ対象の要求IDを含むNULL終端文字。
errbuf - errbuf fdpfrs()が失敗した場合にfdpfrs()によって戻される、エラー・メッセージを含む文字列。effbufのサイズを241として宣言する必要かあります。
#ifndef AFPUB
#include <afpub.h>
#endif
#ifndef AFCP
#include <afcp.h>
#endif
boolean check_request_status(request_id, errbuf)
text* request_id;
text* errbuf;
{
afreqstate request_status;
request_status = fdpfrs(request_id, errbuf);
If (ORAF_REQUEST_TEST_FAILURE(request_status) ||
ORAF_REQUEST_NOT_FOUND(request_status))
return FALSE;
if (ORAF_REQUEST_COMPLETE(request_status) &&
(ORAF_REQUEST_NORMAL(request_status))
return TRUE;
return FALSE;
}
#include <afcp.h>
boolean fdpscp( argc_ptr, argv_ptr, args_method, errbuf)
int *argc_ptr;
char **argv_ptr[];
text args_method;
text *errbuf;
この関数は以前のバージョンのOracle Application Object Libraryで作成されたコンカレント・プログラムとの互換性のために存在しています。コンカレント・プログラムを新しく作成した場合は、コンカレント処理の汎用APIを使用してください。
関数fdpscp()は、起動Pro*Cコンカレント・プログラムの最初の文でコールされます。この関数によってプログラムが必要とするパラメータが取得され、そのパラメータがargv[]配列にロードされて、実行日時を含む標準ヘッダーがログ・ファイルへ出力されます。また、これによってプログラムがデータベースにログオンします。この関数が、コンカレント・プログラムが定義されているアプリケーションに割り当てられたORACLE IDを使用して、プログラムをデータベースに接続します。
コンカレント要求がコールされているパラメータがすべて正常に取得されると、この関数がTRUEを戻します。正常に取得されなかった場合は、FALSEが戻されます。この関数がFALSEを戻した場合、コンカレント・プログラムはerrbufの内容を出力し、エラー状態で終了します。
argc_ptr - main()への最初の引数であるargcへのポインタ。fdpscp()のコールには&argcを使用する必要があります。
argv_ptr - main()への2番目の引数であるargvへのポインタ。fdpscp()のコールには&argvを使用する必要があります。
args_method - このパラメータは現在使用されていません。(text)'\0'へ初期化する必要があります。
errbuf - fdpscp()がFALSEを戻した場合、fdpscp()から戻される、エラー・メッセージを含む文字列。errbuf[]のサイズを241として宣言する必要があります。
#include <afcp.h>
/* This is an example of a Pro*C concurrent program. This
sample program prints its input parameter to the
log file. */
routine()
{
text args_method = (text)'\0';
text errbuf[241];
if (!fdpscp( &argc, &argv, args_method, errbuf ) ){
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE,
"Error calling fdpscp" );
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE, errbuf );
return(afpend(FDP_ERROR, reqinfo, "Failed to get
arguments"));
}
if (!fdpwrt(AFWRT_LOG | AFWRT_NEWLINE, argv[1] )) {
return(afpend(FDP_ERROR, reqinfo, "Failed to write
arguments"));
}
{return(afpend(FDP_SUCCESS, reqinfo, ""));}
}
#include <afcp.h>
boolean fdpscr( command, request_id, errbuf )
text *command;
text *request_id;
text *errbuf;
fdpscr()関数により、コンカレント・プログラムを実行するための要求か発行されます。この関数はPro*Cコンカレント・プログラムからのみコールできます。子要求のユーザー・プロファイル・オプションは、親コンカレント・プログラムの要求をデフォルトとして使用します。要求がコンカレント・マネージャにより実行可能になるように、この関数をコールした後にコミットする必要があります。コミットせずにロールバックすると、要求は失われます。
コンカレント要求が正常に発行されると、fdpscr()からTRUEが戻されます。正常に発行されなかった場合はFALSEが戻されます。
command - 先頭にCONCURRENTが付いた、コンカレント・プログラムへのパラメータを含む文字列。フォームからコンカレント・プログラムをコールするときに使用するコマンドと同しコマンドを、#FNDを除いて使用する必要があります。
request_id - fdpscr()により戻される、コンカレント要求に割り当てられた要求IDを含む文字列。request_id[]のサイズを12として宣言する必要があります。
errbuf - fdpscr()がFALSEを戻した場合、fdpscr()から戻される、エラー・メッセージを含む文字列。errbuf[]のサイズを214として宣言する必要があります。
/* Submit request */
if (!fdpscr( command, request_id, errbuf))
{
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE,
"Failed to submit concurrent request");
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE, errbuf);
return(FALSE);
}
else /* Successful completion */
{
sprintf(errbuf, "Concurrent request %s submitted
successfully", request_id);
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE, errbuf);
return(TRUE);
}
#include fdpwrt.h
boolean fdpwrt( flag, message)
fdcoflgs flags
text *message;
fdpwrt()関数によって標準ログ・ファイルまたは標準レポート出力ファイルにテキスト文字列が書き込まれます。ファイルを明示的にオープンしてクローズする必要はありません。Oracle Application Object Libraryでは、ログ・ファイルまたはレポート出力ファイルの名前を、『Oracle Applications概要』で説明されている標準命名規則に従って命名します。
指定したファイルにメッセージを書き込めない場合は、関数fdpwrt()からFALSEが返されます。それ以外は、TRUEが返されます。
フラグ - 書込み先のファイルを指定するために使用するマクロ。
AFWRT_LOGはログ・ファイルへの書込みを指定する場合に使用します。AFWRT_OUTはレポート出力ファイルへの書込みのためのものてす。
バッファをフラッシュするか、改行文字を追加するかのオプションを選ぶことかできます。オプションをオンにするには「|」(ビット単位のOR)を、オフにするには「&~」(ビット単位のAND NOT)を使用します。
AFWRT_FLUSHでは、各コール後にバッファがファイルに自動的にフラッシュされます。デフォルトでは、AFWRT_FLUSHはログ・ファイル用にはオンに、レポート出力用にはオフに設定されています。AFWRT_NEWLINEでは、バッファのフラッシュ前にバッファ内の文字列の終端に改行文字(\n)が追加されます。デフォルトでは、AFWRT_NEWLINEはオフになっています。
メッセージ - NULL終端文字列。
/* Submit request */
if (!fdpscr( command, request_id, errbuf))
{
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE,
"Failed to submit concurrent request");
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE, errbuf);
return(FALSE);
}
else /* Successful completion */
{
sprintf(errbuf, "Concurrent request %s submitted
successfully", request_id);
fdpwrt( AFWRT_LOG | AFWRT_NEWLINE, errbuf);
return(TRUE);
}