ヘッダーをスキップ

Oracle Applications開発者ガイド
リリース12
E06048-01
目次へ
目次
前のページへ
前へ
次のページへ
次へ

CおよびPro*Cコンカレント・プログラムのコーディング

CおよびPro*Cコンカレント・プログラムのコーディング

この項では、CまたはPro*Cでのコンカレント・プログラムのコーディングについて説明します。また、使用方法の例とともに使用できるユーティリティについても説明しています。

Pro*Cコンカレント・プログラム

CまたはPro*Cを使用するプログラムのコーディングには、コンカレント処理の汎用APIテンプレートEXMAIN.cおよびEXPROG.cを使用します。これらのテンプレートがオペレーティング・システム内のどこに格納されているかについては、『Oracle Applicationsシステム管理者ガイド』を参照してください。

コンカレント処理の汎用API afprcp()

テンプレートEXMAIN.cおよびEXPROG.cを使用すると、システムがプログラムにあわせて適切に初期化されます。これらのテンプレートを使用して作成したコンカレント・プログラム実行ファイルは、起動実行方法または即時実行方法のいずれにも使用できます。

カスタム・プログラムをコーディングするには、ファイルを自分のディレクトリにコピーし、それらに修正を加える前に、まず別の名前で保存しておきます。オリジナルのテンプレートは修正しないことをお薦めします。

EXMAIN.cは初期化を実行するメイン・プログラムで、afprcp()ファンクションを利用してサブルーチンをコールします。EXPROG.cはユーザーのアプリケーション・コードを含むサブルーチンです。

両ファイル内に出現するSUBROUTINE_NAMEをすべて、実際のサブルーチン名に置き換えます。サブルーチンの最後でafpend()をコールし、クリーン・アップしてコンカレント・プログラムから戻るようにする必要があります。ユーティリティafpend()によりデータベース接続が切断され、Application Object Libraryのメモリーが解放されて、Application Object Libraryファイルが終了し、指定したステータス・コードが返されます。ここで返すステータス・コードは次の3つから指定できます。

また、インクルード・コードにビット・マクロの定義を次のようにインクルードします。

#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]ではパラメータは定義しません。

Pro*Cプログラムからの戻り

プログラムが完了した後、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と定義する必要があります。

Pro*Cプログラムのテスト

コンカレント・プログラムは、コンカレト・マネージャを通さずにオペレーティング・システムから直接実行できます。引数をプログラムに渡してデフォルトのユーザー・プロファイル・オプションを使用する場合に、この方法を行います。

構文

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がある場合は、必ず適切なヘッダーを使用するようにします。

コンカレント処理Pro*Cユーティリティ・ルーチン

この項では、コンカレント・プログラムで使用するCルーチンについて説明します。これらのルーチンのうちいくつかのルーチンはオプションで、いくつかのものは必須です。これは作成するコンカレント・プログラムのタイプによって異なります。また、この項にはPro*Cコンカレント・プログラムの例も記載されています。

重要: ユーザー・イグジットからfdpscr()fdpwrt()またはその他のコンカレント・マネージャ関数をコールしないでください。インタフェースとしてサポートされているのは、フォームからコーディング可能なPL/SQLストアド・プロシージャAPIを経由する要求発行のみです。

ユーザー・プロファイルCオプションafpoget()およびafpoput()の詳細は、「ユーザー・プロファイル」の章を参照してください。関連項目: ユーザー・プロファイルの概要

afpend()

#include <afcp.h>

return(afpend(status, reqinfo, message));

説明

コンカレント処理の汎用APIテンプレートで書かれているサブルーチンの最後で、関数afpend()をコールします。afpendは、クリーン・アップして、ステータス・コードおよび完了メッセージを表示し、コンカレント・プログラムから戻るための関数です。これにより、データベースが切断され、Application Object Libraryのメモリーが解放されて、Application Object Libraryファイルが閉じ、指定したステータス・コードが返されます。

戻り値

この関数が正常に終了すると、TRUEが戻されます。エラーが発生した場合はFALSEが戻されます。

引数

/*   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, ""));

    }

fdpfrs()

afreqstate fdpfrs (request_id, errbuf);

text request_id;

text errbuf;

説明

fdpfrs()コマンドは特定の要求IDのステータスを返します。このコマンドは戻りステータス・マクロORAF_REQUEST_XXXとともに使用します。

戻り値

この関数は引数として渡された要求IDのステータスを戻します。

引数

#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;

}

fdpscp()

#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の内容を出力し、エラー状態で終了します。

引数

#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, ""));}

}

fdpscr()

#include <afcp.h>

boolean fdpscr( command, request_id, errbuf )

text        *command;

text        *request_id;

text        *errbuf; 

説明

fdpscr()関数により、コンカレント・プログラムを実行するための要求か発行されます。この関数はPro*Cコンカレント・プログラムからのみコールできます。子要求のユーザー・プロファイル・オプションは、親コンカレント・プログラムの要求をデフォルトとして使用します。要求がコンカレント・マネージャにより実行可能になるように、この関数をコールした後にコミットする必要があります。コミットせずにロールバックすると、要求は失われます。

戻り値

コンカレント要求が正常に発行されると、fdpscr()からTRUEが戻されます。正常に発行されなかった場合はFALSEが戻されます。

引数

/* 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);

    }

fdpwrt()

#include fdpwrt.h

boolean fdpwrt( flag, message)

fdcoflgs         flags

text                *message; 

説明

fdpwrt()関数によって標準ログ・ファイルまたは標準レポート出力ファイルにテキスト文字列が書き込まれます。ファイルを明示的にオープンしてクローズする必要はありません。Oracle Application Object Libraryでは、ログ・ファイルまたはレポート出力ファイルの名前を、『Oracle Applications概要』で説明されている標準命名規則に従って命名します。

戻り値

指定したファイルにメッセージを書き込めない場合は、関数fdpwrt()からFALSEが返されます。それ以外は、TRUEが返されます。

引数

/* 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);

    }