如何在另一个过程中执行一个过程

时间:2016-02-15 21:14:29

标签: oracle stored-procedures

您好我正在编写一个程序调用的程序,此程序将进一步调用另一个程序来执行不同的业务逻辑。所以我做了这样的事。

PROCEDURE calculator(service_id  IN NUMBER, amount IN  NUMBER) as

  p_proc_name varchar(100);
 begin
  select sc.procedure_name into p_proc_name from test.procedure sc where sc.service_config_id = service_id;

  begin
  execute immediate (p_proc_name) using 1;
  exception when NO_DATA_FOUND then 
  DBMS_OUTPUT.PUT_LINE('p_proc_name = ' || p_proc_name);
  end;


end sb_referal_calculator;

PROCEDURE f_service(amount  IN NUMBER) as
  cmpany_id NUMBER;
  service_date date;
  leases_days NUMBER;
  referal_amount Number;
  requested_quote_id number :=1;

  begin
    referal_amount :=0;
    DBMS_OUTPUT.PUT_LINE('service_date = ');


end f_service;

PROCEDURE d_service(amount  IN NUMBER) as
  cmpany_id NUMBER;
  service_date date;
  leases_days NUMBER;
  referal_amount Number;
  requested_quote_id number :=1;

  begin
    referal_amount :=0;
    DBMS_OUTPUT.PUT_LINE('service_date = ');

end d_service;

所以这里的calcultor程序会动态找到另一个程序名,并尝试用参数执行它。但它给出了一个错误。  这只是一个测试程序。

Executing PL/SQL: CALL DBMS_DEBUG_JDWP.CONNECT_TCP( '10.1.26.70', '55891' )
Debugger accepted connection from database on port 55891.
ORA-00900: invalid SQL statement
ORA-06512: at "test.demo_pkg", line 38
ORA-06512: at line 8
Executing PL/SQL: CALL DBMS_DEBUG_JDWP.DISCONNECT()
Process exited.

我真的不知道这个程序将如何执行此任务。我记得它正在运行,我正在进行测试。但真的不是我所做的并停止工作。

请纠正我的错误。

由于

1 个答案:

答案 0 :(得分:1)

使用execute immediate时,它会在无法查看PL / SQL上下文的SQL上下文中运行动态语句。这有几个影响。首先,您必须从PL / SQL调用您的过程,因此您需要创建一个匿名块,正如Egor Skriptunoff所说,并且您需要的格式完全取决于表(以及您的可变)包含的内容。最短的可能是:

execute immdiate 'begin ' || p_proc_name || ' end;' using 1;

但是假设varible包含如下值:

test_pkg.d_service(:arg);

如果包含没有参数且没有包限定符的过程的名称,即只有d_service,它可能需要尽可能多:

execute immdiate 'begin test_pkg.' || p_proc_name || '(:arg); end;' using 1;

或介于两者之间。

另一个影响是过程名称必须是公共的,因为当它被动态调用时,它实际上是从包外部调用的;所以它必须在包规范中声明。根据程序出现在正文中的顺序,这可能就是这种情况。

但是如果你总是在同一个包中调用过程,并且因为你必须拥有有限数量的可能值,那么避免使用动态SQL并使用该值决定调用哪个过程可能更简单:

case p_proc_name
  when 'f_service' then
    f_service(1);
  when 'd_service' then
    d_service(1);
  -- etc.
end case;

这也让你可以调用私人程序。