返回首页

gbase数据、南大通用产品文档:GBase8sDECLARE 语句

更新日期:2024年09月11日

使用动态 SQL 的 DECLARE 语句声明游标,并将它与一个向 GBase 8s ESQL/C
或 SPL 例程返回一组行的 SQL 语句相关联。
语法

FOR UPDATE 或 FOR READ ONLY Select 选项

其它 Select 或 Function 选项

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 518

元素
描述
限制
语法
column
要使用游标更新的

必须存在,但不需要
列在 Projection 子
句的 Select 列表中
标识符
cursor_id
此处为游标声明的
名称
在游标的名称以及准
备好的对象的名称中
(在 SPL 中是变量)
必须唯一
标识符
cursor_id_var
持有 cursor_id
的变量
必须有一个字符数据
类型
特定于语

statement_id
准备好的语句的名

在 PREPARE 语句中声

标识符
statement_id_var
持有
statement_id 的
变量
必须有一个字符数据
类型
特定于语

用法
正如所指出的除外,下节描述了在 GBase 8s ESQL/C 例程中如何使用 DECLARE
语句。有关 SPL 例程中 DECLARE 语句的语法和语义更多的限制,请参阅在
SPL 例程中声明动态游标。
游标是一个与一组行相关联的标识符。DECLARE 语句将游标与以下一个数据库对
象相关联:

使用一个 SQL 语句,例如 SELECT 、EXECUTE FUNCTION(或
EXECUTE PROCEDURE)或 INSERT。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 519
这些 SQL 语句中的每一个会创建一个不同类型的游标。有关更多信息,
请参阅游标类型的概述。

使用准备好的语句的语句标识符(statement id 或 statement id variable)
您可以准备一个先前的 SQL 语句,并将该准备好的语句与游标相关联。
有关更多信息,请参阅将游标与准备好的语句相关联。

使用 GBase 8s ESQL/C 程序中的集合变量
集合变量的名称出现在 SELECT 的 FROM 子句或 INSERT 的 INTO
子句。有关更多信息,请参阅将游标与准备好的语句相关联。
DECLARE 分配一个标识符给游标,指定它的用法并指示 GBase 8s ESQL/C 预处
理器为它分配存储器。在程序执行期间,DECLARE 必须在任何其它引用该游标
的语句之前执行。
在单个程序中可以共同存在的游标和准备好的对象的数目由可用的内存限制。要
避免超出限制,可使用 FREE 语句释放一些准备好的语句或游标。
ESQL/C 程序可以由一个或多个源代码文件组成。在缺省情况下,因为引用游标
的作用域是全局到程序,所以在一个源文件中声明的游标可以被另一个文件中语
句引用。在多文件程序中,如果希望将游标名称的作用域限制到声明这些游标名
称的文件,则必须使用 -local 命令行选项预先处理所有文件。
可以为同一个准备好的语句标识符声明多个游标。例如,下面的 GBase 8s
ESQL/C 示例不会返回错误:

EXEC SQL prepare id1 from 'select * from customer';

EXEC SQL declare x cursor for id1;

EXEC SQL declare y scroll cursor for id1;

EXEC SQL declare z cursor with hold for id1;
如果包含 -ansi 编辑标志(或者如果设置了 DBANSIWARN ),那么会针对使
用动态游标名称或动态语句标识符的语句生成警告。一些错误检查会在运行时执
行,如以下这些典型检查:

将顺序游标作为滚动游标无效的使用

使用未声明的游标

无效的游标名称或语句名称(空)

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 520
建档游标或语句作为标识符指定时,会在编译的时候执行对同一名称的一个游标
的多个声明的检查。下面示例使用主变量存储游标名称:
EXEC SQL declare x cursor for select * from customer;
. . .
stcopy("x", s);
EXEC SQL declare :s cursor for select * from customer;
游标使用排列顺序,该顺序在游标被声明时是有效的,即使这不同于运行时会话
的排列顺序。
游标类型的概述
在典型情况下,对多行数据(或对 GBase 8s ESQL/C 集合变量)的数据操纵语言
(DML)操作需要游标。您可以使用 DECLARE 语句声明一下类型的游标:

Select 游标是与 SELECT 语句相关联的游标。

函数游标是与 EXECUTE FUNCTION (或 EXECUTE PROCEDURE)
语句相关联的游标。

Insert 游标是与 INSERT 语句相关联的游标。
后面的章节描述了这些游标的类型中的每一中类型。游标也可以有顺序、滚动和
控制特征(但是 Insert 游标不可是一个滚动游标)。这些特征确定了游标的结
构;请参阅 游标特性。此外,Select 游标或函数游标可以指定只读或更新方式。
有关更多信息,请参阅Select 游标或 Function 游标。
提示: 函数游标的行为与作为更新游标启用的 Select 游标相同。
除了将游标直接与 SQL 语句的内容相关联,DECLARE 语句的 FOR 关键字可
以紧跟在准备好的 SQL 语句的标识符后面,并将此游标与动态准备好的
INSERT 、SELECT 、EXECUTE FUNCTION(或 EXECUTE PROCEDURE)语
句的结果集相关联。该功能可以使您在不同时刻将不同的语句与同一个游标使
用。在这种情况下,游标的类型取决于打开游标时 statement_id 或 statement_id
变量指定的准备好的语句。(有关更多信息,请参阅将游标与准备好的语句相关
联。)
Select 游标或 Function 游标
当 SQL 语句将多组值返回到一个 GBase 8s ESQL/C 程序中时,必须声明一个游
标以保存多组或行数据并且以一次访问一行的方式访问这些行。您必须将以下
SQL 语句与游标相关联:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 521

如果将 SELECT 语句与游标相关联,则该游标称为 Select 游标。
Select 游标是一个数据结构,代表 SELECT 语句检索到行的活动集合内
特定位置。

如果将 EXECUTE FUNCTION(或者 EXECUTE PROCEDURE)语句与
游标相关联,则该游标称为函数游标。
函数游标代表用户定义的函数返回的列或值。函数游标的行为与作为更新
游标启用的 Select 游标相同。
在 GBase 8s 中,对于后向兼容性,如果一个 SPL 函数是使用 CREATE
PROCEDURE 语句创建的,那么可以使用 EXECUTE PROCEDURE 语句创建一
个函数游标。对于外部函数,必须使用 EXECUTE PROCEDURE 语句。
当您将 SELECT 或 EXECUTE FUNCTION (或 EXECUTE PROCEDURE)语
句与一个游标相关联时,该语句可以包括 INTO 子句。但是,如果准备 SELECT
或 EXECUTE FUNCTION(或 EXECUTE PROCEDURE)语句,您必须省略
PREPARE 语句中的 INTO 子句并使用 FETCH 语句的 INTO 子句从集合游标
检索值。
Select 或函数游标可以扫描返回的数据行,并逐行数据移动到接收变量的集合
中,如下面的步骤所述:
1.
DECLARE
使用 DECLARE 定义一个游标并将它与一个语句相关联。
2.
OPEN
使用 OPEN 打开该游标。数据库服务器处理查询,直到它定位或构造活
动集的第一行。
3.
FETCH
使用 FETCH 从游标检索连续行的数据。
4.
CLOSE
使用 CLOSE 在不再需要游标的活动集时关闭游标。
5.
FREE

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 522
使用 FREE 释放为游标分配的资源。
使用 FOR READ ONLY 选项
使用 FOR READ ONLY 关键字可将游标定义为只读游标。声明为只读的游标不
可以用于更新(或删除)任何它得到的行。
对 FOR READ ONLY 关键字的需要取决于数据库是符合 ANSI 的还是不符合
ANSI 。
因为在不兼容 ANSI 的数据库中,DECLARE 语句定义的游标在缺省情况下是只
读游标,所以如果想将游标成为一个只读游标,您不需要指定 FOR READ ONLY
关键字。显式地指定 FOR READ ONLY 关键字的唯一好处是为了更好地编制程
序文档。
在兼容 ANSI 的数据库中,如果 SELECT 语句符合与游标相关联的 SELECT 语
句的子集 中列出的对更新游标的所有限制,那么通过 DECLARE 语句与
SELECT 语句相关联的游标在缺省情况下是一个更新游标。如果想让一个 Select
游标成为只读,则必须在声明该游标时使用 FOR READ ONLY 关键字。
数据库服务器可以针对只读游标使用比针对更新游标更为宽松的锁定。
下面的示例创建了一个只读游标:
EXEC SQL declare z_curs cursor for
select * from customer_ansi
for read only;
使用 FOR UPDATE 选项
使用 FOR UPDATE 选项可声明更新游标。您可以使用更新游标修改(更新或删
除)当前的行。
在兼容 ANSI 的数据库中,如果一个 Select 游标不是使用 FOR READ ONLY 关
键字声明的,并且该游标遵守在与游标相关联的 SELECT 语句的子集中描述的对
更新游标的限制,那么可以使用该 Select 游标更新或删除数据。在声明游标时不
需要使用 FOR UPDATE 关键字。
下面的示例声明一个更新游标:
EXEC SQL declare new_curs cursor for

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 523
select * from customer_notansi
for update;
在更新游标中,可以更新或是删除活动集中的行。在创建更新游标之后,可以通
过使用带 WHERE CURRENT OF 子句的 UPDATE 或 DELETE 语句更新或删除
当前选择的行。单词 CURRENT OF 是指最近取得的行;它们替代 WHERE 子句
中通常的测试表达式。
更新游标能让您执行使用 UPDATE 语句不可能实现的更新操作,因为做出更新
的决定以及新数据项的值取决于行的原始内容。您的程序可以在决定是否更新之
前评估或操纵选择的数据。UPDATE 语句无法询问正在更新的表。
您可以指定那些可以被更新的特殊列。这些列不需要出现在 Projection 子句的
Select 列表中。
连同列的列表使用 FOR UPDATE
当声明更新游标时,您可以通过包含 OF 关键字和列的列表将更新操作限制在特
定的列。您只可以修改随后 UPDATE 语句中的那些命名的列。列不需要在
SELECT 子句的选择列表中。
下一个示例声明了一个更新游标,并指定该游标只可以更新 customer_notansi
表中的 fname 和 lname 列:
EXEC SQL declare name_curs cursor for
select * from customer_notansi
for update of fname, lname;
缺省情况下,除非声明为 FOR READ ONLY ,否则在兼容 ANSI 的数据库中的
Select 游标是一个更新游标,因此 FOR UPDATE 关键字是可选的。但是,如果
希望更新游标只能够修改表中的一些列,则必须在 FOR UPDATE OF column 列
表中指定这些列。
指定列的主要好处是便于文档的编制并防止编程出错。(数据库服务器拒绝更新
任何其它列。)另一个好处是在 SELECT 语句满足以下条件时性能得到增强:

可以使用索引处理 SELECT 语句。

列出的列不是用于处理 SELECT 语句的索引的一部分。
如果打算更新的列是用于处理 SELECT 语句的索引的一部分,则数据库服务器会
保留一个列表,其中列有每个更新的行,从而确保没有任何行被更新两次。如果

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 524
OF 关键字指定了可以更新的列,则数据库服务器便会确定是否要保留更新行的
列表。如果数据库服务器确定保留该列表的工作已不再需要,则性能随之提高。
如果不使用 OF column 列表,数据库服务器通常会维护一个更新行的列表,尽管
此列表可能并不需要。
下面的示例包含将更新游标同 DELETE 语句使用删除当前行的 GBase 8s
ESQL/C 代码。
每当删除行时,游标仍处于行之间。在删除数据之后,必须在可以引用 DELETE
或 UPDATE 语句中的游标之前使用 FETCH 语句将游标推进到下一行。
EXEC SQL declare q_curs cursor for
select * from customer where lname matches :last_name for update;

EXEC SQL open q_curs;
for (;;)
{
EXEC SQL fetch q_curs into :cust_rec;
if (strncmp(SQLSTATE, "00", 2) != 0)
break;

/* Display customer values and prompt for answer */
printf("\n%s %s", cust_rec.fname, cust_rec.lname);
printf("\nDelete this customer? ");
scanf("%s", answer);

if (answer[0] == 'y')
EXEC SQL delete from customer where current of q_curs;
if (strncmp(SQLSTATE, "00", 2) != 0)
break;
}
printf("\n");
EXEC SQL close q_curs;
使用 Update 游标进行锁定
FOR UPDATE 关键字告知数据库服务器更新操作是可能的,并会引发数据库服务
器使用比对 Select 游标更严格的锁定。您声明一个更新游标可让数据库服务器知
道程序可能更新(或删除)它取得的作为 SELECT 语句一部分的任何行,更新游

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 525
标为程序取得的行使用可升级锁定(也称写锁)。在程序修改行之前,会将行锁
提升为互斥锁。
使用 WITH HOLD 关键字声明一个更新游标是可能的,但是这样做的唯一原因是
将一长串的更新打断成较小的事务。您必须在同一个事务中取得并更新特定的
行。
如果操作涉及取和更新大量的行,则数据库服务器维护的锁表会溢出。防止这种
溢出的通常方式是锁定整个正在更新的表。如果此操作是不可能的,那么一种替
换的方式是通过 Hold 游标来更新,并按时间间隔执行 COMMIT WORK 。但是,
您必须谨慎地计划这样的应用程序,因为 COMMIT WORK 会释放所有的锁,甚
至是那些通过 Hold 游标放置的锁。
与顺序游标相关联的 INSERT 语句的子集
如 DECLARE 语句的程序中所述,要创建一个 Insert 游标,应将顺序游标与
INSERT 语句的限制格式相关联。INSERT 语句必须包括 VALUES 子句;它不
可以包含嵌入的 SELECT 语句。
下面的示例包含声明 Insert 游标的 GBase 8s ESQL/C 代码:
EXEC SQL declare ins_cur cursor for
insert into stock values
(:stock_no,:manu_code,:descr,:u_price,:unit,:u_desc);
Insert 游标简单地插入数据行;它不可以用于取得数据。当打开 Insert 游标时,
会在内存中创建一个缓冲区。该缓冲区在程序执行 PUT 语句时接收数据行。只
有在缓冲区满的时候才会将这些行写入磁盘。您可以在缓冲区还未满时使用
CLOSE 、FLUSH 或 COMMIT WORK 语句刷新缓冲区(即将它的内容写入数据
库)。该主题会在 CLOSE 、FLUSH 和 PUT 语句下做进一步讨论。
您必须在程序结束之前关闭 Insert 游标,从而将任何已缓冲的行插入数据库。如
果没有正确关闭游标,则会丢失数据。有关对 INSERT 语法和使用的完整讨论,
请参阅 INSERT 语句。
Insert 游标
当您将 INSERT 语句与一个游标相关联的时候,该游标称为 Insert 游标。Insert
游标是一个数据结构,它代表 INSERT 语句将要添加到数据库的行。INSERT 游

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 526
标简单地插入数据行;它不可以用于取得数据。要创建 Insert 游标,应将一个游
标与 INSERT 语句的限制格式相关联。INSERT 语句必须包括 VALUES 子句;
它不可以包含嵌入的 SELECT 语句。
如果想要在 INSERT 操作中将多个行添加到数据库,应创建一个 Insert 游标。
Insert 游标允许将大量的插入数据缓存到内存中,并在缓冲区满的时候写入磁
盘,具体如以下这些步骤所述:
1. 使用 DECLARE 可为 INSERT 语句定义一个 Insert 游标。
2. 使用 OPEN 语句打开游标。数据库服务器会在内存中创建缓冲区。并将
游标的位置确定在插入缓冲区的第一行。
3. 使用 PUT 语句将连续的数据行复制到插入缓冲区。
4. 数据库服务器只有在缓冲区满的时候才会将这些行写到磁盘。您可以在缓
冲区还未满的时候使用 CLOSE 、FLUSH 或 COMMIT WORK 语句刷新
缓冲区。该主题会在 PUT 和 CLOSE 语句下做进一步讨论。
5. 当不再需要 Insert 游标时使用 CLOSE 语句关闭游标。您必须在查询结
束之前关闭Insert 游标,从而将任何已缓冲的行插入数据库。如果没有正
确关闭游标,则会丢失数据。
6. 使用 FREE 语句释放游标。FREE 语句会释放为 Insert 游标分配的资
源。
使用 Insert 游标比直接嵌入 INSERT 语句更有效。此进程减少了程序和数据库
服务器之间的通信,也加快了插入的速度。
Insert 游标还具有顺序游标特征。要创建 Insert 游标,可将一个顺序游标与
INSERT 语句额限制格式相关联。(有关更多信息,请参阅 Insert 语句。)以下
示例包含声明顺序 Insert 游标的 GBase 8s ESQL/C 代码:
EXEC SQL declare ins_cur cursor for
insert into stock values (:stock_no,:manu_code,:descr,:u_price,:unit,:u_desc);

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 527
游标特性
您可以将一个游标声明为顺序游标(缺省值)、滚动游标(通过使用 SCROLL
关键字)或保持游标(通过使用 WITH HOLD 关键字)。SCROLL 和 WITH
HOLD 关键字并不互相排斥。后面的章节解释了这些结构特征。
Select 或 Function 游标可以是一个顺序游标或滚动游标。Insert 游标只可以是一
个顺序游标。在 ESQL/C 例程中,选择游标、函数游标和 Insert 游标可以有选择
地成为保持游标。(在 SPL 例程中,所有的游标都是顺序游标,但是只有 Select
游标可以是保持游标。)
缺省创建顺序游标
如果只使用 CURSOR 关键字,则会创建一个顺序游标,它只可以从活动集合按
顺序取得下一行。每次打开顺序游标时,顺序游标只可以从活动集合读一次。
如果正在为一个 Select 游标使用顺序游标,则在每次执行 FETCH 语句时,数据
库服务器会返回当前行的内容,并且找到活动集合中的下一行。
以下示例在一个不兼容 ANSI 的数据库中创建了一个只读顺序游标,在一个兼容
ANSI 的数据库汇总创建了一个更新顺序游标:
EXEC SQL declare s_cur cursor for
select fname, lname into :st_fname, :st_lname
from orders where customer_num = 114;
Insert 游标也具有顺序游标的特征。要创建一个 Insert 游标,请将顺序游标与
INSERT 语句的限制格式相关联。(有关更多信息,请参阅 Insert 游标。)以下
示例声明了一个 Insert 游标:
EXEC SQL declare ins_cur cursor for
insert into stock values
(:stock_no,:manu_code,:descr,:u_price,:unit,:u_desc);
使用 SCROLL 关键字创建滚动游标
使用 SCROLL 关键字创建滚动游标,它可以任何顺序取活动集合的行。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 528
数据库服务器将游标的活动集合保留为一个临时表,直到关闭游标。您可以取得
活动集合的第一行、最后一行或任何一个中间行,以及在不必关闭再重新打开游
标的情况下重复取得一些行。(请参阅 FETCH。)
多用户系统中,在派生出活动集合的行的表中的行可能在打开游标之后有所更
改,并且会在临时表中生成一个副本。如果在一个事务内使用滚动游标,那么通
过将隔离级别设置为“可重复读取”或通过在事务期间以共享方式锁定整个表可以
防止更改复制的行。(请参阅 SET ISOLATION 和 LOCK TABLE。)
以下示例为 SELECT 语句创建了一个滚动游标:
DECLARE sc_cur SCROLL CURSOR FOR SELECT * FROM orders;
您可以将 Select 和 Function 游标创建滚动游标,但不可为 Insert 游标创建滚动
游标。不可将滚动游标声明为 FOR UPDATE。
使用 WITH HOLD 关键字创建保持游标
使用 WITH HOLD 关键字创建 hold 游标。Hold 游标允许跨多个事务对行的集合
进行不中断的访问。
通常,所有的游标在事务结束时关闭。Hold 游标不会关闭;它在事务结束之后仍
保持打开状态。
Hold 游标可以是一个顺序游标或(在 ESQL/C 中)滚动游标。
在 SPL 例程中 WITH HOLD 关键字只对 Select 游标有效。有关 DECLARE 语
句在 SPL 例程中的语法,请参阅 在 SPL 例程中声明动态游标。
在 ESQL/C 中,可以使用 WITH HOLD 关键字声明 Select 和函数游标(具有顺序
和滚动属性)也可以声明 Insert 游标。这些关键字在 DECLARE 语句中跟在
CURSOR 关键字之后。以下示例为 SELECT 创建了一个顺序 Hold 游标:
DECLARE hld_cur CURSOR WITH HOLD FOR
SELECT customer_num, lname, city FROM customer;
您可以如下面的 GBase 8s ESQL/C 代码示例所示使用选择保持游标。此代码段使
用一个 Hold 游标作为主游标来扫描一个记录集合,使用一个顺序游标作为细节
游标俩指向位于不同表中的记录。主游标扫描的记录是更新细节游标指向的记录
的基础。在第一个 WHILE 循环的每个迭代的结束处的 COMMIT WORK 语句将
Hold 游标 c_master 保留为打开状态,但关闭顺序游标 c_detail 并释放所有锁。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 529
这种技术最小化了数据库服务器必须分配给锁和未完成的事务的资源,并且它使
其它用户能够立即访问更新的行。
EXEC SQL BEGIN DECLARE SECTION;
int p_custnum, int save_status; long p_orddate;
EXEC SQL END DECLARE SECTION;

EXEC SQL prepare st_1 from
'select order_date from orders where customer_num = ? for update';
EXEC SQL declare c_detail cursor for st_1;
EXEC SQL declare c_master cursor with hold for
select customer_num from customer where city = 'Pittsburgh';

EXEC SQL open c_master;
if(SQLCODE==0) /* the open worked */
EXEC SQL fetch c_master into :p_custnum; /* discover first customer */
while(SQLCODE==0) /* while no errors and not end of pittsburgh
customers */
{
EXEC SQL begin work; /* start transaction for customer p_custnum */
EXEC SQL open c_detail using :p_custnum;
if(SQLCODE==0) /* detail open succeeded */
EXEC SQL fetch c_detail into :p_orddate; /* get first order */
while(SQLCODE==0) /* while no errors and not end of orders */
{
EXEC SQL update orders set order_date = '08/15/94'
where current of c_detail;
if(status==0) /* update was ok */
EXEC SQL fetch c_detail into :p_orddate; /* next order */
}
if(SQLCODE==SQLNOTFOUND) /* correctly updated all found orders */
EXEC SQL commit work; /* make updates permanent, set status */
else /* some failure in an update */
{
save_status = SQLCODE; /* save error for loop control */
EXEC SQL rollback work;
SQLCODE = save_status; /* force loop to end */
}
if(SQLCODE==0) /* all updates, and the commit, worked ok */

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 530
EXEC SQL fetch c_master into :p_custnum; /* next customer? */
}
EXEC SQL close c_master;
使用 CLOSE 语句显式地关闭 Hold 游标,或使用 CLOSE DATABASE 或
DISCONNECT 语句隐式地关闭 Hold 游标。CLOSE DATABASE 语句关闭所有
游标。
使用保持 Insert 游标
如果您将保持游标与 INSERT 语句相关联,则可以使用事务将一长串的 PUT 语
句打断为较小的 PUT 语句集合。除了等待 PUT 语句填充缓冲区并引发自动写
入数据库,您可以执行 COMMIT WORK 语句刷新行缓冲区。使用 Hold 游标,
COMMIT WORK 会提交插入的行,但将游标保留为打开状态以供进一步插入。
当插入大量的行时,这样方法是期望的,因为暂时的未提交的工作会消耗数据库
服务器的资源。
与游标相关联的 SELECT 语句的子集
如 DECLARE 语句的语法表所示,不是所有的 SELECT 语句都可以与只读或更
新游标相关联。
如果 DECLARE 语句包含 FOR READ ONLY 或 FOR UPDATE 选项,则必须遵
守对 DECLARE 语句中包括的 SELECT 语句的某些限制(直接地或作为准备好
的语句)。
如果 DECLARE 语句包括 FOR READ ONLY 选项,则 SELECT 语句不可以有
FOR READ ONLY 或 FOR UPDATE 选项。(有关 SELEC 语法和用法的描述,
请参阅 SELECT 语句。)
如果 DECLARE 语句包括 FOR UPDATE 选项,则 SELECT 语句必须服从下列限制:

该语句只能从一个表中选择数据。

该语句不能包含任何聚集函数。

该语句还不能包含 FOR UPDATE 关键字。

该语句不可以包括任何以下子句或关键字:DISTINCT 、EXCEPT 、
FOR READ ONLY 、FOR UPDATE 、GROUP BY 、INTERSECT 、
INTO TEMP 、MINUS 、ORDER BY 、UNION 或 UNIQUE。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 531
不兼容 ANSI 的数据库中的游标的示例
在不兼容 ANSI 的数据库中,与 SELECT 语句相关联的游标在缺省情况下是一
个只读游标。以下的示例在一个不兼容 ANSI 的数据库中声明了一个只读游标:
EXEC SQL declare cust_curs cursor for
select * from customer_notansi;
如果想要在程序代码中明确此游标为只读游标,应指定 FOR READ ONLY 选
项,如下面的示例所示:
EXEC SQL declare cust_curs cursor for
select * from customer_notansi for read only;
如果要将这个游标变为一个更新游标,可在 DECLARE 语句中指定的 FOR
UPDATE 选项。此示例声明了一个更新游标:
EXEC SQL declare new_curs cursor for
select * from customer_notansi for update;
如果要使一个更新游标只能够修改表中的一些列,则必须在 FOR UPDATE 子句
中指定那些列。下面的示例声明了一个只可以更新 customer_notansi 表中
fname 和 lname 列的更新游标:
EXEC SQL declare name_curs cursor for
select * from customer_notansi for update of fname, lname;
兼容 ANSI 的数据库中的游标的示例
在兼容 ANSI 的数据库中,与 SELECT 语句相关联的游标在缺省情况下是一个
更新游标。
下面的示例声明了一个兼容 ANSI 的数据库中的更新游标:
EXEC SQL declare x_curs cursor for select * from customer_ansi;
要在程序文档中声明此游标为更新游标,您可以指定 FOR UPDATE 选项,如下
面的示例所示:
EXEC SQL declare x_curs cursor for
select * from customer_ansi for update;
如果希望一个更新游标只能够修改表中的一些列,则必须在 FOR UPDATE 选项
中指定这些列。下面的示例声明了一个更新游标,并指定该游标只可以更新
customer_ansi 表中的 fname 和 lname 列:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 532
EXEC SQL declare y_curs cursor for
select * from customer_ansi for update of fname, lname;
如果要将一个游标变为只读游标,则必须通过在 DECLARE 语句中指定 FOR READ
ONLY 选项来覆盖 DECLARE 语句的缺省行为。下面的示例声明了一个只读游标:
EXEC SQL declare z_curs cursor for
select * from customer_ansi for read only;
将游标与准备好的语句相关联
PREPARE 语句让您在运行时聚集 SQL 语句的文本,并将语句文本传送到数据
库服务器以供执行。如果您期望一个能返回值的动态准备好的 SELECT 、
EXECUTE FUNCTION(或 EXECUTE PROCEDURE)语句可生成多行数据,在
必须将该准备好的语句与一个游标相关联。(请参阅 PREPARE。)
PREPARE 语句的结果是一个语句标识符(statement id 或 id variable),它是一
个代表准备好的语句文本的数据结构,要为语句文本声明一个游标,应将该游标
与语句标识符相关联。
您可以将一个顺序游标与任何准备好的 SELECT 或 EXECUTE FUNCTION (或
EXECUTE PROCEDURE)语句相关联。您不可以将一个滚动游标与准备好的
INSERT 语句或准备好包括 FOR UPDATE 子句的 SELECT 语句相关联。
在打开、使用和关闭游标之后,可以在相同的语句标识符下准备一个不同的语
句。以这种方式,一个单独的游标可能在不同的时刻与不同的语句使用。再次使
用游标之前,必须重新声明该游标。
下面的示例包含准备 SELECT 语句并为准备好的语句文本声明顺序游标的 GBase
8s ESQL/C 代码。首先通过返回值的 SELECT 语句准备语句标识符 st_1 ;然后
为 st_1 声明游标 c_detail。
EXEC SQL prepare st_1 from
'select order_date
from orders where customer_num = ?';
EXEC SQL declare c_detail cursor for st_1;
如果想要使用准备好的 SELECT 语句修改数据,可将 FOR UPDATE 子句添加
到想要准备的语句文本,如下面的 GBase 8s ESQL/C 示例所示:
EXEC SQL prepare sel_1 from

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 533
'select * from customer for update';
EXEC SQL declare sel_curs cursor for sel_1;
更改表结构的 DDL 操作可以使使其相关联的准备语句或相关联的例程引用修改
的表的游标无效,除非准备好的对象被重新编译,或者除非例程被重新优化。有
关更多信息,请参阅对游标引用的表的 DDL 操作。
DECLARE 语句允许您为 GBase 8s ESQL/C 集合变量声明游标。这样的游标称为
集合游标。使用集合变量可访问集合(SET 、MULTISET 、LIST)列的元素。
当要访问集合变量中的一个或多个元素的时候,请使用游标。
集合派生的表这一段标识了要为其声明游标的集合变量。有关更多信息,请参阅
集合派生表。
用集合派生的表选择
DECLARE 语句的图表参考了本节。
要为集合变量声明 Select 游标,应将集合派生的表这一段同与集合游标相关联的
SELECT 语句包括在一起。一个 Select 游标允许您从集合变量选择一个或多个元
素。(有关对 SELECT 语句和使用的描述,请参阅 SELECT 语句。)
当为集合变量声明一个 Select 游标时,DECLARE 语句有以下限制:

它不可以将 FOR READ ONLY 关键字包括为游标方式。
Select 游标是一个更新游标。

它不能包括 SCROLL 或 WITH HOLD 关键字。
Select 游标必须是一个顺序游标。
另外,与集合游标相关联的 SELECT 语句有以下限制:

它不可以包括以下子句或选项:WHERE 、GROUP BY 、ORDER
BY 、HAVING 、INTO TEMP 和 WITH REOPTIMIZATION 。

它不可以在选择列表中包含表达式。

如果集合包含不透明、Distinct、内置或其它集合数据类型的元素,则选
择列表必须是一个星号( * )。

选择列表中的列名称必须是简单的列名称,不带限定符。
这些列不能使用以下语法:
database@server:table.column --INVALID SYNTAX

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 534

它必须在 FROM 子句中指定集合变量的名称。
您不可以为集合变量指定输入参数(问号(?))。同样您不可以使用实
际表格式的“集合派生的表”的段。
使用 Select 游标和集合变量
包括带集合派生的表子句的 SELECT 语句的集合游标提供了对集合变量中的元素
的访问。
要选择多个元素:
1.
在 GBase 8s ESQL/C 程序中创建一个客户端集合变量。
2.
使用 DECLARE 语句为 SELECT 语句声明集合游标。
3.
要修改集合变量的元素,可使用 FOR UPDATE 关键字将选择游标声明为一
个更新游标。然后您可以使用 DELETE 和 UPDATE 语句的 WHERE CURRENT
OF 子句删除或更新集合的元素。
4.
使用 OPEN 语句打开此游标。
5.
使用 FETCH 语句和 INTO 子句从集合游标取得元素。
6.
如果需要,则对取得的数据执行任何更新或删除,并将修改的集合变量保
存集合列中。
一旦集合变量包含正确的元素,即可使用 UPDATE 或 INSERT 语句将集合
变量的内容保存在实际的集合列(SET 、MULTISET 或 LIST)。
7.
使用 CLOSE 语句关闭此集合游标。
此 DECLARE 语句为一个集合变量声明一个 Select 游标:
EXEC SQL BEGIN DECLARE SECTION;
client collection set(integer not null) a_set;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL declare set_curs cursor for select * from table(:a_set);
有关对于 SELECT 语句使用集合游标的扩展的代码示例,请参阅 从集合游标访
存。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 535
使用集合派生表插入
要为集合变量声明 Insert 游标,应将集合派生的表这一段同与集合游标相关联的
INSERT 语句包括在一起。一个 Insert 游标允许您从集合变量选择一个或多个元
素。(有关对 INSERT 语句和使用的描述,请参阅 INSERT 语句。)
该 Insert 游标必须是一个顺序游标。即,DECLARE 语句不能指定 SCROLL 关
键字。
当您为集合变量声明 Insert 游标,INSERT 语句的集合派生表子句必须包含集合
变量的名称。您不能为此集合变量指定一个输入参数(问号(?))。但是,可以
在 INSERT 语句的 VALUES 子句中使用输入参数。该参数指示集合元素稍后将
由 PUT 语句的 FROM 子句提供。
包括 INSERT 语句和集合派生表子句的集合游标允许您将多个元素插入一个集合
变量。
要插入多个元素:
1.
在 GBase 8s ESQL/C 程序中创建一个客户端集合变量。
2.
使用 DECLARE 语句为 INSERT 语句声明集合游标。
3.
使用 OPEN 语句打开游标。
4.
使用 PUT 语句和 FROM 子句将元素放入集合游标。
5.
一旦集合变量包含所有元素,即可对表名称使用 UPDATE 语句或
INSERT 语句将集合变量的内容保存在集合列(SET 、MULTISET 或
LIST)。
6.
使用 CLOSE 语句关闭此集合游标。
此示例为 a_set 集合变量声明了一个 Insert 游标:
EXEC SQL BEGIN DECLARE SECTION;
client collection multiset(smallint not null) a_mset;
int an_element;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL declare mset_curs cursor for
insert into table(:a_mset) values (?);
EXEC SQL open mset_curs;
while (1)

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 536
{
...
EXEC SQL put mset_curs from :an_element;
...
}
要将元素插入集合变量,可使用 FROM 子句的 PUT 语句。有关对 INSERT 语
句使用集合游标的代码示例,请参阅插入到 Collection 游标内。
使用带事务的游标
要回滚修改,必须在事务内执行修改。只有当执行 BEGIN WORK 语句时,不兼
容 ANSI 的数据库中的事务才会开始。
在兼容 ANSI 的数据库中,事务始终有效。
数据库服务器对选择和更新游标强制这些准则以确保可以正常地提交或回滚修
改:

在事务内打开一个插入或更新游标。

在一个事务内包含 PUT 和 FLUSH 语句。

在一个事务内修改数据(更新、插入或删除)。
数据库服务器让您打开和关闭保持游标以便在事务之外执行更新操作;但是,应
当先取得所有与给定修改有关的行,然后在一个单独的事务中执行所有的修改。
您无法在事务之外打开和关闭保持游标或更新游标。
以下示例在事务内使用一个更新游标:
EXEC SQL declare q_curs cursor for
select customer_num, fname, lname from customer
where lname matches :last_name for update;
EXEC SQL open q_curs;
EXEC SQL begin work;
EXEC SQL fetch q_curs into :cust_rec; /* fetch after begin */
EXEC SQL update customer set lname = 'Smith'
where current of q_curs;
/* no error */
EXEC SQL commit work;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 537
当更新事务内的行时,该行保持为锁定状态,直到游标被关闭或者是事务被提交
或回滚。如果在没有任何事务是有效的时候对行进行更新,则在将修改的行写到
磁盘时会释放该行锁定。如果在事务之外更新或删除行,则无法回滚该操作。
在使用事务的数据库中,您无法在事务之外打开一个插入游标,除非也使用
WITH HOLD 关键字声明了该插入游标。
在 SPL 例程中声明动态游标
在 SPL 例程中使用 DECLARE 语句声明动态游标的名称,并将此游标与
PREPARE 语句在同一 SPL 例程中声明的准备好的语句的语句标识符相关联。
SQL 的 DECLARE 语句在 SPL 例程中创建的动态游标与 SPL 的 FOREACH
语句在 SPL 例程中创建的直接顺序游标不同。(有关顺序游标的语法和用法,请
参阅 FOREACH。)
语法
SPL 例程中 DECLARE 语句是 GBase 8s ESQL/C 例程中 DECLARE 支持的语
法的子集。

元素
描述
限制
语法
cursor_id
此处为动态游标声明
的名称r
在例程的游标名称、准
备好的语句名称和 SPL
变量名称中必须是唯一
标识符
statement_id 一个准备好的 SQL
语句的标识符
必须已在同一 SPL 例程
的 PREPARE 语句中声明
标识符
用法
在以 SPL 语言编写的 UDR 中,与游标相关联的 statement_id 必须已在
PREPARE 语句的同一 UDR 中从这些语句类型之一的单个 SQL 语句的文本中
预先声明:

EXECUTE FUNCTION

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 538

EXECUTE PROCEDURE

SELECT.
statement_id 指定的准备好的语句文本可以包含问号( ? )作为用户在运行时提
供的值的占位符,但 PREPARE 语句中的占位符只能表示数据值,而不能表示
SQL 标识符。
DECLARE 语句可以在 SPL 例程中定义的动态游标类似于 ESQL/C 在其功能中
Select 游标或函数游标,但是具有以下限制:

DECLARE 在 SPL 例程中定义的游标可以是 Select 游标或函数游标,
但是它们不能是 Insert 游标或集合游标。

游标或准备好的语句的标识符不能指定为 SPL 变量。因为在 SPL 中,
变量、游标和准备好对象的标识符会共享同一命名空间。

缺省情况下,SPL 的动态游标是顺序的。它们不能是滚动游标。

您使用 WITH HOLD 关键字创建的动态游标的语义与 FOREACH 语句
声明的保持游标相同。

SPL 例程中的 WITH HOLD 关键字只对 Select 游标有效。如果
statement_id 引用了 EXECUTE FUNCTION 或 EXECUTE PROCEDURE
语句的准备好的文本,则 DECLARE 语句失败并发出错误 -26056。

在 DECLARE 语句中 ESQL/C 支持的 FOR UPDATE 和 FOR READ
ONLY 关键字在 SPL 例程中不支持。使用 SPL 的 FOREACH 语句声
明可以模拟 ESQL/C 更新游标的功能的直接游标。(但是当编译 UDR
时,而不是在运行时定义与直接游标相关联的查询。)

SPL 例程中的 DECLARE 语句在集合派生的表上不支持 SELECT 操
作。

SPL 例程的 DECLARE 语句中的语法错误会在运行时报告,不像
ESQL/C 的语法错误,在例程编译完后报告。
DECLARE 的语句与 SPL 例程中的准备好的语句相关联的动态游标的名称可以
由同一 SPL 例程中的动态 SQL 的 OPEN 、CLOSE 、FETCH 和 FREE 语句
引用。
在以下程序片段中,声明一个名为 equi_noctis 的游标,并打开、关闭和释放
它。
CREATE FUNCTION lente
DEFINE first, last VARCHAR(30);

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 539
. . .
DATABASE stores_demo;
LET first = "select * from state";
LET lsst = "where code < ?";
PREPARE stmt_1 FROM first || last;
DECLARE cursor_1 FOR stmt_1;
OPEN cursor_1
. . .
CLOSE cursor_1;
FREE cursor_1;
FREE stmt_1;
...
END FUNCTION;

统一监控主页

统一数据平台监控与运维系统用户手册


- 4 -

南大通用数据技术股份有限公司
在成功登录监控网站后,将进入到网站主界面,如下图所示:

图 错误!文档中没有指定样式的文字。-2 统一监控集群监控主页
主页面展示了当前用户能够查看的所有集群的概览信息,上图给出了
GBase8s 集群的监控。
点击集群名称跳转到该集群的监管主页面。

图 错误!文档中没有指定样式的文字。-3 统一监控导航
从左到右依次为:
集群监管:提供了集群整体运行状态、集群性能、数据库信息、会话、日
志信息等监管功能,点击可进入“集群监管”主界面,具体请参考“集群监
管”章节。
密码修改:提供了对当前登录用户进行密码修改的功能。具体请参考“密
码修改”章节。
登录帐户名:当前的登录用户的帐号信息,如图中为admin。
注销:点击“注销”将退出统一监控,界面将跳转到登录界面。

功能描述
与数据库服务器建立一个新的链接。
原型
PGconn *PQsetdbLogin(const char *pghost,
const char *pgport,
const char *pgoptions,
const char *pgtty,
const char *dbName,
const char *login,
const char *pwd);
参数
表8-38 PQsetdbLogin 参数
关键字
参数说明
pghost
要链接的主机名,详见6.4.5 链接参数章节描述的host 字段。
pgport
主机服务器的端口号,详见6.4.5 链接参数描述的port 字段。
pgoptions
添加命令行选项以在运行时发送到服务器,详见6.4.5 链接参数
描述的options 字段。
pgtty
忽略(以前,这个选项声明服务器日志的输出方向)。
dbName
要链接的数据库名,详见6.4.5 链接参数描述的dbname 字段。
login
要链接的用户名,详见6.4.5 链接参数章节描述的user 字段。
pwd
如果服务器要求口令认证,所用的口令,详见6.4.5 链接参数描
述的password 字段。
返回值
PGconn *:指向包含链接的对象指针,内存在函数内部申请。
注意事项

该函数为PQconnectdb 前身,参数个数固定,未定义参数被调用时使用缺省值,若需

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
281
要给固定参数设置缺省值,则可赋值NULL 或者空字符串。

若dbName 中包含“=”或链接URL 的有效前缀,
则该dbName 被看做一个conninfo 字符
串并传递至PQconnectdb 中,其余参数与PQconnectdbParams 保持一致。
示例
参见6.4.3 示例。