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
权限。
请参阅第 36.4 节以获取有关编写过程的更多信息。
名称
要创建的过程的名称(可选方案限定)。
参数模式
参数的模式:IN
、OUT
、INOUT
或 VARIADIC
。如果省略,则默认值为 IN
。
参数名称
参数的名称。
参数类型
如果存在,则是过程参数的数据类型(可选方案限定),可以是基本类型、复合类型或域类型,也可以引用表列的类型。
根据实现语言,还可能允许指定 “伪类型”,例如 cstring
。伪类型指示实际参数类型不完整或不在普通 SQL 数据类型集中。
通过编写
来引用列的类型。使用此功能有时有助于使过程独立于表定义的更改。table_name
.column_name
%TYPE
default_expr
如果不指定参数,则用作默认值的一个表达式。该表达式必须可以强制转换为参数的参数类型。具有默认值参数之后的某个参数的所有输入参数也必须具有默认值。
语言名称
过程实现的语言名称。它可以是 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
指定过程将使用拥有它的用户的权限执行。
为了符合 SQL,允许使用关键字 EXTERNAL
,但它是可选的,与 SQL 不同,此特性适用于所有过程,不仅是外部过程。
SECURITY DEFINER
过程无法执行事务控制语句(例如,COMMIT
和 ROLLBACK
,具体取决于语言)。
configuration_parameter
value
SET
子句导致在进入过程时将指定的配置参数设置为指定的 value,然后在退出过程时将其恢复为其先前的 value。SET FROM CURRENT
将作为进入过程时应用的 value 保存执行 CREATE PROCEDURE
时的参数的当前 value。
如果将 SET
子句附加到过程,则在该过程中为同一变量执行的 SET LOCAL
命令的效果限定在过程中:配置参数的先前值仍然会在过程退出时恢复。但是,普通 SET
命令(无 LOCAL
)会覆盖 SET
子句,很像它对先前的 SET LOCAL
命令所做的那样:这种命令的效果会在过程退出后持续存在,除非回滚当前事务。
如果将 SET
子句附加到过程,则该过程无法执行事务控制语句(例如,COMMIT
和 ROLLBACK
,具体取决于语言)。
definition
定义过程的字符串常量;含义取决于语言。它可以是内部过程名称、对象文件路径、SQL 命令或过程语言中的文本。
使用 dollar 引用(请参阅 第 4.1.2.4 节)来编写过程定义字符串,而不是常规的单引号语法,这通常很有帮助。如果没有 dollar 引用,过程定义中的任何单引号或反斜杠都必须通过将其加倍来转义。
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);
CREATE PROCEDURE
命令在 SQL 标准中有所定义。 PostgreSQL 实现可以用兼容的方式进行使用,但也有许多扩展。有关详细信息,还请参见 CREATE FUNCTION。