↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11
预发布版本文档。 PostgreSQL 19beta4 为测试版本,最终发布内容可能有所不同。

CREATE PROCEDURE

CREATE PROCEDURE — 定义一个新过程

大纲

CREATE [ OR REPLACE ] PROCEDURE
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
  { LANGUAGE lang_name
    | TRANSFORM { FOR TYPE type_name } [, ... ]
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | SET configuration_parameter { TO value | = 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 节。

参数

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,具体取决于语言)。

关于允许的参数名和值的更多信息,见 SET 和第 19 章。

definition #

定义该过程的字符串常量,其含义取决于所用语言。它可以是内部过程名称、对象文件路径、SQL 命令,或过程语言中的文本。

通常,使用美元引用(见第 4.1.2.4 节)来书写过程定义字符串,会比普通单引号语法更方便。不使用美元引用时,过程定义中的任何单引号或反斜线都必须通过双写进行转义。

obj_file, link_symbol #

当 C 语言源代码中的过程名与 SQL 过程名不同时,会为可动态加载的 C 语言过程使用 AS 子句的这种形式。字符串 obj_file 是包含已编译 C 过程的共享库文件名,其解释方式与 LOAD 命令相同。字符串 link_symbol 是该过程的链接符号,也就是它在 C 语言源代码中的过程名。如果省略链接符号,则假定它与所定义的 SQL 过程名相同。

当重复调用的 CREATE PROCEDURE 引用同一个对象文件时,该文件在每个会话中只会被加载一次。要卸载并重新加载该文件(例如在开发期间),需要启动一个新会话。

sql_body #

LANGUAGE 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。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.