SQL COMMAND · 函数与过程
CREATE PROCEDURE
定义一个新过程
CREATE函数与过程引入 11现存至 20 devel1 次语法变更
- 动词
CREATE- 对象
PROCEDURE- 分组
- 函数与过程
- 引入版本
- 11
- 状态
- 现存
- 语法变更次数
- 1
- 手册小节数
- 6
版本轨迹
相对 PostgreSQL 17 无变化。
语法铁道图 PostgreSQL 18
沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。
语法概要
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权限。
有关编写过程的详细信息,请参阅Section 36.4。
参数
name要创建的过程名称(可选模式限定)。
argmode参数模式:
IN、OUT、INOUT或VARIADIC。 如果省略,默认为IN。argname参数的名称。
argtype过程参数的数据类型(如果有,可选模式限定)。参数类型可以是基础类型、复合类型或域类型,也可以引用表列的类型。
根据实现语言,也可能允许指定诸如
cstring之类的“伪类型”。伪类型表示实际参数类型要么没有被完整指定,要么位于普通 SQL 数据类型集合之外。可以通过写成
来引用列的类型。使用这一特性有时可以帮助让过程不受表定义变更的影响。table_name.column_name%TYPEdefault_expr在未指定该参数时用作默认值的表达式。该表达式必须能够强制转换为该参数的类型。任何位于带默认值参数之后的输入参数也都必须具有默认值。
lang_name实现该过程所用语言的名称。可以是
sql、c、internal,或者用户自定义过程语言的名称,例如plpgsql。 如果指定了sql_body, 默认值是sql。不推荐将该名称放在单引号中;如果这样写,大小写必须完全匹配。TRANSFORM { FOR TYPEtype_name} [, ... ] }列出调用该过程时应应用哪些转换。转换负责在 SQL 类型与语言特定数据类型之间进行转换;详见CREATE TRANSFORM。过程语言实现通常对内置类型有硬编码知识,因此无须在此列出。如果某种过程语言实现不知道如何处理某个类型,且又没有提供转换,则会退回到默认的数据类型转换行为,但具体行为取决于该实现。
[EXTERNAL] SECURITY INVOKER[EXTERNAL] SECURITY DEFINERSECURITY INVOKER表示该过程将以调用它的用户的权限执行。这是默认值。SECURITY DEFINER指定该过程将以拥有它的用户的权限执行。关键字
EXTERNAL是为了符合 SQL 而允许使用的,但它是可选的,因为与 SQL 不同,此特性适用于所有过程,而不只是外部过程。SECURITY DEFINER过程不能执行事务控制语句(例如COMMIT和ROLLBACK,具体取决于语言)。configuration_parametervalueSET子句会在进入该过程时把指定的配置参数设置为指定值,并在过程退出时恢复为之前的值。SET FROM CURRENT会把执行CREATE PROCEDURE时该参数的当前值保存为进入过程时要应用的值。如果为过程附加了
SET子句,那么在该过程中针对同一变量执行的SET LOCAL命令,其效果会被限制在该过程内:过程退出时,该配置参数的先前值仍会被恢复。不过,普通的SET命令(不带LOCAL)会覆盖这个SET子句,就像它会覆盖先前的SET LOCAL命令一样:这种命令的效果会在过程退出后持续存在,除非当前事务被回滚。如果为过程附加了
SET子句,则该过程不能执行事务控制语句(例如COMMIT和ROLLBACK,具体取决于语言)。关于允许的参数名和值的更多信息,见SET和Chapter 19。
definition定义该过程的字符串常量,其含义取决于所用语言。它可以是内部过程名称、对象文件路径、SQL 命令,或过程语言中的文本。
通常,使用美元引用(见Section 4.1.2.4)来书写过程定义字符串,会比普通单引号语法更方便。不使用美元引用时,过程定义中的任何单引号或反斜线都必须通过双写进行转义。
obj_file,link_symbol当 C 语言源代码中的过程名与 SQL 过程名不同时,会为可动态加载的 C 语言过程使用
AS子句的这种形式。字符串obj_file是包含已编译 C 过程的共享库文件名,其解释方式与LOAD命令相同。字符串link_symbol是该过程的链接符号,也就是它在 C 语言源代码中的过程名。如果省略链接符号,则假定它与所定义的 SQL 过程名相同。当重复调用的
CREATE PROCEDURE引用同一个对象文件时,该文件在每个会话中只会被加载一次。要卸载并重新加载该文件(例如在开发期间),需要启动一个新会话。sql_bodyLANGUAGE SQL过程的主体。这应当是一个语句块:BEGIN ATOMIC
statement;statement; ...statement; END这类似于把过程体文本写成字符串常量(见上面的
definition),但有几点不同:这种形式只适用于LANGUAGE SQL,而字符串常量形式适用于所有语言。这种形式在过程定义时解析,字符串常量形式则在执行时解析;因此,这种形式不支持多态参数类型以及其他无法在过程定义时解析的构造。这种形式会跟踪过程与过程体中所用对象之间的依赖关系,因此DROP ... CASCADE能够正常工作,而使用字符串字面量的形式则可能留下悬空过程。最后,这种形式与 SQL 标准以及其他 SQL 实现更兼容。
注解
有关函数创建且同样适用于过程的更多细节,请参见CREATE FUNCTION。
使用CALL执行过程。
示例
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。
另见
语法演化
相邻大版本之间的差异,新的在前。版本号链接到对应快照。
PostgreSQL 14← 13语法变化
+ | sql_body正文更新PostgreSQL 12← 11正文更新
正文更新PostgreSQL 11← 10新增此命令
同组命令
| 命令 | 动词 | 对象 | 版本变动 | 最近变更 |
|---|---|---|---|---|
CALL | CALL | — | — | |
| 调用一个过程 | 现存 | |||
DO | DO | — | — | |
| 执行匿名代码块 | 现存 | |||
CREATE AGGREGATE | CREATE | AGGREGATE | 203 次 | |
| 定义一个新的聚合函数 | 现存 | |||
ALTER AGGREGATE | ALTER | AGGREGATE | 141 次 | |
| 更改一个聚合函数的定义 | 现存 | |||
DROP AGGREGATE | DROP | AGGREGATE | — | |
| 移除一个聚合函数 | 现存 | |||
CREATE FUNCTION | CREATE | FUNCTION | 143 次 | |
| 定义一个新函数 | 现存 | |||
ALTER FUNCTION | ALTER | FUNCTION | 143 次 | |
| 更改函数的定义 | 现存 | |||
DROP FUNCTION | DROP | FUNCTION | — | |
| 移除一个函数 | 现存 | |||
CREATE LANGUAGE | CREATE | LANGUAGE | 131 次 | |
| 定义一种新的过程语言 | 现存 | |||
ALTER LANGUAGE | ALTER | LANGUAGE | 141 次 | |
| 更改一种过程语言的定义 | 现存 | |||
DROP LANGUAGE | DROP | LANGUAGE | — | |
| 移除一种过程语言 | 现存 | |||
CREATE PROCEDURE | CREATE | PROCEDURE | 141 次 | |
| 定义一个新过程 | 现存 | |||
ALTER PROCEDURE | ALTER | PROCEDURE | 142 次 | |
| 更改过程的定义 | 现存 | |||
DROP PROCEDURE | DROP | PROCEDURE | — | |
| 移除一个过程 | 现存 | |||
ALTER ROUTINE | ALTER | ROUTINE | 142 次 | |
| 更改一个例程的定义 | 现存 | |||
DROP ROUTINE | DROP | ROUTINE | — | |
| 移除一个例程 | 现存 | |||
CREATE TRANSFORM | CREATE | TRANSFORM | — | |
| 定义一个新的转换 | 现存 | |||
DROP TRANSFORM | DROP | TRANSFORM | — | |
| 移除一个转换 | 现存 | |||