CREATE PROCEDURE
功能描述
创建一个新的存储过程。
注意事项
- 如果创建存储过程时参数或返回值带有精度,不进行精度检测。
- 创建存储过程时,存储过程定义中对表对象的操作建议都显示指定模式,否则可能会导致存储过程执行异常。
- 在创建存储过程时,存储过程内部通过SET语句设置current_schema和search_path无效。执行完函数search_path和current_schema与执行函数前的search_path和current_schema保持一致。
- SELECT、CALL调用函数时,必须要在出参位置提供实参进行调用,实参不会发生作用。
- 存储过程指定package属性时支持重载。
- 不能创建仅形参名字不同(存储过程名和参数列表类型都一样)的重载存储过程。
- 重载的存储过程在调用时变量需要明确具体的类型。
- 不能创建与函数拥有相同名称和参数列表的存储过程。
- 在存储过程内部使用未声明的变量,存储过程被调用时会报错。
- 在创建procedure时,不能在avg函数外面嵌套其他agg函数,或者其他系统函数。
- 在存储过程内部调用其它无参数的存储过程时,可以省略括号,直接使用存储过程名进行调用。
- 在存储过程内部调用其他有出参的函数,如果在赋值表达式中调用时,被调函数的出参可以省略,给出了也会被忽略。
- 存储过程支持参数注释的查看与导出、导入。
- 存储过程支持介于IS/AS与plsql_body之间的注释的查看与导出、导入。
- 存储过程默认为SECURITY INVOKER权限,如果想将默认行为改为SECURITY DEFINER权限,需要设置GUC参数behavior_compat_options='plsql_security_definer'。
- 被授予CREATE ANY FUNCTION权限的用户,可以在用户模式下创建/替换存储过程。
- out/inout参数必须传入变量,不能够传入常量。
- 集中式环境下,想要调用in参数相同,out参数不同的存储过程,需要设置GUC参数behavior_compat_options='proc_outparam_override',并且打开参数后,无论使用select还是call调用存储过程,都必须加上out参数。打开参数后,不支持使用perform调用存储过程或函数。
- 不支持在函数、存储过程、事务或匿名块中执行analyze操作。
- 不可与同一模式下已存在的synonym产生命名冲突。
- 通过
CREATE OR REPLACE
语法替换已有的存储过程时,会一并重建依赖此存储过程的视图,存储过程中的参数数据类型变更等情况可能会导致重建视图失败,进而导致替换存储过程失败。此种情况下,建议先删除依赖的视图,再重建存储过程,再重新创建视图。
语法格式
CREATE [ OR REPLACE ] [DEFINER = usr] PROCEDURE procedure_name
[ ( {[ argmode ] [ argname ] argtype [ { DEFAULT | := | = } expression ]}[,...]) ]
{ IS | AS } plsql_body
/
参数说明
OR REPLACE
当存在同名的存储过程时,替换原来的定义。
DEFINER = user
当创建存储过程、函数时指定SECURITY DEFINER、AUTHID DEFINER、AUTHID DEFINER或者SECURITY DEFINER时声明该函数将以DEFINER指定的用户的权限执行。user后面可以跟
@'主机名'
或者@'ip'
,但并不校验主机名或者ip的合法性。DEFINER = user
选项仅在数据库兼容模式为MySQL时能够使用(即创建DB时DBCOMPATIBILITY='B'),在其他数据库兼容模式下不能使用该特性,详细内容请参考DEFINER。procedure_name
创建的存储过程名称,可以带有模式名。
取值范围:字符串,要符合标识符的命名规范。
argmode
参数的模式。
- VARIADIC用于声明数组类型的参数。
- 只有OUT模式的参数能跟在VARIADIC参数之后。
取值范围: IN、OUT、INOUT或VARIADIC。
默认值:IN
argname
参数的名称。
取值范围:字符串,要符合标识符的命名规范。
argname和argmode的顺序没有严格要求,推荐按照argname、argmode、argtype的顺序使用。
argtype
参数的数据类型。可以使用%TYPE或%ROWTYPE间接引用变量或表的类型,详细可参考存储过程章节定义变量。
取值范围:可用的数据类型。
plsql_body
PL/SQL存储过程体。
当在存储过程体中进行创建用户等涉及用户密码相关操作时,系统表及csv日志中会记录密码的明文。因此不建议用户在存储过程体中进行涉及用户密码的相关操作。
IS | AS
语法格式要求,必须写其中一个。两个含义相同。
示例
1、创建测试表。
CREATE TABLE graderecord ( number INTEGER, name CHAR(20), class CHAR(20), grade INTEGER );
2、创建一个存储过程向表graderecord中插入数据。
CREATE PROCEDURE insert_data (param1 INT = 0, param2 CHAR(20),param3 CHAR(20),param4 INT = 0 ) IS BEGIN INSERT INTO graderecord VALUES(param1,param2,param3,param4); END; /
3、调用存储过程。
CALL insert_data(param1:=210101,param2:='Alan',param3:='21.01',param4:=92);
返回结果为:
insert_data ------------- (1 row)
4、查询表graderecord。
select * from graderecord;
返回结果如下,表中成功插入一条数据:
number | name | class | grade --------+----------------------+----------------------+------- 210101 | Alan | 21.01 | 92 (1 row)
5、删除存储过程和测试表。
DROP PROCEDURE insert_data; DROP TABLE graderecord;