可滚动游标和数据库的增删改


1.可滚动游标

  (1)标准游标

    1)始终从开始方向向结束方向移动,每 fetch 一次,向结束方向移动一次;

    2)一条记录只能被访问一次;

    3)再次访问该记录只能关闭游标后重新打开

  (2)滚动游标

    1)可滚动游标:使游标指针在记录集之间灵活移动,使每条记录可以反复被访问的一种游标

    2)ODBC(Open DataBase Connectivity)是一种跨DBMS的数据库操作平台,在应用程序和实际dbms之间提供了一种通用接口

    3)许多DBMS实际上不支持可滚动游标,但ODBC支持

  (3)可滚动游标的格式

    exec sql declare cursor_name [insensitive] [SCROLL] cursor  //声明游标时的可滚动选项

      [with hold] FOR Subquery

      [order by result_column [ASC | DESC][, result_column ...]

      [for end only | for update of columnname] [, columnname] ...];

    exec sql fetch 

      [next | prior | first | last | [ablolute | relative] value_spec]  //选择向什么方向移动

      FROM cursor_name INTO host-variable [, host-variable ...];

    1)next:向结束方向移动一条

    2)prior:向开始方向移动一条

    3)first:回到第一条

    4)last:移动到最后一条

    5)absolute value_spec:定向检索指定位置的行,value_spec由1至当前记录集最大值

    6)relative value_spec:相对当前记录向前或向后移动,value_spec为正数向结束方向移动,为负数向开始方向移动

2.可滚动游标的定义和使用

  (1)可滚动游标移动时需判断是否到结束位置,或到起始位置

    1)设置两个边界:判断是否到 EOF 位置(最后一条记录的后面),或 BOF (起始记录的前面)

    2)不设置边界:可通过 whenever not found 语句设置来检测

3.数据库记录的删除

  (1)查找删除

    exec sql delete from tablename [corr_name]

      Where search_condition;

  (2)定位删除

    exec sql delete from tablename [corr_name]

      Where current of cursor_name;

  (3)举例

    exec sql delete from customers c where c.city = 'Harbin' and 

      not exists (select from orders o where o.cid = c.cid);  //查找删除

exec sql declare delcust cursor for        //定义游标delcust 
    select cid from customers c where c.city = 'Harbin' and 
    not exists(select * from orders o where o.cid = o.cid)
    for update of cid;
exec ssql open delcust    
while(TRUE)
{
    exec sql fetch delcust into :cust_id;
    exec sql delete from customers where current of delcust;
}

4.数据库记录的更新

  (1)查找更新

    exec sql update tablename [corr_name]

      set columnname = expr [, columnname = expr ...]

      [where search_condition]

  (2)定位更新

    exec sql update tablename [corr_name]

      set columnname = expr [, columnname = expr ...]

      where current of cursor_name;

  (3)举例

    exec sql update student s

      set sclass = '035102'

      where s.sclass = '034101'  //查找更新

exec sql declare stud cursor for        //定义游标stud 
    select * from student s where s.sclass = '034101'
    for update of sclass;
exec ssql open stud
while(TRUE)
{
    exec sql fetch stud into :vSno,:vSname,:vSclass;
    exec sql update student set sclass = '035101' where current of stud;
}

5数据库记录的插入

  (1)插入方式

    exec sql insert into tablename [(columnname [,columnname, ...] )]

      [values (expr [,expr, ...]) | subqurey];

  (2)举例

    exec sql insert into student (sno, sname, sclass)

      values ('03510128', '张三', '035101');

    //插入方式和交互式SQL语法一样,只是加入引导词 exec sql,变为嵌入式SQL语言 

 1 //宿主语言与SQL结合的过程性控制
 2 //求数据库中某一列位于中值的那一行
 3 #include 
 4 #include "prompt.h"
 5 exec sql include sqlca;
 6 char custprompt[] = "Please enter a customer ID:"
 7 
 8 int main()
 9 {
10     exec sql begin declare section;        //声明一些变量 
11         char cid[5], user_name[20], user_pwd[10];
12         double dollars;
13         int ocount;
14     exec sql end declare section;
15     
16     exec sql declare dollars_cursor cursor for        //声明游标 
17         select dollars from orders where cid =:cid and 
18             dollars is not null
19         order by dollars;
20     
21     int i;
22     exec sql whenever sqlerror goto report_error;    //错误捕获语句 
23     strcpy(user_name,"poneilsql");
24     strcpy(user_pwd,"xxxx");
25     exec sql connect :user_name identified by :user_pwd;
26     
27     while(prompt(custprompt, 1, cid, 4)>=0)
28     {
29         exec sql select count(dollars)
30         into :ocount from orders where cid =:cid;
31         if(ocount == 0)
32         {
33             printf("No record reviewed for cid value %s\n",cid);
34             continue;
35         }
36         exec sql open dollars_cursor;    //打开游标 
37         for(i = 0; i < (ocount+1)/2; i++)
38         {
39             exec sql fetch dollars_cursor into :dollars;
40         }
41         exec sql close dollars_cursor;    //关闭游标 
42         exec sql commit work;        //提交 
43         printf("Median dollar amount = %f\n",dollars);
44     }
45     return 0;
46     //后续还有一些错误处理语句 
47 } 

相关