CREATE PROCEDURE
功能描述
创建一个新的存储过程。
注意事项
- 如果创建存储过程时参数或返回值带有精度,不进行精度检测。
- 创建存储过程时,存储过程定义中对表对象的操作建议都显示指定模式,否则可能会导致存储过程执行异常。
- 在创建存储过程时,存储过程内部通过SET语句设置current_schema和search_path无效。执行完函数search_path和current_schema与执行函数前的search_path和current_schema保持一致。
- 如果存储过程参数中带有出参,SELECT调用存储过程必须缺省出参,CALL调用存储过程时调用非重载函数必须指定出参,对于重载的package函数,out参数可以缺省,具体信息参见CALL的示例。
- 存储过程指定package属性时支持重载。
- 在创建procedure时,不能在avg函数外面嵌套其他agg函数,或者其他系统函数。
- 函数定义时如果指定为IMMUTABLE和SHIPPABLE类型,应该尽量避免函数中存在INSERT,UPDATE,DELETE,MERGE和DDL操作,因为上述操作应该由CN判断对应的执行节点,否则执行结果可能产生错误。
- 存储过程中不支持需要return集合的操作。
- 在存储过程内部调用其它无参数的存储过程时,可以省略括号,直接使用存储过程名进行调用。
- 在存储过程内部调用其他有出参的函数,如果在赋值表达式中调用时,被调函数的出参可以省略,给出了也会被忽略。
- 存储过程支持参数注释的查看与导出、导入。
- 存储过程支持介于IS/AS与plsql_body之间的注释的查看与导出、导入。
- 被授予CREATE ANY FUNCTION权限的用户,可以在用户模式下创建/替换存储过程。
- 存储过程默认为SECURITY INVOKER权限,如果想将默认行为改为SECURITY DEFINER权限,需要设置guc参数behavior_compat_options='plsql_security_definer',如果对定义者权限不了解,请参考《安全加固指南》中的“数据库配置 > 权限控制”章节。
语法格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
openGauss=# CREATE [ OR REPLACE ] PROCEDURE procedure_name [ ( {[ argname ] [ argmode ] argtype [ { DEFAULT | := | = } expression ]}[,...]) ] [ { IMMUTABLE | STABLE | VOLATILE } | { SHIPPABLE | NOT SHIPPABLE } | {PACKAGE} | [ NOT ] LEAKPROOF | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER} | COST execution_cost | SET configuration_parameter { [ TO | = ] value | FROM CURRENT } ][ ... ] { IS | AS } plsql_body / |
参数说明
- OR REPLACE
当存在同名的存储过程时,替换原来的定义。
- procedure_name
创建的存储过程名称,可以带有模式名。
取值范围:字符串,要符合标识符的命名规范。
- argmode
参数的模式。
VARIADIC用于声明数组类型的参数。
取值范围: IN,OUT,INOUT或VARIADIC。缺省值是IN。只有OUT模式的参数后面能跟VARIADIC。并且OUT和INOUT模式的参数不能用在RETURNS TABLE的过程定义中。
- argname
参数的名称。
取值范围:字符串,要符合标识符的命名规范。
- argtype
参数的数据类型。可以使用%ROWTYPE间接引用表的类型,或者使用%TYPE间接引用表或复合类型中某一列的类型。
取值范围:可用的数据类型。
- IMMUTABLE、STABLE等
行为约束可选项。各参数的功能与CREATE FUNCTION类似,详细说明见CREATE FUNCTION
- plsql_body
PL/SQL存储过程体。
当在存储过程体中进行创建用户等涉及用户密码相关操作时,系统表及csv日志中会记录密码的明文。因此不建议用户在存储过程体中进行涉及用户密码的相关操作。
argname和argmode的顺序没有严格要求,推荐按照argname、argmode、argtype的顺序使用。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
--创建一个存储过程。 openGauss=# CREATE OR REPLACE PROCEDURE prc_add ( param1 IN INTEGER, param2 IN OUT INTEGER ) AS BEGIN param2:= param1 + param2; dbe_output.print_line('result is: '||to_char(param2)); END; / --调用此存储过程。 openGauss=# SELECT prc_add(2,3); --创建一个参数模式为VARIADIC的存储过程。 openGauss=# CREATE OR REPLACE PROCEDURE pro_variadic (var1 VARCHAR2(10) DEFAULT 'hello!',var4 VARIADIC int4[]) AS BEGIN dbe_output.print_line(var1); END; / --执行此存储过程。 openGauss=# SELECT pro_variadic(var1=>'hello', VARIADIC var4=> array[1,2,3,4]); --创建一个存储过程,将带着调用它的用户的权限执行。 openGauss=# CREATE TABLE tb1(a integer); openGauss=# CREATE PROCEDURE insert_data(v integer) SECURITY INVOKER AS BEGIN INSERT INTO tb1 VALUES(v); END; / --调用此存储过程。 openGauss=# CALL insert_data(1); --创建带有package属性的存储过程。 openGauss=# create or replace procedure package_func_overload(col int, col2 out varchar) package as declare col_type text; begin col2 := '122'; dbe_output.print_line('two varchar parameters ' || col2); end; / --删除一个存储过程。 openGauss=# DROP PROCEDURE prc_add; openGauss=# DROP PROCEDURE pro_variadic; openGauss=# DROP PROCEDURE insert_data; openGauss=# DROP PROCEDURE package_func_overload; |
相关链接
优化建议
- analyse | analyze
- 不支持在事务或匿名块中执行analyze 。
- 不支持在函数或存储过程中执行analyze操作。