CREATE PROCEDURE

CREATE PROCEDURE — 定义一个新的过程

Synopsis

CREATE [ OR REPLACE ] [ EDITIONABLE | NONEDITIONABLE ] PROCEDURE
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
  { LANGUAGE lang_name
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
  } ...

简介

CREATE PROCEDURE定义一个新的过程。CREATE OR REPLACE PROCEDURE将会创建一个新过程或者替换一个已有的定义。为了能够定义过程,用户必须具有所使用的语言上的USAGE特权。

如果这个命令中包括了一个方案名称,则该过程将被创建在该方案中。否则过程将被创建在当前的方案中。新过程的名称不能匹配同一方案中具有相同输入参数类型的任何现有过程或函数。不过,具有不同参数类型的过程和函数可以共享同一个名称(这被称为重载)。

要替换一个已有过程的当前定义,请使用CREATE OR REPLACE PROCEDURE。不能用这种方式更改过程的名称或者参数类型(如果尝试这样做,实际上会创建一个新的、不同的过程)。

CREATE OR REPLACE PROCEDURE被用来替换一个现有的过程时,该过程的拥有关系和权限保持不变。所有其他的过程属性会被赋予这个命令中指定的或者暗示的值。必须拥有(包括成为拥有角色的成员)该过程才能替换它。

创建过程的用户将成为该过程的拥有者。

为了能够创建一个过程,用户必须具有参数类型上的USAGE特权。

有关编写过程的详细信息,请参阅Section 38.4

参数

EDITIONABLE
NONEDITIONABLE

如果为 schema 中的架构对象 PROCEDURE 启用了版本控制,则使用这两个属性可以指定函数是受版本控制的对象还是非受版本控制的对象。

目前只支持语法,未实现功能。

该用法仅支持在oracle兼容模式使用.

name

要创建的过程的名称(可以是被方案限定的)。

argmode

参数的模式可以是:INOUTINOUT或者VARIADIC。 如果省略,则默认为IN

argname

参数的名称。

argtype

过程的参数(如果有)的数据类型(可以是被方案限定的)。参数类型可以是基础类型、组合类型或者域类型,或者可以引用一个表列的类型。在lightdb_oracle_type_date_to_oracle_date中介绍了date类型的使用。

根据具体的实现语言,还可能可以指定伪类型,例如cstring。伪类型表示实际的参数类型没有完全确定,或者是位于普通SQL数据类型的集合之外。

写上table_name.column_name%TYPE可以引用某个列的类型。使用这种特性有时可以让过程不受表定义改变的影响。

default_expr

没有指定参数时要被用作默认值的表达式。这个表达式必须符合该参数的参数类型。在非oracle模式下,跟在有默认值的参数后面的输入参数也都必须有默认值。

lang_name

用于实现该过程的语言名称。它可以是sqlcinternal或者一种用户定义的过程语言的名称,例如plpgsql。 如果指定了sql_body,则默认值为sql。 将名称包裹在单引号内的方式已经被废弃,并且要求大小写匹配。

[EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINER

SECURITY INVOKER指示过程以调用它的用户的特权来执行。这是默认方式。SECURITY DEFINER指定过程以拥有它的用户的特权来执行。

为了符合SQL标注,允许使用EXTERNAL关键词,但它是可选的,因为和SQL中不同,这个特性适用于所有的过程而不仅仅是外部过程。

SECURITY DEFINER过程不能执行事务控制语句(例如COMMITROLLBACK,具体取决于实现的语言)。

configuration_parameter
value

SET子句导致在进入该过程时指定的配置参数被设置为指定的值,并且在过程退出时恢复到之前的值。SET FROM CURRENTCREATE PROCEDURE执行时该参数的当前值保存为在进入该过程时要应用的值。

如果对过程附加一个SET子句,那么在该过程中为同一个变量执行的SET LOCAL命令的效果就被限制于该过程:在过程退出时还是会恢复到该配置参数的以前的值。不过,一个普通的SET命令(没有LOCAL)会重载这个SET子句,很像它对一个之前的SET LOCAL命令所做的事情:这样一个命令的效果将持续到过程退出之后,除非当前事务被回滚。

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

有关允许的参数名和值的更多信息请参考SETChapter 18

definition

一个定义该过程的字符串常量,其含义取决于语言。它可以是一个内部的过程名、一个对象文件的路径、一个SQL命令或者以一种过程语言编写的文本。

在编写过程的定义字符串时,使用美元引用(见Section 5.1.2.4)而不是普通的单引号语法常常会很有帮助。如果没有美元引用,过程定义中的任何单引号或者反斜线必须以双写的方式进行转义。

obj_file, link_symbol

当C语言源码中的过程名与SQL过程的名称不同时,这种形式的AS子句被用于动态可装载的C语言过程。字符串obj_file是包含已编译好的C过程的共享库文件名,并且被按照LOAD命令的方式解析。字符串link_symbol是该过程的链接符号,也就是该过程在C语言源代码中的名称。如果链接符号被省略,则会被假定为与正在被定义的SQL过程的名称相同。

当重复的CREATE PROCEDURE调用引用同一个对象文件时,只会对每一个会话装载该文件一次。要卸载或者重新载入该文件(可能是在开发期间),应该开始一个新的会话。

注解

函数创建也适用于过程,更多细节请参考CREATE FUNCTION

使用CALL来执行过程。

示例

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);

在 oracle 模式下,在有默认值的参数后面的参数不需要有默认值。 pl/sql:

CREATE OR REPLACE PROCEDURE increment(i integer, j integer default 1, k integer, out res integer )
AS $$
        BEGIN
              res = i + j + k;
        END;
$$ LANGUAGE plorasql;

call increment(1,k=>1,res=>null);
 res 
-----
   3
(1 row)

兼容性

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

另见

ALTER PROCEDURE, DROP PROCEDURE, CALL, CREATE FUNCTION