================ CREATE PROCEDURE ================ .. container:: refentry :name: SQL-CREATEPROCEDURE .. container:: titlepage .. container:: refnamediv .. rubric:: CREATE PROCEDURE :name: create-procedure CREATE PROCEDURE — 定义一个新的过程 .. container:: refsynopsisdiv .. rubric:: 大纲 :name: 大纲 .. code:: 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' } ... .. container:: refsect1 :name: SQL-CREATEPROCEDURE-DESCRIPTION .. rubric:: 简介 :name: 简介 ``CREATE PROCEDURE``\ 定义一个新的过程。\ ``CREATE OR REPLACE PROCEDURE``\ 将会创建一个新过程或者替换一个已有的定义。为了能够定义过程,用户必须具有所使用的语言上的\ ``USAGE``\ 特权。 如果这个命令中包括了一个方案名称,则该过程将被创建在该方案中。否则过程将被创建在当前的方案中。新过程的名称不能匹配同一方案中具有相同输入参数类型的任何现有过程或函数。不过,具有不同参数类型的过程和函数可以共享同一个名称(这被称为\ *重载*\ )。 要替换一个已有过程的当前定义,请使用\ ``CREATE OR REPLACE PROCEDURE``\ 。不能用这种方式更改过程的名称或者参数类型(如果尝试这样做,实际上会创建一个新的、不同的过程)。 当\ ``CREATE OR REPLACE PROCEDURE``\ 被用来替换一个现有的过程时,该过程的拥有关系和权限保持不变。所有其他的过程属性会被赋予这个命令中指定的或者暗示的值。必须拥有(包括成为拥有角色的成员)该过程才能替换它。 创建过程的用户将成为该过程的拥有者。 为了能够创建一个过程,用户必须具有参数类型上的\ ``USAGE``\ 特权。 .. container:: refsect1 :name: id-1.9.3.76.6 .. rubric:: Parameters :name: parameters .. container:: variablelist ``name`` 要创建的过程的名称(可以是被方案限定的)。 ``argmode`` 参数的模式可以是:\ ``IN``\ 、\ ``INOUT``\ 或者\ ``VARIADIC``\ 。如果省略,则默认为\ ``IN``\ (当前对过程不支持\ ``OUT``\ 参数,可使用\ ``INOUT``\ )。 ``argname`` 参数的名称。 ``argtype`` 过程的参数(如果有)的数据类型(可以是被方案限定的)。参数类型可以是基础类型、组合类型或者域类型,或者可以引用一个表列的类型。 根据具体的实现语言,还可能可以指定“伪类型”,例如\ ``cstring``\ 。伪类型表示实际的参数类型没有完全确定,或者是位于普通SQL数据类型的集合之外。 写上\ ``table_name``.\ ``column_name``\ %TYPE可以引用某个列的类型。使用这种特性有时可以让过程不受表定义改变的影响。 ``default_expr`` 没有指定参数时要被用作默认值的表达式。这个表达式必须符合该参数的参数类型。跟在有默认值的参数后面的输入参数也都必须有默认值。 ``lang_name`` 用于实现该过程的语言名称。它可以是\ ``sql``\ 、\ ``c``\ 、\ ``internal``\ 或者一种用户定义的过程语言的名称,例如\ ``plpgsql``\ 。将名称包裹在单引号内的方式已经被废弃,并且要求大小写匹配。 ``TRANSFORM { FOR TYPE type_name`` } [, ... ] } 列出对过程的调用应该应用哪些Transform。Transform负责在SQL类型和语言相关的数据类型之间进行转换,请参考\ `CREATE TRANSFORM `__\ 。过程语言实现通常采用硬编码的方式保存内建类型的知识,因此它们无需在这里列出。但如果一种过程语言实现不知道如何处理一种类型并且没有提供Transform,它将回退到默认的行为来转换数据类型,但是这依赖于其实现。 ``[EXTERNAL] SECURITY INVOKER`` \ ``[EXTERNAL] SECURITY DEFINER`` ``SECURITY INVOKER``\ 指示过程以调用它的用户的特权来执行。这是默认方式。\ ``SECURITY DEFINER``\ 指定过程以拥有它的用户的特权来执行。 为了符合SQL标注,允许使用\ ``EXTERNAL``\ 关键词,但它是可选的,因为和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``\ ,具体取决于实现的语言)。 ``definition`` 一个定义该过程的字符串常量,其含义取决于语言。它可以是一个内部的过程名、一个对象文件的路径、一个SQL命令或者以一种过程语言编写的文本。 在编写过程的定义字符串时,使用美元引用(见\ `节 `__\ )而不是普通的单引号语法常常会很有帮助。如果没有美元引用,过程定义中的任何单引号或者反斜线必须以双写的方式进行转义。 ``obj_file``, ``link_symbol`` 当C语言源码中的过程名与SQL过程的名称不同时,这种形式的\ ``AS``\ 子句被用于动态可装载的C语言过程。字符串\ ``obj_file``\ 是包含已编译好的C过程的共享库文件名,并且被按照\ `LOAD `__\ 命令的方式解析。字符串\ ``link_symbol``\ 是该过程的链接符号,也就是该过程在C语言源代码中的名称。如果链接符号被省略,则会被假定为与正在被定义的SQL过程的名称相同。 当重复的\ ``CREATE PROCEDURE``\ 调用引用同一个对象文件时,只会对每一个会话装载该文件一次。要卸载或者重新载入该文件(可能是在开发期间),应该开始一个新的会话。 .. container:: refsect1 :name: SQL-CREATEPROCEDURE-NOTES .. rubric:: 注解 :name: 注解 函数创建也适用于过程,更多细节请参考\ `CREATE FUNCTION `__\ 。 使用\ `CALL `__\ 来执行过程。 .. container:: refsect1 :name: SQL-CREATEPROCEDURE-EXAMPLES .. rubric:: 示例 :name: 示例 .. code:: programlisting CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL AS $$ INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); $$; CALL insert_data(1, 2); .. container:: refsect1 :name: SQL-CREATEPROCEDURE-COMPAT .. rubric:: 兼容性 :name: 兼容性 SQL标准中定义有一个\ ``CREATE PROCEDURE``\ 命令。OushuDB的版本类似但是并不完全兼容。详情请见\ `CREATE FUNCTION `__\ 。 .. container:: refsect1 :name: id-1.9.3.76.10 .. rubric:: 另见 :name: 另见 `ALTER PROCEDURE `__, `DROP PROCEDURE `__, `CALL `__, `CREATE FUNCTION `__