CREATE PROCEDURE — 定义新过程
CREATE [ OR REPLACE ] PROCEDUREname
( [ [argmode
] [argname
]argtype
[ { DEFAULT | = }default_expr
] [, ...] ] ) { LANGUAGElang_name
| TRANSFORM { FOR TYPEtype_name
} [, ... ] | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | SETconfiguration_parameter
{ TOvalue
| =value
| FROM CURRENT } | AS 'definition
' | AS 'obj_file
', 'link_symbol
' |sql_body
} ...
CREATE PROCEDURE
定义新过程。 CREATE OR REPLACE PROCEDURE
将创建新过程或替换现有定义。要能够定义过程,用户必须对该语言拥有 USAGE
权限。
如果包含架构名称,则过程在指定的架构中创建。否则,它在当前架构中创建。新过程的名称不能与同一架构中具有相同输入参数类型的任何现有过程或函数匹配。但是,不同参数类型的过程和函数可以共享一个名称(这称为重载)。
要替换现有过程的当前定义,请使用 CREATE OR REPLACE PROCEDURE
。不能通过这种方式更改过程的名称或参数类型(如果您尝试,实际上将创建一个新的、不同的过程)。
当 CREATE OR REPLACE PROCEDURE
用于替换现有过程时,过程的所有权和权限不会更改。所有其他过程属性都分配为命令中指定或隐含的值。您必须拥有该过程才能替换它(包括成为所有者角色的成员)。
创建过程的用户将成为该过程的所有者。
要能够创建过程,您必须对参数类型拥有 USAGE
权限。
有关编写过程的详细信息,请参阅 第 38.4 节。
name
要创建的存储过程的名称(可选的模式限定)。
argmode
参数的模式:IN
、OUT
、INOUT
或 VARIADIC
。如果省略,则默认为 IN
。
argname
参数的名称。
argtype
存储过程参数的数据类型(可选的模式限定),如果有的话。参数类型可以是基本类型、复合类型或域类型,或者可以引用表列的类型。
根据实现语言,它还可能允许指定 “伪类型”,例如 cstring
。伪类型表示实际参数类型要么指定不完整,要么不在普通 SQL 数据类型的集合中。
通过编写
来引用列的类型。使用此功能有时有助于使过程独立于表定义的更改。table_name
.column_name
%TYPE
default_expr
如果未指定参数,则用作默认值的表达式。该表达式必须可以强制转换为参数的参数类型。带有默认值的参数后面的所有输入参数也必须具有默认值。
lang_name
存储过程实现所用语言的名称。它可以是 sql
、c
、internal
或用户定义的过程语言的名称,例如 plpgsql
。如果指定了 sql_body
,则默认为 sql
。用单引号括起名称已弃用,并且需要匹配大小写。
TRANSFORM { FOR TYPE type_name
} [, ... ] }
列出应应用于对过程调用的转换。转换在 SQL 类型和特定于语言的数据类型之间转换;请参见 CREATE TRANSFORM。过程语言实现通常对内置类型有硬编码的知识,因此不必在此处列出这些类型。如果过程语言实现不知道如何处理类型且未提供转换,它将回退到用于转换数据类型的默认行为,但这取决于实现。
[EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINER
SECURITY INVOKER
表示该过程将使用调用它的用户的权限执行。这是默认设置。SECURITY DEFINER
指定该过程将使用拥有它的用户的权限执行。
关键字 EXTERNAL
允许用于 SQL 符合性,但它是可选的,因为与 SQL 不同,此功能适用于所有过程,而不仅仅是外部过程。
SECURITY DEFINER
过程无法执行事务控制语句(例如,COMMIT
和 ROLLBACK
,具体取决于语言)。
configuration_parameter
value
当进入过程时,SET
子句会导致将指定的配置参数设置为指定的值,然后在退出过程时将其还原为其先前值。SET FROM CURRENT
将在执行 CREATE PROCEDURE
时当前的参数值保存为在进入过程时应用的值。
如果 SET
子句附加到过程,则在过程内部针对同一变量执行的 SET LOCAL
命令的效果仅限于该过程:配置参数的先前值仍会在过程退出时还原。但是,普通 SET
命令(不带 LOCAL
)会覆盖 SET
子句,就像它对先前的 SET LOCAL
命令所做的那样:此类命令的效果将在过程退出后仍然存在,除非回滚当前事务。
如果 SET
子句附加到过程,则该过程无法执行事务控制语句(例如,COMMIT
和 ROLLBACK
,具体取决于语言)。
定义
定义过程的字符串常量;含义取决于语言。它可以是内部过程名称、对象文件路径、SQL 命令或过程语言中的文本。
通常,使用美元引用(请参阅第 4.1.2.4 节)来编写过程定义字符串,而不是使用普通的单引号语法,会很有帮助。如果不使用美元引用,过程定义中的任何单引号或反斜杠都必须通过加倍来转义。
obj_file
、link_symbol
此形式的 AS
子句用于动态可加载的 C 语言过程,当 C 语言源代码中的过程名称与 SQL 过程的名称不同时。字符串 obj_file
是包含已编译 C 过程的共享库文件的名称,并且解释为 LOAD
命令。字符串 link_symbol
是过程的链接符号,即 C 语言源代码中过程的名称。如果省略链接符号,则假定它与正在定义的 SQL 过程的名称相同。
当重复的 CREATE PROCEDURE
调用引用同一对象文件时,每个会话只加载一次该文件。要卸载并重新加载文件(可能在开发期间),请启动一个新会话。
sql_body
LANGUAGE SQL
过程的主体。这应是一个块
BEGIN ATOMICstatement
;statement
; ...statement
; END
这类似于将过程主体的文本写为字符串常量(请参阅上面的 definition
),但有一些区别:此形式仅适用于 LANGUAGE SQL
,字符串常量形式适用于所有语言。此形式在过程定义时进行解析,字符串常量形式在执行时进行解析;因此,此形式不支持多态参数类型和在过程定义时无法解析的其他构造。此形式跟踪过程与过程主体中使用的对象之间的依赖关系,因此 DROP ... CASCADE
将正常工作,而使用字符串常量的形式可能会留下悬空过程。最后,此形式与 SQL 标准和其他 SQL 实现更兼容。
CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL AS $$ INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); $$;
或
CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;
并像这样调用
CALL insert_data(1, 2);
SQL 标准中定义了 CREATE PROCEDURE
命令。PostgreSQL 实现可以兼容的方式使用,但有很多扩展。有关详细信息,另请参阅CREATE FUNCTION。