更新时间:2026-10-21 GMT+08:00
嵌套的子程序
在PL/SQL块内创建的子程序,支持在匿名块、存储过程、函数、包内的存储过程及函数中,声明并创建子存储过程或子函数。
注意事项
- 在ORA兼容性数据库下使用。
- 最大嵌套层数限制通过GUC参数max_subpro_nested_layers控制(默认值为3,取值范围0~100)。若嵌套子程序中含有匿名块,匿名块不计入层数,但匿名块内嵌套子程序计入总层数。
- 嵌套子程序不支持重载、不支持使用SETOF。
- 嵌套子程序内不支持定义为自治事务,但可调用含有自治事务的存储过程或函数。
- 子函数(FUNCTION)不支持直接调用且必须包含返回值,子存储过程(PROCEDURE)不支持在表达式中调用。
- 嵌套子程序不支持PERFORM调用,动态语句中不能包含嵌套子程序。
- 当前嵌套子程序的修饰符支持如下,其余修饰符暂不支持。
{IMMUTABLE | STABLE | VOLATILE } {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } - 仅支持一个限定符引用嵌套子程序或嵌套子程序的变量。
- 当子函数(FUNCTION)返回值类型为函数自定义的record类型时,无法通过subfunc().col的方式访问子函数返回值的列属性,执行时会报错。
- 嵌套子程序的声明必须位于声明部分的最后(在其他变量、游标、类型等声明完成之后再声明嵌套子程序)。
- 嵌套子程序只能在声明的函数或存储过程内部调用,外部不可使用。
- 嵌套子程序不支持debugger打断点,但支持step单步调试。
- 其余注意事项同存储过程及函数一致。
语法格式
- 创建子存储过程语法格式:
PROCEDURE procedure_name [ (parameters) ] [{IMMUTABLE | STABLE | VOLATILE } | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }] { IS | AS } [ declarations ] BEGIN plsql_body END; - 创建子函数语法:
FUNCTION function_name [ (parameters) ] RETURN rettype [{IMMUTABLE | STABLE | VOLATILE } | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }] { IS | AS } [ declarations ] BEGIN plsql_body END;在declarations部分可再定义下层的嵌套子程序。
- 示例:
-- 创建一个存储过程 CREATE OR REPLACE PROCEDURE proc_test() AS -- 声明并定义一个子存储过程 PROCEDURE proc_sub() IS BEGIN dbe_output.put_line('this is subprogram'); END; BEGIN dbe_output.put_line('this is a procedure'); -- 执行块内调用子存储过程 proc_sub(); END; / -- 外部调用存储过程 BEGIN proc_test; END; / -- 输出结果 this is a procedure this is subprogram ANONYMOUS BLOCK EXECUTE
嵌套子程序的声明及定义规则
- 嵌套子程序不可重复声明,不可重复定义,不支持重载。
- 嵌套子程序的标识符不得与变量名,关键字同名。
- 支持先声明后定义,所有先声明的子程序必须在后续声明块中找到其定义。
嵌套子程序的调用规则
- 嵌套子程序可调用自身实现递归调用。
- 嵌套子程序可调用上层作用域声明的子程序。
- 嵌套子程序可调用本地声明的下层子程序,但不可访问下层子程序内部的嵌套子程序。
- 嵌套子程序可调用相同作用域中先于自身声明的子程序。
示例:
-- 调用自身
CREATE OR REPLACE PROCEDURE proc_test(var1 int) AS
PROCEDURE proc_sub(var2 int) IS
BEGIN
dbe_output.put_line('var = ' || var2);
IF var2 > 1 THEN
proc_sub(var2 - 1);
END IF;
END;
BEGIN
proc_sub(var1);
END;
/
BEGIN
proc_test(3);
END;
/
--输出结果
var = 3
var = 2
var = 1
--调用上层子程序
CREATE OR REPLACE PROCEDURE proc_test(var1 int) AS
PROCEDURE procsub_1(var2 int) IS
BEGIN
proc_test(var2 - 1);
END;
BEGIN
dbe_output.put_line('proc_test var1 = ' || var1);
IF var1 > 1 THEN
procsub_1(var1);
END IF;
END;
/
BEGIN
proc_test(3);
END;
/
-- 输出结果
proc_test var1 = 3
proc_test var1 = 2
proc_test var1 = 1
-- 调用本地声明的下层子程序
CREATE OR REPLACE PROCEDURE proc_test() AS
PROCEDURE proc_sub1 IS
procedure proc_sub2 IS
BEGIN
dbe_output.put_line('--this is subprogram2 begin');
dbe_output.put_line('--this is subprogram2 end');
END;
BEGIN
dbe_output.put_line('this is subprogram1 begin');
proc_sub2();
dbe_output.put_line('this is subprogram1 end');
END;
BEGIN
dbe_output.put_line('this is a procedure begin');
proc_sub1();
dbe_output.put_line('this is a procedure end');
END;
/
BEGIN
proc_test;
END;
/
-- 输出结果
this is a procedure begin
this is subprogram1 begin
--this is subprogram2 begin
--this is subprogram2 end
this is subprogram1 end
this is a procedure end 嵌套子程序的变量
变量类型包括:基础类型,record类型、table of类型、cursor类型、varray类型等其它PL/SQL支持的变量类型。
- 可访问的变量:
- 自身声明的变量。
- 上层子程序声明的变量。
- 变量的访问规则:
- 如果变量不带限定符,首先将在本程序内查找变量。如果变量名不存在,则向上层查找变量,以此类推。
- 如果变量带有限定符,将在限定符的区域查找。目前仅支持一个限定符的使用。
父主题: 子程序