GaussDB-嵌套的子程序

87 阅读4分钟

GaussDB-嵌套的子程序

在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 subpragram'); END; BEGIN dbe_output.put_line('this is a procedure'); -- 执行块内调用子存储过程 proc_sub(); END; / -- 外部调用存储过程 BEGIN proc_test; END; / -- 输出结果 this is a procedure this is subpragram 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 subpragram2 begin'); dbe_output.put_line('--this is subpragram2 end'); END; BEGIN dbe_output.put_line('this is subpragram1 begin'); proc_sub2(); dbe_output.put_line('this is subpragram1 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 subpragram1 begin --this is subpragram2 begin --this is subpragram2 end this is subpragram1 end this is a procedure end

| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### 嵌套子程序的变量

变量类型包括:基础类型,cursor类型等其它PL/SQL支持的变量类型。

-   可访问的变量:

    -   自身声明的变量。
    -   上层子程序声明的变量。

-   变量的访问规则:

    -   如果变量不带限定符,首先将在本程序内查找变量,如果变量名不存在,则向上层查找变量,以此类推。
    -   如果变量带有限定符,将在限定符的区域查找。目前仅支持一个限定符的调用。

更多详情请参考GaussDB 文档中心:<https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/productdesc/qlh_03_0001.html>