数据集与游标
解决问题:SQL语言如何在DBMS中执行
如何将SQL检索到的结果返回到宿主程序
静态SQL,SQL语句中的常量更换为变量
1.如何读取单行数据和多行数据
(1)检索单行结果,将结果直接传送到宿主程序的变量中
exec sql SELECT [ALL | DISTINCT] expression [, expression ...]
INTO host-variable, [host-variable, ...]
FROM tableref [corr_name] [, tableref [corr_name] ...]
WHERE serach_condition;
(2)举例
exec sql select Sname, Sage
into :vSname, :vSage
from Student where Sname = :specName;
(3)检索多行结果,需要游标(Cursor)
1)游标是指向某检索记录集的指针,通过这个指针的移动,一行一行的读取
2)读一行的操作通过 Fetch ... into 语句实现的:每一次Fetch,都是先向下移动指针,然后读取
3)记录集有结束标识EOF,用来标记后面已经没有记录了
(4)游标的使用
1)定义->打开->处理数据表->关闭
exec sql declare cur_student cursor for
select Sno, Sname, Sclass froom Student where Sclass = '035101'; //定义游标
exec sql open cur_student; //打开游标,产生结果集合
exec sql fetch cur_student into :vSno, :vSname, :vSclass; ...
exec sql close cur_student //关闭游标,以上操作可重复多次使用
2.数据集和游标的使用举例
1 #define TURE 1 2 #includeExample3 #include "prompt.h" 4 exec sql include sqlca; 5 exec sql begin declare section; 6 char cust_id[5],agent_id[14]; 7 double dollar_sum; 8 exec sql end declare section; 9 10 int main() 11 { 12 char cid_prompt[] = "Please enter customer ID:"; 13 exec sql declare agent_dollars cursor for //声明一个游标agent_dollars 14 select aid, sum(dollars) 15 from orders where cid = :cust_id 16 group by aid; 17 18 exec sql whenever sqlerror goto report_error; //错误捕获,出错是转到report_error 19 exec sql connect to testdb; //连接数据库 20 exec sql whenever not found goto finsh //错误捕获,如果找不到对应数据库,转到finsh 21 22 while((prompt(cid_prompt,1,cust_id,4))>=0) //可以多次打开游标 23 { 24 exec sql open agent_dollers; //打开游标 25 while(TRUE) 26 { 27 exec sql fetch agent_dollers into :agent_id, :doller_sum; 28 //通过指针读取数据,放入到agent_id,doller_sum中 29 printf("%s %11.2f\n",agent_id,dollar_sum); 30 } 31 finsh: exec sql close agent_dollars; //处理完关闭游标 32 exec sql commit work; //断开数据库连接 33 } 34 exec sql disconnect current; 35 return 0; 36 37 //出错时执行下列操作 38 report_error: 39 print_dberror(); 40 exec sql rollback; 41 exec sql disconnect current; 42 return 1; 43 }
3.游标的使用方法(规范)
(1)Cursor的定义:declare cursor
exec sql declare cursor_name cursor for
Subquery
[order by result_column [ASC | DESC] [, result_column ...] [FOR [read only | update [of columnname [, columnname ...] ]]]]
(2)举例
exec sql declar cur_student cursor for
select Sno,Sname,Sclass from Student where Sclass = :vClass
older by Sno
for read only;
(3)Cursor的open和close
exec sql open cursor_name;
exec sql close cursor_name;
(4)Cursor的数据读取:Fetch
exec sql fetch cursor_name
into host-variable, [host-variable, ...];