2024年9月26日:PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不受支持的版本:11

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

参数的模式:INOUTINOUTVARIADIC。如果省略,则默认为 IN

argname

参数的名称。

argtype

过程参数的数据类型(可选模式限定),如果有。参数类型可以是基本类型、复合类型或域类型,也可以引用表列的类型。

根据实现语言,还可以允许指定伪类型,例如 cstring。伪类型表示实际参数类型要么未完全指定,要么在普通 SQL 数据类型集合之外。

列的类型通过编写 table_name.column_name%TYPE 来引用。使用此功能有时可以帮助使过程独立于表定义的更改。

default_expr

如果未指定参数,则用作默认值的表达式。该表达式必须能够强制转换为参数的参数类型。所有在具有默认值的参数之后的输入参数也必须具有默认值。

lang_name

实现过程的语言的名称。它可以是 sqlcinternal 或用户定义的过程语言的名称,例如 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 过程不能执行事务控制语句(例如,COMMITROLLBACK,具体取决于语言)。

configuration_parameter
value

SET 子句导致在进入过程时将指定的配置参数设置为指定值,然后在过程退出时将其恢复为其先前值。SET FROM CURRENT 将在执行 CREATE PROCEDURE 时当前的参数值保存为在进入过程时要应用的值。

如果 SET 子句附加到过程,则在过程中对同一变量执行的 SET LOCAL 命令的影响仅限于过程:在过程退出时仍会恢复配置参数的先前值。但是,普通 SET 命令(不带 LOCAL)会覆盖 SET 子句,就像它对先前的 SET LOCAL 命令所做的那样:此类命令的影响将在过程退出后持续存在,除非当前事务回滚。

如果 SET 子句附加到过程,则该过程不能执行事务控制语句(例如,COMMITROLLBACK,具体取决于语言)。

有关允许的参数名称和值的更多信息,请参阅SET第 19 章

definition

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

通常使用美元符号引用(请参阅第 4.1.2.4 节)来编写过程定义字符串,而不是普通的单引号语法。如果不使用美元符号引用,则过程定义中的任何单引号或反斜杠都必须通过加倍来转义。

obj_filelink_symbol

当 C 语言源代码中的过程名称与 SQL 过程的名称不同时,此形式的 AS 子句用于动态加载的 C 语言过程。字符串 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

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用此表单报告文档问题。