280 likes | 418 Views
3.7 嵌入式 SQL. 以 C 或 PL/1 作为主语言的嵌入式一般形式为: EXEC SQL〈SQL 主语句 〉 例 将下面一条 SQL 语句“ DROP TABLE Student” 嵌入到程序中为: EXEC SQL DROP TABLE Student ;. 3.7.2 嵌入式语句与主语言之间的通信. 数据库工作单元与源程序之间的通信包括: 1 向主语言传递 SQL 语句的之间的状态信息,使主语言能够控制此程序流程 2 主语言向 SQL 语句提供参数 3 将 SQL 语句查询数据库的结果交主语言进一步处理. 1 SQL 通信区
E N D
3.7嵌入式SQL • 以C或PL/1作为主语言的嵌入式一般形式为: • EXEC SQL〈SQL主语句〉 • 例 将下面一条SQL语句“DROP TABLE Student”嵌入到程序中为: • EXEC SQL DROP TABLE Student;
3.7.2 嵌入式语句与主语言之间的通信 • 数据库工作单元与源程序之间的通信包括: • 1 向主语言传递SQL语句的之间的状态信息,使主语言能够控制此程序流程 • 2 主语言向SQL语句提供参数 • 3 将SQL语句查询数据库的结果交主语言进一步处理
1 SQL 通信区 • 包括描述系统当前工作状态和运行环境的各种数据,将送到SQL通信区SQLCA。 应用程序从中取出这些状态信息,据此决定接下来执行的语句。 • 2 主变量 • 嵌入式语句可以使用主语言的程序变量来输入或输出数据。主语言程序变量简称主变量
3 游标 • 下面给出嵌入SQL的一小段C程序: • exec sql include sqlca; • exec sql begin declare section; • char title-id(7); • char title(81); • int royalty
Exec sql end declare section; • main() • { • exec sql declare c1 cursor for • select tit-id,roy from titles; • exec sql open c1; • for(;;) • { • exec sql fetch c1 into :title-id,title,:royalty
If (sqlca.sqlcode<> success) • break; • printf(“title id:%royalty:%d,:title-id,royalty); • printf(“title:%s”,title); • exec sql close c1;
3.7.3不用游标的SOL语句 • 说明性语句 • 数据定义语句 • 数据控制语句 • 查询结果为单记录的SELECT语句 • 非CURRENT形式的UPDATE • 非CURRENT形式的DELETE • INSERT语句
1。说明性语句 • 格式: • EXEC SQL BEGIN DECLARE SECTION • 主变量的说明; • EXEC SQL END DECLARE SECTION;
数据定义语句 • 例。 建立一个学生表STUDENT。 • EXEC SQL CREATE TABLE Student • (Sno CHAR(5) NOT NULL UNIQUE • Sname CHAR(20), • Ssex CHAR(1), • Sage INT, • Sdept CHAR(15);
3.数据控制语句 • 例 把查询STUDENT表权限授给用户U1。 • EXEC SQL GRANT SELECT ON • TABLE STUDENT TO U1
4。查询结果为单记录的SELECT语句 • EXEC SQL SELECT [ALL DISTINCT] • <目标列表达式 > [, <目标列表达式 > ] • INTO < 主变量 >[<指示变量> ] [, <主变量> [<指示变量> ] ] • FROM <表名或视图名> • [ WHERE <条件表达式>] • [ GROUP BY <列名1> [HAVING<条件表达式> ] ] • [ORDER BY <列名2> [ASC DESC] ];
注意 • 使用主变量前须加以说明,且引用时其前面要加冒号。 • 查询结果中某列为空时(NULL),如果 • INTO子句中主变量后面跟有指示变量,系统自动为该指示变量赋一空值。 • 查询结果为空时,DBMS将SQLCODE的值置为100。 • 查询结果非单条记录,SQLCA中返回错误信息。
例。 根据学生号码查询学生信息 • EXEC SQL SELECT Sno,Sname, Ssex, Sage,Sdept • INTO :Hsno,:H name ,:Hsex, • :Hage,:Hdept • FROM Student • WHERE Sno= :givensno;
例 查询某个学生选修某门课程的成绩。 • EXEC SQL SELECT Sno,Cno,Grade • INTO :Hsno,:Hcno,:Hgrade:Gradeid • FROM SC • WHERE Sno= :givensnoAND Cno= • :givencno;
5.非CURRENT形式的UPDATE语句 • 将全体学生1号课程的成绩加若干分。 • EXEC SQL UPDATE SC • SET Grade= Grade+:Raise • WHERE Cno=‘1’;
例 将计算机系全体学生年龄置空值(NULL) • Sageid= -1; • EXEC SQL UPDATE Student • SET Sage=:Raise:Sageid • WHERE Sdept=‘CS’; • 等价于: • EXEC SQL UPDATE Student • SET Sage = NULL • WHERE Sdept=‘CS’;
6。非CURRENT形式的DELETE语句 • 例 删除某个学生所有选课记录。 • EXEC SQL DELETE • FROM SC • WHERE Sno= • (SELECT Sno • FROM Student • WHERE Sname =:stdname
等价于: • EXEC SQL DELETE • FROM SC • WHERE :stdname = • (SELECT Sname • FROM Student • WHERE Student。 Sno=SC.sno
7.INSERT 语句 • INSERT 语句的VALUES子句可以使用主变量和指示变量。 • 例 将某个学生某门课程的记录插入SC表中。 • Gradeid=-1 • EXEC SQL INSERT • INTO SC(Sno,Cno,Grade) • VALUES(:stdno,:couno,:gr,:gradeid)
3.7.4 使用游标的SQL语句 • 查询结果为多条记录的SELECT语句。 • CURRENT 形式的UPDATE语句。 • CURRENT 形式的 DELETE语句。
查询结果为多条记录的SELECT语句 • 使用游标的步骤: • 1)。说明游标 • EXEC SQL DECLARE 〈游标名〉CURSOR FOR 〈SELECT语句〉; • 2)。打开游标 • EXEC SQL OPEN 〈游标名〉; • 3)。推进游标指针并取当前记录。 • EXEC SQL FETCH 〈游标名〉 • INTO < 主变量 >[<指示变量> ] [, <主变量> [<指示变量> ] ]
4)。关闭游标 • EXEC SQL CLOSE 〈游标名〉 • 例 查询某个系全体学生的信息。 • • • EXEC SQL BEGIN DECLARESECTION • • /*说明主变量deptname,Hsno,Hsname,Hsage 等。*/ • EXEC SQL END DECLARE SECTION; •
get(deptname); • • EXEC SQL DECLARE SX CURSOR FOR • SELECT Sno,Sname,Ssex,Sage • FROM Student • WHERE Sdept=:deptname; • /*说明游标*/ • EXEC SQL OPEN SX /*打开游标*/ • WHILE(1) • /*用循环结构逐条处理结果集中的记录*/
{ • EXEC SQL FETCH SX INTO • :Hsno, :Hsname, :Hssex, :Hsage; • /*游标指针向前推进一行,取当前行送相 • 应主变量*/ • if (sqlca.sqlcode<>SUCCESS) • break; • /*若查询结束或出现SQL语句错误,则退出循环*/ • • • };
EXEC SQL CLOSE SX; • / *关闭游标* / • • • 例 查询某系全体学生的选课信息。 • • • EXEC SQL BEGIN DECLARESECTION • • /*说明主变量deptname,Hsno,Hsname,Hsage 等。*/ • EXEC SQL END DECLARE SECTION;
• • • EXEC SQL DECLARE SX CURSOR FOR • SELECT Sno,Sname,Ssex,Sage • FROM Student • WHERE Sdept=:deptname; • /*说明游标*/ • WHERE(get(deptname)!=NULL) • /*接受主变量deptname的值*/
{ • EXEC SQL OPEN SX • WHILE(1) {/*用循环结构逐条处理结果集中的记录 • EXEC SQL FETCH SX INTO • :Hsno, :Hsname, :Hssex, :Hsage; • /*游标指针向前推进一行,取当前行送相 • 应主变量*/ • if (sqlca.sqlcode<>SUCCESS) • break; • /*若查询结束或出现SQL语句错误,则退出循环*/
Prinf(“% s,% s, % s,% d,”Sno,Sname,Ssex,Sage);/*显示该记录*/ • printf(“UPDATE AGE? ”); • /*问用户是不是修改*/ • scanf(“% c”,& yn); • if (yn=‘y’ or yn=‘Y’) • /*需要修改*/ • { • printf “INPUT NEW AGE :”); • scanf(“% d”,& NEW Age); • EXEC SQL UPDATE Student • SET Sage= :NEWAge • WHERE CURRENT OF SX;