1

異なるプロシージャを持つ 1 つのパッケージと、他のプロシージャを呼び出すメイン プロシージャが 1 つあります。

フロントエンドを通じて、プロシージャ名を に渡していますmain()。('呼び出す必要があるプロシージャ名') を含むパラメータ名を記述するだけで、プロシージャを呼び出す方法はありますか?

CREATE OR REPLACE PACKAGE BODY UPLOAD_PKG
IS

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG_PR IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG,'ABC');
  END PRINT_LOG_PR;

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG1 IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG, 'XYZ');
  END PRINT_LOG1;

  PROCEDURE Main( p_obj_type VARCHAR2
                 , errbuf VARCHAR2
                 , retcode VARCHAR2) IS
  BEGIN 
    -Is this possible for eg i have passed PRINT_LOG1 here and calling PRINT_LOG1
     p_obj_type ;-
  END main;
END UPLOAD_PKG
4

4 に答える 4

4

はい。

PROCEDURE Main( p_obj_type VARCHAR2
              , errbuf VARCHAR2
              , retcode VARCHAR2) IS
BEGIN 
  CASE p_obj_type
  WHEN 'PRINT_LOG_PR' THEN PRINT_LOG_PR;
  WHEN 'PRINT_LOG1' THEN PRINT_LOG1;
  END CASE;
END main;
于 2010-10-01T04:51:00.893 に答える
3

使用する:

CREATE OR REPLACE PACKAGE BODY UPLOAD_PKG
IS

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG_PR IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG,'ABC');
  END PRINT_LOG_PR;

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG1 IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG, 'XYZ');
  END PRINT_LOG1;

  PROCEDURE MAIN( p_obj_type VARCHAR2
                 , errbuf VARCHAR2
                 , retcode VARCHAR2) IS
  BEGIN 

    CASE p_obj_type
      WHEN 'PRINT_LOG_PR' THEN UPLOAD_PKG.PRINT_LOG_PR;
      WHEN 'PRINT_LOG1' THEN UPLOAD_PKG.PRINT_LOG1;
    END CASE;

  END MAIN;

END UPLOAD_PKG

MAIN ストアド プロシージャで使用した CASE ステートメントは、ANSI SQL CASE ではなく、PLSQL CASE ステートメントです。PLSQL バージョンEND CASEでは CASE ステートメントを終了する必要があるため、わかります。

于 2010-10-01T04:50:59.960 に答える
1

If you don't want to use dynamic pl/sql, then I would suggest to use constant variables in package header to choose between procedures (avoiding hard coding much as possible).

Main procedure call would be for example:

UPLOAD_PKG.MAIN(UPLOAD_PKG.C_PRINT_LOG_PR, v_errbuf, v_retcode);

And in the Main body you would use case like this:

CASE p_obj_type
  WHEN C_PRINT_LOG_PR THEN UPLOAD_PKG.PRINT_LOG_PR;
  WHEN C_PRINT_LOG1   THEN UPLOAD_PKG.PRINT_LOG1;
  ELSE RAISE SOME_ERROR;
END CASE;

In header you can define constant variables to contain whatever:

CREATE OR REPLACE PACKAGE UPLOAD_PKG
IS
  C_PRINT_LOG_PR CONSTANT VARCHAR2(22) := 'What ever';
  C_PRINT_LOG1   CONSTANT VARCHAR2(22) := 'What ever2';
  ...

But some cases client applications cannot refer global variables of packages, so you need to create function for every constant variable to return those. But this will go little bit too complicated, if you just could call those correct procedures...

But for the curiosity can you tell us why do you need to use package this way?

于 2010-10-03T14:31:24.170 に答える
0

CASE ソリューションと同様に、動的 PL/SQL を使用してこれを行うことができます。

PROCEDURE MAIN( p_obj_type VARCHAR2
             , errbuf VARCHAR2
             , retcode VARCHAR2) IS
 BEGIN 
    EXECUTE IMMEDIATE 'begin upload_pkg.'||p_obj_type|| '; end;';
END MAIN;

単純なパラメーター (Date、Varhar2、Number) は、USING コマンドで IN OUT に渡すことができます。

重要な問題は、それが賢明かどうかです。

他の動的言語と同様に、コンパイル時ではなく、実行時にのみ検出されるエラーの範囲を残します。つまり、存在しない p_obj_type の値を渡します。これは、定数または抽象データ型を使用して軽減できます。

また、各動的 sql または pl/sql コマンドは、実際のコンパイル済みコードと比較して、解析のオーバーヘッドがわずかに発生します。このオーバーヘッドは小さいですが、ループ内で実行すると顕著になります。

最後に、呼び出されたコードには同じパラメーター シグネチャが必要です。

于 2010-10-01T10:28:32.073 に答える