受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

CREATE PROCEDURE

CREATE PROCEDURE — 定义一个新过程

Synopsis

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权限。

有关编写过程的详细信息,请参阅Section 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,具体取决于语言)。

关于允许的参数名和值的更多信息,见SETChapter 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_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

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。