可滚动游标和数据库的增删改
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 #include4 #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 }