调用带有变量名的函数?

发布于 2024-09-25 15:36:31 字数 745 浏览 10 评论 0原文

我有一个包含不同过程的包,以及一个主过程,我通过它调用其他过程。

通过前端,我将过程名称传递到 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

I have one package that has different procedures, and one main procedure through which I am calling other procedures.

Through the front end, I am passing the procedure name into main(). Is there any way by which the procedure can be called just writing the parameter name containing('Procedure Name that is need to be called')?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

掩于岁月 2024-10-02 15:36:31

是的。

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;

Yes.

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;
陈甜 2024-10-02 15:36:31

使用:

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 语句。

Use:

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

The CASE statement I used in the MAIN stored procedure is the PLSQL CASE statement, not the ANSI SQL CASE. You can tell because the PLSQL version needs END CASE to end the CASE statement.

可爱暴击 2024-10-02 15:36:31

如果您不想使用动态 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';
  ...

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

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

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?

就是爱搞怪 2024-10-02 15:36:31

除了 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 命令都会产生少量的解析开销。此开销很小,但如果在循环内执行,则会变得很明显。

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

As well as the CASE solution, it is possible to do this using dynamic 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;

Simple parameters (Date, Varhar2, Number) can be passed IN OUT with the USING command.

The key question is whether it is advisable.

As with any dynamic language, it leaves scope for errors that will only be found at runtime, rather than compile time - i.e. passing in a value for p_obj_type that does not exist. You could mitigate this through constants or abstract data types.

Also each dynamic sql or pl/sql command incurs a small parsing overhead vs actual compiled code. This overhead is small, but becomes noticeable if performed inside a loop.

Lastly, the called code must have the same parameter signature.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文