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 语句是 PLSQL CASE 语句,而不是 ANSI SQL CASE。你可以看出是因为PLSQL版本需要END CASE结束CASE语句。

于 2010-10-01T04:50:59.960 回答
1

如果您不想使用动态 pl/sql,那么我建议在包头中使用常量变量来在程序之间进行选择(尽可能避免硬编码)。

主程序调用例如:

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

在主体中,您将使用这样的案例:

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;

在标题中,您可以定义常量变量以包含任何内容:

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

但在某些情况下,客户端应用程序无法引用包的全局变量,因此您需要为每个常量变量创建函数以返回这些变量。但这有点太复杂了,如果你能调用那些正确的程序......

但是出于好奇,您能告诉我们为什么需要以这种方式使用包吗?

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

可以使用 USING 命令将简单参数(日期、Varhar2、数字)传入 OUT。

关键问题是它是否可取

与任何动态语言一样,它为仅在运行时而不是编译时发现的错误留出了余地——即传入一个不存在的 p_obj_type 值。您可以通过常量或抽象数据类型来缓解这种情况。

此外,与实际编译的代码相比,每个动态 sql 或 pl/sql 命令都会产生很小的解析开销。这种开销很小,但如果在循环内执行,就会变得很明显。

最后,被调用的代码必须具有相同的参数签名。

于 2010-10-01T10:28:32.073 回答