嵌入式SQL
所有sql语句前面要加前缀 exec sql
EXEC sql connect to target [as connection-name] [user user-name]; /*target是数据库服务器的名字 connect-name 是可选的连接名*/
2.定义主变量与数据通讯区
1 exec sql begin declare section;/*主变量说明开始*/ 2 char Deptname[20]; 3 char Hsno[9]; 4 char Hsname[20]; 5 char Hsseex[2]; 6 int HSage; 7 int NEWAGE; 8 exec sql end declare section;/*主变量说明结束*/ 9 long sqlcode; 10 exec sql include sqlca;/*定义sql通信区*/
3.执行sql语句(增删改查)
exec sql select sno,sname,ssex,sage,sdept into:Hsno,:Hname,:Hsex,:Hage,:Hdept/*:后为主变量*/ from student where sno = :givensno;
4.关闭数据库连接
exec sql disconnect [connection];
5.程序实例(打印指定学号的学生记录)
1 //主变量定义 2 exec sql begin declare section; 3 char Deptname[20]; 4 char HSno[9]; 5 char HSName[20]; 6 char HSSex[2]; 7 int HSage; 8 exec sql end declare section; 9 //定义sql通信区 10 long sqlcode; 11 exec sql include sqlca; 12 //c语言主程序 13 int main(void){ 14 printf("Please input the student number"); 15 scanf("%s",Hsno); 16 //连接Test数据库 17 exec sql connect to Test@localhost:54321 AS conn1 18 user "system" using "manager"; 19 //执行sql查询 20 exec sql select Sno,sname,ssex,sage,sdept 21 into :Hsno,:Hname,:Hsex,:Hage,:Hdept 22 from student 23 where sno = :HSno; 24 if(sqlca.sqlcade == 0)//等于0表示操作成功 25 { 26 printf("\n%-9s %-20s %-2s %-4s %-20s\n","Sno","Sname","Ssex","Sage","Sdept"); 27 printf("%-9s %-20s %-2s %-4s %-20s\n",Hsno,Hname,Hsex,HSage,Hdept); 28 } 29 //关闭游标,断开连接 30 exec sql disconnect conn1; 31 32 }
6.嵌入式sql语句与主语言之间的通信
-
想主语言传递SQL语句的执行状态信息 --- SQL通信区(SQLCA)
-
主语言向SQL语句提供参数 ---- 主变量
-
将SQL语句查询的结果返回给主语言 --- 主变量和游标
SQLCA
定义:
exec sql include sqlca;
使用:
sqlca里面有一个sqlcode,每次执行sql语句后都返回给sqlcode一个值,如果为0,代表执行成功。
主变量和指示变量
定义:
bebin declare section .. //说明主变量和指示变量 .. end declare section
指示变量:
-
指示输入主变量是否为空值
-
检测输出主变量是否为空值,值是否被截断。
使用:
在SQL语句中,主变量和指示变量前要加 :作为标志
在SQL语句外,就是普通的变量。
指示变量紧跟主变量,例如:
into :hsno,:hcno,:hgrade:gradeid/*指示变量gradeid*/
如果gradeid<0,不论hgrade为何值,均为空值
游标(cursor)
使用游标的目的:
主语言一次只能处理一条记录,但是sql一次可以产生多条记录,所以为了解决这种不匹配的处理方式,引入游标,其实就是一个缓冲区,一条一条的给主语言传递记录。
游标创建
exec sql declare <游标名> cursor for <select语句>;
创建后只是申请了缓冲区,并不执行select语句,激活游标语句:
exec sql open <游标名>;
游标使用步骤
-
申请cursor
-
打开游标
此时游标指针只是指向第一条记录,并不会往下推进
-
推进游标指针并取当前记录(使用fetch语句)
exec sql fetch <游标名> into<主变量>[<指示变量>]...;
-
关闭游标(close语句)
exec sql close <游标名>;
-
必须使用游标的SQL语句
-
查询结果为多条记录的select语句(因为你要打印出来,就是要和主程序交互,所以用游标)
-
current形式的update语句
-
current形式的delete语句
关于current形式的理解:
-
current形式就是当前的形式,是动态变化的形式,所以要用到游标,正好契合。
一般的update和delete语句不打印,不用和主程序交互,就不需要用游标,这就是非current形式
current形式怎么交互呢?
实际上也是用到了select语句,就是要删除或者修改其中某个记录,用带游标的select语句查出所有满足条件的记录,进一步找出要删除或修改的记录,用current形式的update和delete语句修改或删除之,其中要用到子句:
where current of <游标名>;
即用游标指示要删除的当前记录。
动态SQL
在编译阶段无法获得完整的SQL语句,需要在程序执行时才能够确定的SQL语句,称为“动态嵌入式SQL”
-
允许在程序运行过程中临时“组装”出SQL语句
-
支持动态组装SQL语句和动态参数两种形式