原理:游标就是把数据按照指定要求提取出相应的数据集,然后逐条进行数据处理。

游标的概念

 1.1游标(Cursor)

它使用户可逐行访问由SQL Server返回的结果集。

 使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式。

 用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。

 游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。

1.2SQL语言与主语言具有不同数据处理方式

(1).SQL语言是面向集合的,一条SQL语句原则上可以产生或处理多条记录

(2).主语言是面向记录的,一组主变量一次只能存放一条记录

仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求,嵌入式SQL引入了游标的概念,用来协调这两种不同的处理方式。

游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每个游标区都有一个名字。

1.3 游标的优点

 从游标定义可以得到游标的如下优点,这些优点使游标在实际应用中发挥了重要作用:

1)允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。

2)提供对基于游标位置的表中的行进行删除和更新的能力。

3)游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。

1.4 游标的使用

 讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱。

 使用游标的顺序:声名游标、打开游标、读取数据、关闭游标、删除游标。

EXEC SQL DECLARE CURSORNAME CURSOR FOR

EXEC SQL OPEN CURSORNAME

EXEC  SQL FETCH CURSORNAME INTO 

EXEC SQL CLOSE CURSORNAME

 

 

不用游标的SQL语句的种类:

1.说明性语句 declare

2.数据定义语句 create,alter,drop

3.数据控制语句 grant,revoke

4.查询结果为单记录的SELECT语句 where查询中出现unique

5.非CURRENT形式的UPDATE语句

6.非CURRENT形式的DELETE语句

7.INSERT语句 

 

一、说明性语句是专为在嵌入式SQL中说明主变量、SQLCA等而设置的。

说明主变量

1.EXEC SQL BEGIN DECLARE SECTION;

2.EXEC SQL END DECLARE SECTION;

这两条语句必须配对出现,相当于一个括号,两条语句中间是主变量的说明。

说明SQLCA

3.EXEC SQL INCLUDE SQLCA

二、数据定义语句

例如:建立一个“学生”表Student

EXEC SQL CREATE TABLE Student

(Sno CHAR(5) NOT NULL UNIQUE,

Sname CHAR(20),

Ssex CHAR(1),

Sage INT,

Sdept CHAR(15));

数据定义语句中不允许使用主变量。

三、数据控制语句

例如:把查询Student表权限授给用户U1

EXEC SQL GRANT SELECT ON TABLE Student TO U1;

四、查询结果为单记录的SELECT语句

语句格式:

EXEC SQL SELECT [ALL|DISTINCT]<目标表达式>[,<目标表达式>]...

INTO <主变量>[<指示变量>][,<主变量>[<指示变量>]]...

FROM <表名或视图名>[,<表名或视图名>]...

[WHERE <条件表达式>]

[GROUP BY <列名1>[HAVING<条件表达式>]]

[ORDER BY <列名2>[ASC|DESC]];

对交互式SELECT语句的扩充,多了一个INTO子句,把从数据库中找到的符合条件的记录,放到INTO子句指出的主变量中去。

使用注意事项:

1.使用主变量,只能出现在INTO子句、WHERE子句的条件表达式、HAVING短语的条件表达式

2.使用指示变量,指示变量只能用于INTO子句中。如果INTO子句中主变量后面跟有指示变量,则当查询得出某个数据项为空值时,系统会自动将相应主变量后面的指示变量置为负值,但不向该主变量执行赋值操作,即主变量仍保持执行SQL语句之前的值。当发现指示变量值为负值时,不管主变量为何值,均应认为主变量值为NULL。

3.查询结果为空集。如果数据库中没有满足条件的记录,即查询结果为空,则DBMS将SQLCODE的值置为100

4.查询结果为多条记录,程序出错,DBMS会在SQLCA中返回错误信息。

从提高应用程序的数据独立性角度考虑,SELECT语句在任何情况下都应该使用游标。

五、非CURRENT形式的UPDATE语句

使用主变量:出现在SET子句,WHERE子句。

使用指示变量:出现在SET子句。

非CURRENT形式的UPDATE语句可以操作多条元组。       

六、非CURRENT形式的DELETE语句

使用主变量:出现在WHERE子句中。

非CURRENT形式的DELETE语句可以操作多条元组。

七、非CURRENT形式的INSERT语句

使用主变量:出现在VALUES子句

使用指示变量:出现在VALUES子句

非CURRENT形式的INSERT语句一次只能输入一条元组。

必须使用游标的SQL语句          

1.查询结果为多条记录的SELECT语句。

2.CURRENT形式的UPDATE语句。

3.CURRENT形式的DELETE语句。                     

 一、查询结果为多条记录的SELECT语句

使用游标的步骤:

1.说明游标

2.打开游标

3.移动游标指针,然后取当前记录

4.关闭游标

 

 

1.说明游标:使用DECLARE语句。语句格式:EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句>;功能:一条说明性语句,DBMS并不执行SELECT指定的查询操作。

2.打开游标:使用OPEN语句,语句格式:EXEC SQL OPEN <游标名>;功能:打开游标实际上是执行相应的SELECT语句,把所有满足查询条件的记录从指定表取到缓冲区中;这时游标处于活动状态,指针指向查询结果集中第一条记录之前。

3.移动游标指针,然后取当前记录。使用FETCH语句,语句格式:EXEC SQL FETCH [[NEXT|PRIOR|FIRST|LAST]FROM] <游标名> INTO <主变量>[<指示变量>][,<主变量>[<指示变量>]]...;功能:指定方向推动游标指针,然后将缓冲区中的当前记录取出来送至主变量供主语言进一步处理;NEXT|PRIOR|FIRST|LAST:指定推动游标指针的方式。

NEXT:向前推进一条记录。

PRIOR:向后回退一条记录。

FIRST:推向第一条记录。

LAST:推向最后一条记录。

缺省值为NEXT。

说明:

  1.主变量必须与SELECT语句中的目标列表达式具有一一对应关系。

  2.FETCH语句通常用在一个循环结构中,通过循环执行FETCH语句逐条取出结果集中的行进行处理。

  3.为进一步方便用户处理数据,现在一些关系数据库管理系统对FETCH语句做了扩充,允许用户向任意方向以任意步长移动游标指针。

4.关闭游标:使用CLOSE语句,语句格式:EXEC SQL CLOSE <游标名>;功能:关闭游标,释放结果集占用的缓冲区及其他资源。说明:游标被关闭后,就不再和原来的查询结果集相联系,被关闭的游标可以再次被打开,与新的查询结果相联系。

二、CURRENT形式的UPDATE语句和DELETE语句:是面向集合的操作;一次修改或删除所有满足条件的记录。

如果只想修改或删除其中某个记录:用带游标的SELECT语句查出所有满足条件的记录;从中进一步找出要修改或删除的记录;用CURRENT形式的UPDATE语句和DELETE语句语句修改或删除之。

步骤:

(1).DECLARE,说明游标

(2).OPEN,打开游标,把所有满足查询条件的记录从指定表取至缓冲区

(3).FETCH,推进游标指针,把当前记录从缓冲区中取出来送至主变量

(4).检查该记录是否是要修改或删除的记录,是则处理之

(5).重复第(3)和(4)步,用逐条取出结果集中的行进行判断和处理

(6).CLOSE,关闭游标,释放结果集占用的缓冲区和其他资源。

为UPDATE语句说明游标:使用带FOR UPDATE OF <列名>短语的DECLARE语句。语句格式:EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句> FOR UPDATE OF <列名>;FOR UPDATE OF <列名>短语用于指明检索出的数据在指定列上是可修改的,以便DBMS进行并发控制。

为DELETE语句说明游标,使用带FOR DELETE短语的DECLARE语句。语句格式:EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT 语句> FOR UPDATE;FOR UPDATE短语提示DBMS进行并发控制。

 

修改或删除当前记录:语句格式:<UPDATE语句> WHERE CURRENT OF <游标名>;<DELETE语句> WHERE CURRENT OF <游标名>。WHERE CURRENT OF <游标名>子句表示修改或删除的是该游标中最近一次取出的记录。

当游标定义中的SELECT语句带有UNION或ORDER BY子句时,或者改SELECT语句相当于定义了一个不可更新的视图时,不能使用CURRENT形式的UPDATE语句和DELETE语句。