不能。execute immediate 无法直接调用未知签名的过程,因它不解析目标过程元数据;必须先查询 all_arguments 获取参数个数、类型、方向及顺序,再构造带 begin...end 的动态块并严格按元数据绑定变量,否则必报 ora-06550 或 ora-00900 等错误。

EXECUTE IMMEDIATE 能不能直接调用未知签名的过程
不能。Oracle 的 EXECUTE IMMEDIATE 本身不解析目标过程的元数据,它只按你写的字符串拼接和参数顺序执行。如果你不知道参数个数、类型、方向(IN/OUT/IN OUT),硬写 USING 子句必然报错——最常见的是 ORA-06550: wrong number or types of arguments 或 ORA-06502: PL/SQL: numeric or value error。
动态调用前必须获取参数元信息
得先查 ALL_ARGUMENTS(或 USER_ARGUMENTS)拿到过程签名,否则没法构造合法的绑定参数列表。关键点:
-
OWNER、OBJECT_NAME、PACKAGE_NAME必须精确匹配,大小写敏感(除非用双引号建对象) - 按
POSITION排序才能还原参数顺序;IN_OUT字段值为IN、OUT或IN/OUT -
DATA_TYPE决定绑定变量类型:比如VARCHAR2→VARCHAR2(4000),NUMBER→NUMBER,DATE→DATE - 注意
DEFAULTED = 'Y'的参数可跳过,但显式传NULL不等于跳过
构造动态块时 BEGIN...END 封装是强制的
哪怕目标过程无返回值,也必须包在匿名 PL/SQL 块里,否则语法不合法。例如:
DECLARE v_sql VARCHAR2(32767); BEGIN v_sql := 'BEGIN ' || :proc_name || '(:p1, :p2); END;'; EXECUTE IMMEDIATE v_sql USING IN 'val1', OUT :p2; END;
常见错误写法:EXECUTE IMMEDIATE :proc_name USING ... —— 这会触发 ORA-00900: invalid SQL statement,因为过程调用不是独立 SQL 语句。
OUT 和 IN OUT 参数必须用变量接收,不能用字面量
USING 子句中,OUT 和 IN OUT 参数必须绑定到已声明的 PL/SQL 变量,不能是常量或表达式。例如:
- ✅ 正确:
USING IN 'A', OUT l_out_val(l_out_val是VARCHAR2变量) - ❌ 错误:
USING IN 'A', OUT 'dummy'(字面量不可赋值) - ❌ 错误:
USING IN 'A', OUT SYSDATE(表达式不可赋值)
如果过程有多个 OUT 参数,变量声明顺序、类型、长度必须与 ALL_ARGUMENTS 查询结果严格一致,否则运行时报类型不匹配。
EXECUTE IMMEDIATE 自动完成,必须手写适配层或借助外部工具生成代码。











