2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前18)/ 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 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_file, link_symbol

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

兼容性

SQL 标准中定义了CREATE PROCEDURE 命令。PostgreSQL 实现可以以兼容的方式使用,但有许多扩展。有关详细信息,另请参阅CREATE FUNCTION

提交更正

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