返回首页

gbase数据、南大通用产品文档:GBase8s

更新日期:2024年09月11日

GCITransStart
函数原型:
sword
GCITransStart(
GCISvcCtx *svchp,



GCIError *errhp,
uword timeout,
ub4 flags
);
功能描述:
开启事务处理模式
参数说明:
svchp(输入)
要开启事务模式的上下文句柄
errhp(输入)
错误信息句柄,调用该接口失败时将错误码和错误信息写入该句柄。可设置为空
timeout(输入)
保留参数,目前不使用(仅用于和Oracle 保持兼容)
flags(输入)
保留参数,目前不使用(仅用于和Oracle 保持兼容)
返回值:
如果执行成功,则返回GCI_SUCCESS,否则返回GCI_ERROR

功能描述
取消一个先前为两阶段提交准备好的事务。
注意事项
该功能仅在维护模式(GUC 参数xc_maintenance_mode 为on 时)下可用。该模式谨慎打
开,一般供维护人员排查问题使用,一般用户不应使用该模式。
要想回滚一个预备事务,必须是最初发起事务的用户,或者是系统管理员。
事务功能由数据库自动维护,不应显式使用事务功能。
语法格式
ROLLBACK PREPARED transaction_id ;
参数说明

transaction_id
待提交事务的标识符。它不能和任何当前预备事务已经使用了的标识符同名。
相关命令
COMMIT PREPARED,PREPARE TRANSACTION。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1224

当对全文索引所在的表进行DDL 和DML 操作时,全文索引也会做相应的改变。
表5-143 具体见下面对照
索引所在表操作
全文索引对应的影响
索引所在表变更名称
索引会根据新的表名称而改变索引数据目录
名称
索引列被删除
索引跟随删除
列数据更新
更新索引时进行更新
列数据删除
索引不作处理,而依赖GBase UP 原删除机制
屏蔽查询结果

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 958
自定义存储过程和函数
本章主要介绍存储过程和自定义函数的定义和使用。
概述
存储过程
存储过程是一组可以完成特定功能的SQL 语句集,经编译后存储在数据库中。用
户在执行存储过程时,需要指定存储过程的名称并给出参数(如果存储过程里包含
参数)。
在如下情况中,存储过程非常有用:

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

当安全非常重要时。例如,银行对所有常用的操作都使用存储过程。这提供了
一个一致的和安全的环境,
并且存储过程可以保证每一个操作都正确的写入日
志。如此设置,应用程序和用户将不能直接访问数据表,只能执行特定的存储
过程。
存储过程可以提高性能,这是因为只需要在服务器和客户端之间传递更少的信息。
负面影响是增加了数据库服务器的负担,
因为在服务器端执行更多的任务而在客户
端(应用程序)则只需执行较少的任务。这在一个或很少的数据库服务器连接有大
量客户端(比如Web 服务器)的情况下则更明显。
存储过程允许用户在数据库服务器中使用函数库。
这正是现代应用程序语言具有的
特性,例如,通过使用类来进行程序设计。这些客户端应用程序语言特性不论是否
应用于数据库端的设计,对程序员来说采用这样的方法还是很有益处的。
GBase UP 的存储过程遵循SQL:2003 标准。
GBase UP 的存储过程仍在不断地完善中。本章中所描述的所有语法都被有效地支
持,其局限性和扩展要求将被记录备案。
关于存储过程的异常处理方法请参见《GBase UP 存储过程异常处理参考手册》。
函数
GBase UP 支持函数(FUNCTION)的定义和使用,但ORACLE 引擎和HIVE 引擎
不支持。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 959
创建存储过程、函数
存储过程和函数是由CREATE PROCEDURE 和CREATE FUNCTION 语句所创建的
程序。存储过程通过CALL 语句来调用程序,而且只能通过输出变量得到返回值。
函数可以像其它函数一样从语句内部来调用(通过调用函数名),并返回一个标量
值。存储程序(过程和函数)也可以调用其它存储程序(过程和函数)。
每个存储过程或函数都与一个特定的数据库相联系。
当存储程序(过程和函数)被调用时,隐含的USE database_name 被执行(当存储
程序(过程和函数)结束时完成),不允许在存储程序(过程和函数)中使用USE
语句。
用户能使用数据库名来限定存储程序(过程和函数)名。这可以用来指明不在当前
数据库中的存储程序(过程和函数)。例如,要调用一个与gbase 数据库相关联的
存储过程p 或函数f,用户可以使用CALL gbase.p()或gbase.f()。
当一个数据库被删除了,所有与它相关的存储程序(过程和函数)也都被删除了。

GBase UP 允许在存储过程中使用标准的SELECT 语句。这样,一个查询的结果简
单直接地传送到客户端。
多个SELECT 语句产生多个结果集,
所以客户端必须使用
一个支持多结果集的GBase UP 客户端库。
要创建一个存储程序(过程和函数),必须具有CREATE ROUTINE 权限,ALTER
ROUTINE 和EXECUTE 权限自动的授予给它的创建者。如果开启更新日志,用户
可能需要SUPER 权限。
在默认情况下,存储程序(过程和函数)与当前的数据库相关联。要显式的将过程
与数据库联系起来,那用户创建存储程序(过程和函数)时需要将它的名字的格式
写为database_name.sp_name。
在括号中必须要有参数列表。如果没有参数,应该使用空的参数列表()。默认参
数为IN 参数。如果要将一个参数指定为其它类型,则请在参数名前使用关键字。
使用RETURNS 子句(只有FUNCTION 才能指定RETURNS 子句)指明函数的返
回类型时,函数体中必须包含一个RETURN 语句。
如果一个存储过程或函数对同样的输入参数得到同样的结果,则被认为它是"确定
的"(DETERMINISTIC),否则就是"非确定"的(NOT DETERMINISTIC)。默认
是NOT DETERMINISTIC。
就复制来说,使用NOW()函数(或它的同义字)或RAND()并不会生成一个非确定
性程序。
对于NOW(),
更新日志包括时间戳并能进行正确的复制。如果在一个程序
中只调用一次,RAND()也能正确地复制。
当前DETERMINISTIC 特性是可接受的,但并不被优化器所使用。然而,如果更新
日志被激活,这个特性将影响到GBase UP 是否接受过程的定义。
几个特征参数提供了程序的数据使用信息。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 960
SQL SECURITY 参数用来指明,
此程序的执行权限是赋予创建者还是调用者。
默认
的值是DEFINER。创建者和调用者必须要有对与程序相关的数据库的访问权。要
执行存储程序(过程和函数)必须具有EXECUTE 权限,必须具有这个权限的用户
要么是定义者,要么是调用者,这依赖于如何设置SQL SECURITY 特征。
COMMENT 语句是GBase UP 的扩展,可以用来描述存储过程。可以使用SHOW
CREATE PROCEDURE 和SHOW CREATE FUNCTION 语句来显示这些信息。
GBase UP 允许存储程序(过程和函数)包含DDL 语句(比如CREATE 和DROP)
和SQL 事务语句(比如COMMIT)。这不是标准所需要的,只是特定的实现。
返回结果集的语句不能用在函数中。这些语句包括不使用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 ([[,…] [,parameter_n]])
[characteristic ...]
BEGIN

<过程定义>
END
函数语法格式:
CREATE FUNCTION ([[,…] [,parameter_n]])
RETURNS type
BEGIN

<函数定义>
END

参数说明如下:
1)
要创建的存储过程的名称。在同一数据库内,
存储过程的名称必须唯一。存储过程名称只允许a~z、A~Z、0~9、下
划线,且不能只包含数字。
2)
([[,...] [,parameter_n]])定义存储过程的参数,
每一个参数的定
义格式是:
<参数方向><参数名称><参数数据类型>
存储过程的<参数方向>确定参数是输入、输出还是输入输出,只能取IN、
OUT、INOUT 中的一个。函数的<参数方向>只能是输入IN。
<参数名称>在同一个存储过程中必须唯一,只允许a~z、A~Z、0~9、
下划线,且不能只包含数字。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 961
<参数数据类型>指定参数的数据类型。
3)
<过程定义>、<函数定义>是一系列的SQL 语句的组合,其中包含一些数
据操作以完成一定的功能逻辑。
定义存储过程时,存储过程名后面的括号是必需的,即使没有任何参数,
也不能省略。
如果存储过程、函数中的<过程定义>仅包含一条SQL 语句,则可以省略
BEGIN 和END,否则,在定义存储过程时,必须使用BEGIN...END 结构
把相关的SQL 语句组织在一起形成<过程定义>。
存储过程、函数可以嵌套。
type 是GBase UP 支持的数据类型。
下面是一个使用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 UP 中表示转义字
符)。

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

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 962
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

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 963
修改存储过程、函数
语法格式:
ALTER {PROCEDURE | FUNCTION} [characteristic ...]
characteristic:
SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
示例

示例1:修改存储过程的注释信息。
gbase> ALTER PROCEDURE proc_count COMMENT 'new comment';
Query OK, 0 rows affected

示例2:修改函数的注释信息。
gbase> ALTER FUNCTION fn_count COMMENT 'new comment';
Query OK, 0 rows affected
删除存储过程、函数
语法格式:
DROP {PROCEDURE | FUNCTION} [IF EXISTS]
参数说明如下:
要删除的存储过程(函数)的名称。
示例

示例1:删除存储过程。
gbase> DROP PROCEDURE IF EXISTS proc_count;
Query OK, 0 rows affected

示例2:删除函数。
gbase> DROP FUNCTION IF EXISTS fn_count;
Query OK, 0 rows affected
调用存储过程、函数
GBase UP 使用CALL 语句调用存储过程。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 964
语法格式:
CALL [database_name.]proc_name([<参数列表>])
说明:
调用存储过程时,如果存储过程有参数,则必须按照存储过程的定义中的顺序和类
型为参数赋值,
同时,
对于OUT 和INOUT 参数,
必须指明OUT 和INOUT 关键字。

即使存储过程没有任何参数,在调用时也必须在<存储过程名称>后面加上括号。
GBase UP 使用SELECT 语句调用函数。
SET @变量名 = [database_name.]func_name([<参数列表>])
GBase UP 使用SELECT 语句查看调用函数的执行结果。
语法格式:
SELECT @变量名;
示例

示例1:调用存储过程示例。
gbase> USE test;
Query OK, 0 rows affected

gbase> DELIMITER //
gbase> DROP PROCEDURE proc_count//
Query OK, 0 rows affected

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 UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 965

示例2:调用函数示例。
gbase> USE test;
Query OK, 0 rows affected

gbase> DELIMITER //
gbase> DROP FUNCTION hello //
Query OK, 0 rows affected

gbase> CREATE FUNCTION hello (s CHAR(20)) RETURNS VARCHAR(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
查看存储过程、函数的状态
查看创建或修改后的存储过程或函数的状态,可以使用如下语句:
SHOW {PROCEDURE | FUNCTION} STATUS
SHOW CREATE {PROCEDURE | FUNCTION}
示例

示例1:查看fn_count 函数的状态。
gbase> SHOW CREATE FUNCTION fn_count;
+----------+-...-+-----------------------------------+-...-+
| Function | ... | Create Function | ... |
+----------+-...-+-----------------------------------+-...-+
| fn_count | ... | CREATE...FUNCTION"fn_count"...END | ... |
+----------+-...-+-----------------------------------+-...-+
1 row in set
在显示信息中包含6 列,每列的具体信息如下。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 966
1. Function:fn_count
2. sql_mode:
PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_AUTO_VALUE_ON_ZERO,STRICT_ALL_
TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITU
TION,PAD_CHAR_TO_FULL_LENGTH
3. Create Function:CREATE DEFINER="root"@"%" FUNCTION "fn_count"(param
varchar(10)) RETURNS int
BEGIN
SELECT COUNT(*)/5 INTO @count FROM ssbm.customer WHERE c_nation= param;
RETURN @count;
END
4.
character_set_client:utf8
5.
collation_connection:utf8_general_ci
6.
Database Collation:utf8_general_ci
存储过程所支持的流程结构和语句
GBase UP 在存储过程中除支持最基本的结构外,在<过程定义>部分还支持一些用
于实现特定逻辑的流程控制结构和语句,这些结构和语句主要用于实现分支和循
环。
DELIMITER
语法格式:
DELIMITER [Delimiter]
分隔符是通知客户端,已经完成输入一个SQL 语句的字符或字符串符号,通常使
用分号“;”,但在存储过程中,因为其中包含很多语句,每一个都需要一个分号,
因此需要选择不太可能出现在语句中的符号作为分隔符,如“//”。
示例

示例1:使用//作为分隔符。
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS dodeclare //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE dodeclare (p1 INT)
BEGIN
DECLARE intX INT;
SET intX = 0;

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 967
REPEAT SET intX = intX + 1; UNTIL intX > p1 END REPEAT;
SELECT intX;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL dodeclare(1000);
+------+
| intX |
+------+
| 1001 |
+------+
1 row in set
Query OK, 0 rows affected
BEGIN...END
语法格式:
[begin_label:] BEGIN
[statement_list]
END [end_label]
存储程序(过程和函数)可能包含多个语句,这时就使用BEGIN...END 复合语句。

statement_list:表示一个或多个语句的列表。多个语句之间使用分号“;”进行分隔。

复合语句可以被标记。
end_label 只有在begin_label 出现后才能使用,
并且如果两者
都出现,它们必须相同。
要使用多个语句,就需要客户端能发送包含语句分隔符“;”的查询字符串。这可在
客户端通过gbase 命令行使用分隔符更改命令来处理。更改查询结束的分隔符“;”
(比如,改为//),允许“;”用在程序体中。
DECLARE
DECLARE 语句用来定义各种程序的局部项:
局部变量
(参看存储过程中的变量)

条件和处理器(参看条件和处理器)以及游标(参看游标)。目前不支持SIGNAL
和RESIGNAL 语句。
DECLARE 只能被用在BEGIN...END 复合语句之间,且必须位于其它语句之前。
游标必须在声明处理器变量之前被声明,并且条件必须在声明游标或处理器前声
明。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 968
语法格式:
DECLARE var_name[,...] type [DEFAULT value]
这个语句用来声明局部变量。如果要对变量提供一个默认的值,则包括一个
DEFAULT 语句。这个值可以指定为一个表达式,或一个常量。如果DEFAULT 缺
少子句,初始值为NULL。
局部变量的作用范围在它被声明的BEGIN...END 块之间。变量可以在嵌套块中使
用,除非在块中声明了同名的变量。
示例

示例1:
DECLARE intX INT
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS dodeclare //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE dodeclare (p1 INT)
BEGIN
DECLARE intX INT;
SET intX = 0;
REPEAT SET intX = intX + 1; UNTIL intX > p1 END REPEAT;
SELECT intX;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL dodeclare(1000);
+------+
| intX |
+------+
| 1001 |
+------+
1 row in set
Query OK, 0 rows affected
语法格式:
DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
handler_type:
CONTINUE | EXIT | UNDO
condition_value:
SQLSTATE [VALUE] sqlstate_value

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 969
| condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION
| gbase_error_code
这条语句指明了处理程序,它们每个可以作为一个或多个条件来对待。如果这
些条件之一发生了,具体指明的语句就会被执行。
参数说明如下:
对于一个CONTINUE 命令,在处理器语句执行结束后,当前的程序继续执行。
而对于一个EXIT 处理器,当前BEGIN...END 复合语句的执行被终止。
SQLWARNING 是对所有以01 开始的SQLSTATE 代码的速记。
NOT FOUND 是对所有以02 开始的SQLSTATE 代码的速记。
SQLEXCEPTION 是对所有的没有被SQLWARNING 或NOT FOUND 捕获的
SQLSTATE 代码的速记。

示例2:
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS curdemo //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE curdemo()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE cnt INT DEFAULT 0;
DECLARE s_region CHAR(255);
DECLARE stmp CHAR(255) DEFAULT '';
DECLARE cur_region CURSOR FOR SELECT DISTINCT c_region FROM ssbm.customer
ORDER BY c_region LIMIT 1000;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
DROP TABLE IF EXISTS products;
CREATE TABLE products(region CHAR(255),count INT);
OPEN cur_region;
REPEAT
FETCH cur_region INTO s_region;
IF NOT done THEN
IF stmp='' THEN
SET stmp=s_region;
SET cnt=1;
END IF;
IF stmp!=s_region THEN
INSERT INTO products(region,count) VALUES(stmp,cnt);
SET cnt=1;

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 970
SET stmp=s_region;
END IF;
SET cnt=cnt+1;
END IF;
UNTIL done END REPEAT;
CLOSE cur_region;
INSERT INTO products(region,count) VALUES(stmp,cnt);
END//
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL curdemo;
Query OK, 1 row affected

gbase> SELECT region,count FROM products;
+-----------------------------------------------------------+-------+
| region | count |
+-----------------------------------------------------------+-------+
| AFRICA | 2 |
| AMERICA | 2 |
| ASIA | 2 |
| EUROPE | 2 |
| MIDDLE EAST | 2 |
+-----------------------------------------------------------+-------+
5 rows in set
SET
语法格式:
SET var_name = expr [, var_name = expr]
存储过程中的SET 语句是对一般SET 语句的扩展。引用的变量可以是在一个存储
过程或全局服务器变量中声明的。
存储过程中的SET 语句只是已存在的SET 语法的部分实现。这允许扩展语法SET
a=x,b=y,...这里可以混用不同的变量类型(局部变量与全局和会话服务器变量)。
这也允许局部变量和一些对系统变量有意义的选项结合起来,在这种情况下,选项
虽被认出但被忽略掉。
示例

示例:SET intX = 0

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 971
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS dodeclare //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE dodeclare (p1 INT)
BEGIN
DECLARE intX INT;
SET intX = 0;
REPEAT SET intX = intX + 1; UNTIL intX > p1 END REPEAT;
SELECT intX;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;

gbase> CALL dodeclare(1000);
+------+
| intX |
+------+
| 1001 |
+------+
1 row in set
Query OK, 0 rows affected
SELECT...INTO...
语法格式:
SELECT col_name[,...] INTO var_name[,...] table_expr
功能:
将选出的列存储到变量中。只有单一行的结果才可以被取回。
示例

示例1:SELECT intX INTO @intResult;
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS doselect_into //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE doselect_into (p1 INT)
BEGIN
DECLARE intX INT;

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 972
SET intX = 0;
REPEAT SET intX = intX + 1; UNTIL intX > p1 END REPEAT;
SELECT intX INTO @intResult;
SELECT @intResult;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL doselect_into (1000);
+------------+
| @intResult |
+------------+
| 1001 |
+------------+
1 row in set
Query OK, 0 rows affected
IF
GBase UP 的IF 结构是一个简单的条件分支结构。
语法格式:
IF <判断条件> THEN
<执行体>
ELSE
<执行体>
END IF;
GBase UP 的IF 结构允许嵌套。
示例

示例1:IF...THEN...ELSE...END IF
gbase> DELIMITER //
gbase> DROP FUNCTION IF EXISTS fn_count//
Query OK, 0 rows affected

gbase> CREATE FUNCTION fn_count (param VARCHAR(10)) RETURNS INT
BEGIN
SELECT
COUNT(*)/3
INTO
@count
FROM
ssbm.customer
WHERE
c_nation=
'JORDAN';
IF @count<=3 THEN
RETURN @count;
ELSE

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 973
RETURN @count/3;
END IF;
END//
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> SET @result = fn_count ('JORDAN');
Query OK, 0 rows affected

gbase> SELECT @result;
+---------+
| @result |
+---------+
| 131 |
+---------+
1 row in set
ITERATE
ITERATE 语句用于实现回到指定位置重复执行,
该语句只能出现在LOOP、
REPEAT
和WHILE 结构中,并且必须为该语句定义要回到的位置的标签,之后在使用该语
句处指定该标签。
语法格式:
ITERATE<标签名>
ITERATE 语句通常被放在IF 结构中以实现根据条件重复执行。
示例

示例1:ITERATE...
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS doiterate //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE doiterate(p1 INT)
BEGIN
label1: LOOP
SET p1 = p1 + 1;
IF p1 < 10 THEN ITERATE label1; END IF;
LEAVE label1;
END LOOP label1;

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 974
SET @x = p1;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL doiterate(1);
Query OK, 0 rows affected

gbase> SELECT @x;
+------+
| @x |
+------+
| 10 |
+------+
1 row in set
CASE
GBase UP 使用CASE 结构处理多路分支的情况,其语法格式有两种,分别描述如
下:
CASE
WHEN <条件1> THEN <执行语句1>
WHEN <条件2> THEN <执行语句2>
...
ELSE <执行语句X>
END CASE;
当<条件1>为真值时,<执行语句1>;当<条件2>为真值时,<执行语句2>;如果
没有匹配的结果值,那么返回ELSE 后的<执行语句X>。
CASE <判定条件>
WHEN <值1> THEN <执行语句1>
WHEN <值2> THEN <执行语句2>
...
ELSE <执行语句X>
END CASE;
计算<判定条件>,如果<判定条件>的值等于<值1>,<执行语句1>;如果<判定条
件>的值等于<值2>,<执行语句2>;如果没有相匹配的值则执行<执行语句X>。
示例

示例1:CASE 后无判定条件。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 975
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS casedemo//
Query OK, 0 rows affected

gbase> CREATE PROCEDURE casedemo()
-> BEGIN
-> SELECT DISTINCT CASE WHEN c_nation='CHINA' THEN '中国' WHEN
c_nation='MOROCCO' THEN '摩洛哥' WHEN c_nation='JORDAN' THEN '约旦' ELSE '其它
国家' END 中文,c_nation FROM ssbm.customer LIMIT 10;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL casedemo();
+-------------------+
| 中文,c_nation |
+-------------------+
| 中国 |
| 摩洛哥 |
| 约旦 |
| 其它国家 |
+-------------------+
4 rows in set

Query OK, 0 rows affected


示例2:CASE 后有判定条件。
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS casedemo2//
Query OK, 0 rows affected

gbase> CREATE PROCEDURE casedemo2()
BEGIN
SELECT DISTINCT CASE c_nation WHEN 'CHINA' THEN '中国' WHEN 'MOROCCO' THEN
'摩洛哥' WHEN 'JORDAN' THEN '约旦' ELSE '其它国家' END 中文,c_nation FROM
ssbm.customer LIMIT 10;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL casedemo2();
+-------------------+
| 中文,c_nation |

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 976
+-------------------+
| 中国 |
| 摩洛哥 |
| 约旦 |
| 其它国家 |
+-------------------+
4 rows in set

Query OK, 0 rows affected
LOOP
LOOP 结构是GBase UP 中的一个简单的循环结构,用于重复执行一个或者一组语
句。这个循环结构在形式上是个死循环结构,因此在执行体中通常要包括一个条件
判断语句和LEAVE 语句用于退出循环。
语法格式:
LOOP
<执行体>
END LOOP;
示例

示例1:LOOP...END LOOP
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS doiterate//
Query OK, 0 rows affected

gbase> CREATE PROCEDURE doiterate(p1 INT)
BEGIN
label1: LOOP
SET p1 = p1 + 1;
IF p1 < 10 THEN ITERATE label1; END IF;
LEAVE label1;
END LOOP label1;
SET @x = p1;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL doiterate(1);
Query OK, 0 rows affected

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 977

gbase> SELECT @x;
+------+
| @x |
+------+
| 10 |
+------+
1 row in set
REPEAT
REPEAT 结构是GBase UP 中比较常见的一种循环结构,该结构会重复执行执行体
直到满足退出条件。
语法格式:
REPEAT
<执行体>
UNTIL<退出条件>
END REPEAT;
REPEAT 结构的执行体至少会执行一次,如果不允许这样可以使用WHILE 结构代
替。
示例

示例1:REPEAT...UNTIL...END REPEAT
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS dorepeat//
Query OK, 0 rows affected

gbase> CREATE PROCEDURE dorepeat(p1 INT)
BEGIN
SET @x = 0;
REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL dorepeat(1000);
Query OK, 0 rows affected

gbase> SELECT @x;

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 978
+------+
| @x |
+------+
| 1001 |
+------+
1 row in set
WHILE
WHILE 是GBase UP 中另一种常见的循环结构,
在满足执行条件时该结构会重复执
行执行体。
语法格式:
WHILE <执行条件> DO
<执行体>
END WHILE;
WHILE 结构在逻辑上与REPEAT 一致,唯一不同的是until 结构中的执行体至少会
执行一次,而WHILE 结构中的执行体则可能一次也不执行。
示例

示例1:WHILE...END WHILE
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS doWhile//
Query OK, 0 rows affected

gbase> CREATE PROCEDURE doWhile(p1 INT)
BEGIN
SET @x = 0;
WHILE @x < p1 DO SET @x = @x + 1; END WHILE;
END//
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL dowhile(1000);
Query OK, 0 rows affected

gbase> SELECT @x;
+------+
| @x |
+------+

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 979
| 1000 |
+------+
1 row in set
LEAVE
GBase UP 中的LEAVE 语句用于退出循环结构,因此该语句也只能出现在LOOP、
REPEAT 和WHILE 结构中。
同样的,
在使用LEAVE 语句时必须为包含该语句的循
环结构定义标签,然后在使用该语句处指定该标签。
语法格式:
LEAVE <标签名>
LEAVE 语句通常被放在IF 结构中以实现根据条件退出循环结构。
示例

示例1:LEAVE...
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS doiterate //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE doiterate(p1 INT)
BEGIN
label1: LOOP
SET p1 = p1 + 1;
IF p1 < 10 THEN ITERATE label1; END IF;
LEAVE label1;
END LOOP label1;
SET @x = p1;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL doiterate(1);
Query OK, 0 rows affected

gbase> SELECT @x;
+------+
| @x |
+------+
| 10 |
+------+

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 980
1 row in set
静态游标(CURSOR)
由SELECT 语句返回的结果集通常包括一系列的记录行,
但经常有一些情况下,

不总是能够将整个结果集作为一个单元来有效地处理。
这时就需要一种机制以便每
次处理一行记录,数据库中的游标就提供了这种机制。由于游标的意义,大多数的
数据库都支持游标。GBase UP 数据库也支持游标,但游标的定义和使用有一定的
限制。
本节中描述的游标为静态游标,
即在DECLARE 时必须指定SELECT STATEMENT
语句的结果集进行绑定;
在后续操作中只能对于该结果集进行只读、
仅向前的操作。

对于动态游标的定义及使用,请参见“5.5.7.14 动态游标(REF CURSOR)”。
游标必须在声明处理器之前被声明,
变量和条件必须在声明游标或处理器之前被声
明。
示例

示例1:静态游标完整示例。
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS curdemo //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE curdemo()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE cnt INT DEFAULT 0;
DECLARE s_region CHAR(255);
DECLARE stmp CHAR(255) DEFAULT '';
DECLARE cur_region CURSOR FOR SELECT DISTINCT c_region FROM ssbm.customer
ORDER BY c_region LIMIT 1000;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
DROP TABLE IF EXISTS products;
CREATE TABLE products(region CHAR(255),count INT);
OPEN cur_region;
REPEAT
FETCH cur_region INTO s_region;
IF NOT done THEN
IF stmp='' THEN
SET stmp=s_region;
SET cnt=1;

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 981
END IF;
IF stmp!=s_region THEN
INSERT INTO products(region,count) VALUES(stmp,cnt);
SET cnt=1;
SET stmp=s_region;
END IF;
SET cnt=cnt+1;
END IF;
UNTIL done END REPEAT;
CLOSE cur_region;
INSERT INTO products(region,count) VALUES(stmp,cnt);
END//
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL curdemo;
Query OK, 1 row affected

gbase> SELECT region,count FROM products;
+------------------------------------------------------------+-------+
| region | count |
+------------------------------------------------------------+-------+
| AFRICA | 2 |
| AMERICA | 2 |
| ASIA | 2 |
| EUROPE | 2 |
| MIDDLE EAST | 2 |
+------------------------------------------------------------+-------+
5 rows in set

游标的定义
GBase UP 中使用DECLARE 定义游标,标注的主体一定是一个SELECT 语句。
可以在一个程序中定义多个游标,但是每个块中的游标只能有唯一的名字。
SELECT 语句不能包含有INTO 子句。
语法格式:
DECLARE <游标名称> CURSOR FOR 游标的内容,可以是任何合法的SELECT 语句。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 982
示例

示例:
DECLARE cur CURSOR FOR SELECT DISTINCT lo_orderkey FROM ssbm.lineorder ORDER BY
lo_orderkey LIMIT 10;

打开游标
和其它数据库中使用游标的方式一样,
在使用GBase UP 的游标前也需要使用OPEN
语句打开游标。
语法格式:
OPEN <游标名称>
示例

示例:以下代码是包含在游标代码块中的。
DECLARE cur CURSOR FOR SELECT DISTINCT c_region,1 FROM ssbm.customer ORDER BY
c_region LIMIT 1000;
OPEN cur;

从游标中取得数据
使用游标的目的是为了取得游标定义中的SELECT 语句所返回的结果集中的字段
的值,在GBase UP 中,这一取值的过程也是通过FETCH 语句实现的。
语法格式:
FETCH <游标名称> INTO <局部变量>
参数说明如下:
<游标名称>前面定义的游标的名称,需要从该游标中取得返回值
<局部变量>从游标中取得的值要保存在这些局部变量中,FETCH 语句中要求局部
变量的数量与游标定义语句中SELECT 语句中的选择列表中的字段数量相同,
且数
据类型也要对应相同或者可以进行自动转换。
这些局部变量会在后续的语句中进行
处理。
示例

示例:以下代码是包含在游标代码块中的。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 983
DECLARE s_region CHAR(16);
DECLARE region INT;
DECLARE cur CURSOR FOR SELECT DISTINCT c_region,1 FROM ssbm.customer ORDER BY
c_region LIMIT 1000;
OPEN cur;
FETCH cur INTO s_region, region;//

关闭游标
游标在使用完成后需要关闭,否则游标所占用的服务器的资源不会被释放。
如果没有明确的关闭,游标则在声明它的复合语句结束处被关闭。
语法格式:
CLOSE <游标名称>
示例

示例:以下代码是包含在游标代码块中的。
DECLARE s_region CHAR(16);
DECLARE region INT;
DECLARE cur CURSOR FOR SELECT DISTINCT c_region,1 FROM ssbm.customer ORDER BY
c_region LIMIT 1000;
OPEN cur;
FETCH cur INTO s_region, region;
CLOSE cur;//

静态游标使用注意事项
GBase UP 中的游标是一种只读、仅向前的游标。游标中包含的数据是不能在使用
时被更改的,并且游标中的数据只能按照从头至尾的顺序来读取。
GBase UP 中的游标需要配合处理器(handler)来使用,游标需要在处理器的声明
语句之前被声明,而且,任何游标内使用的变量都需要在游标的声明语句之前被定
义。
在使用游标处理数据时,通常会使用LOOP、REPEAT 或者WHILE 结构,并在这
些结构的执行体中使用FETCH 语句来遍历游标中的数据。
在GBase UP 中,同一个存储过程中可声明多个游标,但有以下限制:
多个游标不能嵌套,也不能相互交叉,最好是使用完一个再使用另外一个。
在同一个存储过程中只能定义一个处理器,这一个处理器会作用于所有的游标,因
此,如果两个游标在流程上并列执行时会变得不甚合理。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 984
如果使用了LOOP、REPEAT 或者WHILE 结构来遍历游标取得数据并进行处理,
同时如果在这些循环结构的结构体中调用了存储过程,
则被调用的存储过程中不应
该再包含游标和用于遍历游标的LOOP、REPEAT 或者WHILE 结构,否则可能会
出现一些不可预期的结果。

游标示例
gbase> DELIMITER //
gbase> DROP PROCEDURE IF EXISTS docursor //
Query OK, 0 rows affected

gbase> CREATE PROCEDURE docursor()
BEGIN
DECLARE s_region VARCHAR(40);
DECLARE DONE INT DEFAULT(0);
DECLARE cur CURSOR FOR SELECT DISTINCT c_region FROM
ssbm.customer ORDER BY c_region LIMIT 6;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur;
REPEAT
FETCH cur INTO s_region;
IF NOT done THEN
SELECT s_region;
END IF;
UNTIL DONE END REPEAT;
CLOSE cur;
END //
Query OK, 0 rows affected

gbase> DELIMITER ;
gbase> CALL docursor();
+----------+
| s_region |
+----------+
| AFRICA |
+----------+
1 row in set

+----------+
| s_region |
+----------+
| AMERICA |
+----------+
1 row in set

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 985

+----------+
| s_region |
+----------+
| ASIA |
+----------+
1 row in set

+----------+
| s_region |
+----------+
| EUROPE |
+----------+
1 row in set

+-------------+
| s_region |
+-------------+
| MIDDLE EAST |
+-------------+
1 row in set

Query OK, 0 rows affected
动态游标(REF CURSOR)
GBase UP 支持动态游标的定义和使用。
作为静态游标的加强,在DECLARE 时使用REF CURSOR 声明为动态游标后,允
许在OPEN 时可多次绑定不同SELECT STATEMENT 语句的结果集。

游标的定义
语法格式:
DECLARE <游标名称> REF CURSOR
参数说明如下:
DECLARE:使用DECLARE 定义动态游标时,不允许指定任何SELECT 语句。
<游标名称>:要创建的游标的名称,只允许a~z、A~Z、0~9、下划线,且不能
只包含数字。
REF CURSOR:表示该游标为动态游标。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 986
示例

示例:
DECLARE cur REF CURSOR;

打开游标
和静态游标的使用方式一样,在使用动态游标前也需要使用OPEN 语句打开游标。

语法格式:
OPEN <游标名称> FOR :游标的内容,可以是任何合法的SELECT 语句,也可以是动态
SQL 语句。
示例

示例:以下代码是包含在游标代码块中的。
DECLARE cur REF CURSOR;
OPEN
cur
FOR
SELECT
DISTINCT
c_region,1
FROM
ssbm.customer
ORDER
BY
c_region
LIMIT
1000;

从游标中取得数据
通过FETCH 语句,可取得动态游标OPEN 语句中的SELECT 语句返回的结果集中
的字段的值。
语法格式:
FETCH <游标名称> INTO <局部变量>
参数说明如下:
<游标名称>通过OPEN 打开的游标的名称。
<局部变量>从游标中取得的值要保存在这些局部变量中,FETCH 语句中要求局部
变量的数量与动态游标OPEN语句中的SELECT语句中的选择列表中的字段数量相
同,且数据类型也要对应相同或者可以进行自动转换。
示例

示例:以下代码是包含在游标代码块中的。

GBase UP 产品手册 5 数据库管理指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 987
DECLARE s_region CHAR(16);
DECLARE region INT;
DECLARE cur REF CURSOR;
OPEN
cur
FOR
SELECT
DISTINCT
c_region,1
FROM
ssbm.customer ORDER
BY
c_region
LIMIT
1000;
FETCH cur INTO s_region, region;//

关闭游标
游标在使用完成后需要关闭,否则游标所占用的服务器的资源不会被释放。
如果没有明确的关闭,游标则在声明它的复合语句结束处被关闭。
语法格式:
CLOSE <游标名称>
示例

示例:以下代码是包含在游标代码块中的。
DECLARE s_region CHAR(16);
DECLARE region INT;
DECLARE cur REF CURSOR;
OPEN
cur
FOR
SELECT
DISTINCT
c_region,1
FROM
ssbm.customer ORDER
BY
c_region
LIMIT
1000;
FETCH cur INTO s_region, region;//
CLOSE cur;//

动态游标中使用的动态SQL 语法