暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

GBase 8a MPP存储过程参考-1

原创 Todd 2022-08-29
964

1.1.1  概述

GBase 8a MPP Cluster的存储过程仍在不断地完善中。本章中所描述的所有语法都被有效地支持,其局限性和扩展要求将被记录备案。

1.1.1.1     存储过程

定义

存储过程是一组可以完成特定功能的SQL语句集,经编译后存储在数据库中。用户在执行存储过程时,需要指定存储过程的名称并给出参数(如果存储过程里包含参数)。

应用场景

在如下情况中,存储过程非常有用:

l  当多个客户端应用程序是由不同的语言编写,或者运行在不同的平台,但需要执行同样的数据库操作时;

l  当安全非常重要时。例如,银行对所有常用的操作都使用存储过程。这提供了一个一致的和安全的环境,并且存储过程可以保证每一个操作都正确的写入日志。如此设置,应用程序和用户将不能直接访问数据表,只能执行特定的存储过程;

l  存储过程可以提高性能,这是因为只需要在服务器和客户端之间传递更少的信息。负面影响是增加了数据库服务器的负担,因为在服务器端执行更多的任务而在客户端(应用程序)则只需执行较少的任务。这在一个或很少的数据库服务器连接有大量客户端(比如Web服务器)的情况下则更明显;

l  存储过程允许用户在数据库服务器中使用函数库。这正是现代应用程序语言具有的特性,例如,通过使用类来进行程序设计。这些客户端应用程序语言特性不论是否应用于数据库端的设计,对程序员来说采用这样的方法还是很有益处的。

说明

GBase 8a MPP Cluster的存储过程遵循SQL:2003标准。

1.1.1.2     函数

GBase 8a MPP Cluster支持函数(FUNCTION)的定义和使用。

1.1.2  创建存储过程、函数

l  存储过程和函数是由CREATE PROCEDURE和CREATE FUNCTION语句所创建的程序;

l  存储过程通过CALL语句来调用程序,而且只能通过输出变量得到返回值。函数可以像其它函数一样从语句内部来调用(通过调用函数名),并返回一个标量值。存储程序(过程和函数)也可以调用其它存储程序(过程和函数);

l  每个存储过程或函数都与一个特定的数据库相联系。当存储程序(过程和函数)被调用时,隐含的USE database_name被执行(当存储程序(过程和函数)结束时完成),不允许在存储程序(过程和函数)中使用USE语句。用户能使用数据库名来限定存储程序(过程和函数)名。这可以用来指明不在当前数据库中的存储程序(过程和函数)。例如,要调用一个与gbase数据库相关联的存储过程p或函数f,用户可以使用CALL gbase.p()或gbase.f()。当一个数据库被删除了,所有与它相关的存储程序(过程和函数)也都被删除了;

l  GBase 8a MPP Cluster允许在存储过程中使用标准的SELECT语句。这样,一个查询的结果简单直接地传送到客户端。多个SELECT语句产生多个结果集,所以客户端必须使用一个支持多结果集的GBase 8a MPP Cluster客户端库;

l  要创建一个存储程序(过程和函数),必须具有CREATE ROUTINE权限,ALTER ROUTINE和EXECUTE权限自动的授予给它的创建者。如果开启更新日志,用户可能需要SUPER权限;

l  在默认情况下,存储程序(过程和函数)与当前的数据库相关联。要显式的将过程与数据库联系起来,那用户创建存储程序(过程和函数)时需要将它的名字的格式写为database_name.sp_name;

l  在括号中必须要有参数列表。如果没有参数,应该使用空的参数列表();默认参数为IN参数。如果要将一个参数指定为其它类型,则请在参数名前使用关键字;

l  使用RETURNS子句(只有FUNCTION才能指定RETURNS子句)指明函数的返回类型时,函数体中必须包含一个RETURN语句;

l  如果一个存储过程或函数对同样的输入参数得到同样的结果,则被认为它是"确定的"(DETERMINISTIC),否则就是"非确定"的(NOT DETERMINISTIC)。默认是NOT DETERMINISTIC;

l  就复制来说,使用NOW()函数(或它的同义字)或RAND()并不会生成一个非确定性程序。对于NOW(),更新日志包括时间戳并能进行正确的复制。如果在一个程序中只调用一次,RAND()也能正确地复制;

l  当前DETERMINISTIC特性是可接受的,但并不被优化器所使用。然而,如果更新日志被激活,这个特性将影响到GBase 8a MPP Cluster是否接受过程的定义;

l  以下几个特征参数提供了程序的数据使用信息:

1. SQL SECURITY参数用来指明,此程序的执行权限是赋予创建者还是调

用者。默认的值是DEFINER。创建者和调用者必须要有对与程序相关的数据库的访问权。要执行存储程序(过程和函数)必须具有EXECUTE权限,必须具有这个权限的用户要么是定义者,要么是调用者,这依赖于如何设置SQLSECURITY特征;

2. COMMENT语句是GBase 8a MPP Cluster的扩展,可以用来描述存储过

程。可以使用SHOW CREATE PROCED URE、SHOW CREATE FUNCTION语句来显示这些信息。

l  GBase 8a MPP Cluster允许存储程序(过程和函数)包含DDL语句(比如CREATE和DROP)和SQL事务语句(比如COMMIT)。这不是标准所需要的,只是特定的实现;

l  返回结果集的语句不能用在函数中。这些语句包括不使用INTO将列值赋给变量的SELECT语句,SHOW语句等。对于在函数定义时就返回结果集的语句返回一个“Not allowed to return a result set from a function”错误(ER_SP_NO_RETSET_IN_FUNC)。对于在函数运行时才返回结果集的语句,返回“PROCEDURE%s can't return a result set in the given context”错误(ER_SP_BADSELECT)。

存储过程语法格式

存储过程语法格式如下示例:

CREATE PROCEDURE <proc_name>([<parameter_1>[,…] [,parameter_n]])

[characteristic ...]

BEGIN

                                 <过程定义>

END

函数语法格式

函数语法格式如下示例:

CREATE FUNCTION <func_name>([<parameter_1>[,…] [,parameter_n]])

RETURNS  type

BEGIN

                                 <函数定义>

END

说明

参数说明

l  <proc_name>、<func_name>要创建的存储过程的名称。在同一数据库内,存储过程的名称必须唯一。存储过程名称只允许a~z、A~Z、0~9、下划线,且不能只包含数字;

l  ([<parameter_1>[,...] [,parameter_n]])定义存储过程的参数,每一个参数的定义格式是:<参数方向><参数名称><参数数据类型>;

l  存储过程的<参数方向>确定参数是输入、输出还是输入输出,只能取IN、OUT、INOUT中的一个。函数的<参数方向>只能是输入IN;

l  <参数名称>在同一个存储过程中必须唯一,只允许a~z、A~Z、0~9、下划线,且不能只包含数字;

l  <参数数据类型>指定参数的数据类型;

l  <过程定义>、<函数定义>是一系列的SQL语句的组合,其中包含一些数据操作以完成一定的功能逻辑;

l  定义存储过程时,存储过程名后面的括号是必需的,即使没有任何参数,也不能省略;

l  如果存储过程、函数中的<过程定义>仅包含一条SQL语句,则可以省略BEGIN和END,否则,在定义存储过程时,必须使用BEGIN...END结构把相关的SQL语句组织在一起形成<过程定义>;

l  存储过程、函数可以嵌套;

l  type是GBase 8a MPP Cluster支持的数据类型。

示例

下面是一个使用IN,OUT参数的简单的存储过程的示例。这个示例在存储过程定义前,使用delimiter命令来把语句定界符从“;”变为“//”。这样就允许用在存储程序体中的“;”定界符传递到服务器,而不是被解释。

示例1

创建proce_count存储过程,并调用。

gbase> DELIMITER //

gbase> CREATE PROCEDURE proc_count (OUT param1 INT,IN param2  VARCHAR(10))

     BEGIN

     SELECT COUNT(*) INTO param1 FROM ssbm.customer WHERE c_nation= param2;

     END //

Query OK, 0 rows affected

 

gbase> CALL proc_count(@count1,'JORDAN')//

Query OK, 0 rows affected

 

gbase> DELIMITER ;

gbase> SELECT @count1;

+---------+

| @count1 |

+---------+

|    1182 |

+---------+

1 row in set

说明

当使用定界符命令时,用户应该避免使用反斜杆(在GBase 8a MPP 

Cluster中表示转义字符)。

示例2

创建含有参数的hello函数,使用SQL函数执行操作并返回结果。

gbase> DELIMITER //

gbase> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)

     RETURN CONCAT('Hello, ',s,'!');//

Query OK, 0 rows affected

 

gbase> DELIMITER ;

gbase> SET @result = hello('world');

Query OK, 0 rows affected

 

gbase> SELECT @result;

+----------------------------------------------------+

| @result                                            |

+----------------------------------------------------+

| Hello, world               !                       |

+----------------------------------------------------+

1 row in set

说明

如果一个函数的RETURN语句返回的值与函数中RETURNS子句指明的值类型不同,返回的值强制为正确的类型。

示例3

创建fn_count函数,过程定义中包含SQL语句。

gbase> DELIMITER //

gbase> CREATE FUNCTION fn_count (param  varchar(10)) RETURNS INT

       BEGIN

       SELECT COUNT(*)/5 INTO @count FROM ssbm.customer WHERE c_nation= param;

       RETURN @count;

       END//

Query OK, 0 rows affected

 

gbase> DELIMITER ;

 

gbase> SET @result = fn_count('JORDAN');

Query OK, 0 rows affected

 

gbase> SELECT @result;

+---------+

| @result |

+---------+

|     236 |

+---------+

1 row in set

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论