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 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,取决于语言)。
definition一个定义过程的字符串常量;其含义取决于语言。它可以是内部过程名称、对象文件的路径、SQL 命令或程序语言中的文本。
使用美元引号(请参阅 第 4.1.2.4 节)编写过程定义字符串通常很有帮助,而不是使用普通的单引号语法。如果没有美元引号,过程定义中的任何单引号或反斜杠都必须通过加倍来转义它们。
obj_file、link_symbol当 C 语言源代码中的过程名称与 SQL 过程的名称不同时,此形式的 AS 子句用于动态加载的 C 语言过程。字符串 obj_file 是包含已编译的 C 过程的共享库文件的名称,其解释方式与 LOAD 命令相同。字符串 link_symbol 是过程的链接符号,即 C 语言源代码中过程的名称。如果省略链接符号,则假定它与正在定义的 SQL 过程的名称相同。
当重复的 CREATE PROCEDURE 调用引用同一个对象文件时,该文件在每个会话中仅加载一次。要卸载并重新加载该文件(可能在开发过程中),请启动一个新会话。
sql_bodyLANGUAGE SQL 过程的主体。这应该是一个块
BEGIN ATOMICstatement;statement; ...statement; END
这类似于将过程主体的文本编写为字符串常量(请参阅上面的definition),但存在一些差异:此形式仅适用于 LANGUAGE SQL,字符串常量形式适用于所有语言。此形式在过程定义时进行解析,字符串常量形式在执行时进行解析;因此,此形式不支持多态参数类型和其他在过程定义时无法解析的构造。此形式跟踪过程和过程中使用的对象之间的依赖关系,因此 DROP ... CASCADE 将正确工作,而使用字符串文字的形式可能会留下悬空的过程。最后,此形式与 SQL 标准和其他 SQL 实现更加兼容。
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。
如果您在文档中发现任何不正确的内容,与您使用特定功能的体验不符或需要进一步澄清,请使用此表单报告文档问题。