使用非Sql类型执行Immediate

时间:2013-09-20 08:27:06

标签: oracle plsql

我需要在PL / SQL函数中动态调用一个函数(比如handler()),它返回一个嵌套表。

代码:

BEGIN
... 
   v_function := 'handler'; //shown like this of simplicity.
   EXECUTE IMMEDIATE 'BEGIN :result := ' || v_function || '(...); END;'
     USING OUT v_error_msg;

... //process v_error_msg
END;

handler()规范:

TYPE t_error_msgs IS TABLE OF VARCHAR2(2000);

FUNCTION handle (...)
  RETURN t_error_msgs;

问题是我在编译PL-00457:expressions have to be of SQL types时得到execute immediate,不允许绑定非sql类型。

有什么办法吗?

1 个答案:

答案 0 :(得分:1)

这取决于'workaround'的含义类型必须在SQL级别声明,而不是在PL / SQL块中声明(在这种情况下可能是一个包)。这可行,例如:

CREATE OR REPLACE TYPE t_error_msgs AS TABLE OF VARCHAR2(2000)
/

CREATE OR REPLACE PACKAGE p42 AS
  FUNCTION handler RETURN t_error_msgs;
END p42;
/

CREATE OR REPLACE PACKAGE BODY p42 AS
  FUNCTION handler RETURN t_error_msgs IS
  BEGIN
    RETURN null; -- put real data here, obviously...
  END handler;
END p42;
/

DECLARE
  v_error_msg t_error_msgs;
  v_function varchar2(30);
BEGIN
  v_function := 'p42.handler';
  EXECUTE IMMEDIATE 'BEGIN :result := ' || v_function || '; END;'
    USING OUT v_error_msg;
END;
/

或者你可以重新考虑你是否真的需要它是动态的。大概你正在通过或以某种方式确定要动态调用并填充v_function的函数。如果有一个相对较短的可能值列表,那么使用case进行单独的静态函数调用可能会更简单。