西华师范大学计算机学院
第三章 关系数据库标准语言 SQL
(续 4)
第三章 关系数据库标准语言 SQL
3.1 SQL概述
3.2 数据定义
3.3 查询
3.4 数据更新
3.5 视图
3.6 数据控制
3.7 嵌入式 SQL
3.8 小结
3.7 嵌 入 式 SQL
? SQL语言提供了两种不同的使用方式:
– 交互式, SQL语句作为独立的数据语言,以交互的方式使用
– 嵌入式,用某种传统的编程语言(例如,C,PASCAL、
COBOL等)编写程序,但程序中的某些函数或某些语句是
SQL语句。这种方式下使用的 SQL语言称为嵌入式 SQL
( EmbeddedSQL),其中传统的编程语言称为宿主语言
(或主语言)
? 为什么要引入嵌入式 SQL
– SQL语言是非过程性语言,事务处理应用需要程序根据不同
的条件执行不同的任务,如果单单使用 SQL语言,很难实
现这类应用。
? 这两种方式细节上有差别,在程序设计的环境下,SQL语句
要做某些必要的扩充
? DBMS有两种方法处理嵌入式 SQL语言:
预编译和扩充编译程序法 。
? 预编译是指由 DBMS的预编译器对源程
序进行扫描, 识别出其中的 SQL语句,
把它们转换为宿主语言调用语句, 使宿
主语言编译器能够识别, 最后由编译器
将整个源程序编译为目标码 。
? 扩充编译程序法是指修改和扩充宿主语
言的编译程序, 使其能够直接处理 SQL
语句 。 目前使用较多的是预编译方法,
其处理过程如下图所示 。
嵌入式 SQL语句的处理过程
预处理程序 编译器
S Q L 函数库
宿主语言+
函数调用
目标代码
宿主语言+
嵌入式 S Q L
? 其中关键的一步,是将嵌有 SQL的宿主
语言源代码通过预编译器( Precomplier)变成
纯宿主语言源代码。 RDBMS除了提供 SQL语
言接口外,一般都提供一批用宿主语言编写的
SQL函数,供应用程序调用 DBMS的各种功能。
如建立与 DBMS的连接及连接的环境、传送
SQL语句、执行 SQL语句、返回执行结果和状
态等等。这些函数组成 SQL函数库。预编译器
将 SQL语句编译成宿主语言对 SQL函数的调用,
从而把嵌有 SQL的宿主语言源代码变成纯宿主
语言源代码,在编译连接后执行。
使用嵌入式 SQL必须解决以下几个问题:
(1)预编译器不能识别和接受 SQL语句, 因
此, 嵌入式程序中, 应有区分 SQL语句
与宿主语言语句的标记 。
(2)DBMS和宿主语言程序 ( 程序工作单元 )
如何进行信息传递 。
(3)一条 SQL语句原则上可产生或处理一组
记录, 而宿主语言一次只能处理一个记
录, 必须协调这两种处理方式 。
3.7.1嵌入式 SQL的一般形式
? 为了区分 SQL语句与主语言语句,需要,
? 前缀,EXEC SQL
? 结束标志:随主语言的不同而不同
? 以 C为主语言的嵌入式 SQL语句的一般形式
EXEC SQL <SQL语句 >;
例,EXEC SQL DROP TABLE Student;
? 以 COBOL作为主语言的嵌入式 SQL语句的一般形式
EXEC SQL <SQL语句 > END-EXEC
例,EXEC SQL DROP TABLE Student END-EXEC
嵌入 SQL语句
说明性语句
嵌入 SQL语句 数据定义
可执行语句 数据控制
数据操纵
? 允许出现可执行的高级语言语句的地方,都可以写可
执行 SQL语句
? 允许出现说明语句的地方,都可以写说明性 SQL语句
3.7.2 嵌入式 SQL语句与主语言之间的通信
将 SQL嵌入到高级语言中混合编程,程序中会含
有两种不同计算模型的语句
– SQL语句
? 描述性的面向集合的语句
? 负责操纵数据库
– 高级语言语句
? 过程性的面向记录的语句
? 负责控制程序流程
工作单元之间的通信方式
1,SQL通信区
向主语言传递 SQL语句的执行状态信息,主语言能够据此控制
程序流程
2,主变量
1)主语言向 SQL语句提供参数
2)将 SQL语句查询数据库的结果交主语言进一步处理
3,游标
解决集合性操作语言与过程性操作语言的不匹配
1,SQL通信区
? SQLCA,SQL Communication Area
– SQLCA是一个数据结构,它是系统定义的主变量(全局
变量)
? SQLCA的用途
– SQL语句执行后,DBMS反馈给应用程序信息
? 描述系统当前工作状态
? 描述运行环境
– 这些信息将送到 SQL通信区 SQLCA中
– 应用程序从 SQLCA中取出这些状态信息,据此决定接下
来执行的语句
SQLCA的内容
? 与所执行的 SQL语句有关
? 与该 SQL语句的执行情况有关
例:在执行删除语句 DELETE后,不同的执行情况,SQLCA中有
不同的信息:
? 违反数据保护规则,操作拒绝
? 没有满足条件的行,一行也没有删除
? 成功删除,并有删除的行数
? 无条件删除警告信息
? 由于各种原因,执行出错
SQLCA的使用方法
– 定义 SQLCA
? 用 EXEC SQL INCLUDE SQLCA加以定义
– 使用 SQLCA
? SQLCA中有一个整型分量 SQLCODE,供 DBMS向应用
程序报告 SQL语句的执行情况
? 如果 SQLCODE等于预定义的常量 SUCCESS,则表示
SQL语句成功,否则表示出错
? 应用程序每执行完一条 SQL 语句之后都应该测试
一下 SQLCODE的值,以了解该 SQL语句执行情况并
做相应处理
不同的系统, SQLCODE代码值的含义可能
不完全相同 。 一般约定:
? SQLCODE=0,表示语句执行成功, 无异
常情况;
? SQLCODE为负整数, 表示 SQL语句执行
失败, 具体负值表示错误的类别;
? SQLCODE为正整数, 表示 SQL语句已执
行, 但 出 现 了 例 外 情 况 。 如
SQLCODE=100,表示语句已执行, 但无
数据可取 ( 如,DB中无满足条件的数
据 ) 。
2,主变量
? 什么是主变量
– 嵌入式 SQL语句中可以使用主语言的程序变
量来输入或输出数据
– 在 SQL语句中使用的宿主语言程序变量简称
为主变量( Host Variable)
主变量(续)
? 主变量的类型
– 输入主变量
? 由应用程序对其赋值,SQL语句引用
– 输出主变量
? 由 SQL语句赋值或设置状态信息,返回给
应用程序
– 一个主变量有可能既是输入主变量又是输出
主变量
主变量(续)
? 主变量的用途
– 输入主变量
? 指定向数据库中插入的数据
? 将数据库中的数据修改为指定值
? 指定执行的操作
? 指定 WHERE子句或 HAVING子句中的条件
– 输出主变量
? 获取 SQL语句的结果数据
? 获取 SQL语句的执行状态
主变量(续)
? 指示变量
– 一个主变量可以附带一个指示变量( Indicator
Variable)
– 什么是指示变量
? 整型变量
? 用来“指示”所指主变量的值或条件
– 指示变量的用途
? 输入主变量可以利用指示变量赋空值
? 输出主变量可以利用指示变量检测出是否空值,
值是否被截断
主变量(续)
? 在 SQL语句中使用主变量和指示变量的方法
– 1) 说明主变量和指示变量
BEGIN DECLARE SECTION
........,
........,(说明主变量和指示变量 )
.........
END DECLARE SECTION
中间的内容称为说明段。说明段中变量说明的格
式必须符合宿主语言的要求,而且变量的数据类型应
该是宿主语言和 SQL都能处理的类型,如整型、实型、
字符串型等,C语言中不允许主变量为数组或结构。
主变量(续)
– 2) 使用主变量
? 说明之后的主变量可以在 SQL语句中任何
一个能够使用表达式的地方出现
? 为了与数据库对象名(表名、视图名、列
名等)区别,SQL语句中的主变量名前要
加冒号(,)作为标志
主变量(续)
– 3) 使用指示变量
? 指示变量前也必须加冒号标志
? 必须紧跟在所指主变量之后
主变量(续)
? 在 SQL语句之外 (主语言语句中 )使用主变
量和指示变量的方法
– 可以直接引用,不必加冒号
3,游标( cursor)
? 为什么要使用游标
– SQL语言与主语言具有不同数据处理方式
? SQL语言是面向集合的,一条 SQL语句原
则上可以产生或处理多条记录
游标(续)
? 主语言是面向记录的,一组主变量一次
只能存放一条记录
– 仅使用主变量并不能完全满足 SQL语句向应
用程序输出数据的要求
– 嵌入式 SQL引入了游标的概念,用来协调这
两种不同的处理方式
游标(续)
? 什么是游标
– 游标是系统为用户开设的一个数据缓冲区,
存放 SQL语句的执行结果
– 每个游标区都有一个名字
– 用户可以用 SQL语句逐一从游标中获取记录,
并赋给主变量,交由主语言进一步处理
嵌入式 SQL语句与主语言之间的通信 (续 )
? 小结
– 在嵌入式 SQL中,SQL语句与主语言语句分工非常
明确
? SQL语句:直接与数据库打交道
? 主语言语句
1,控制程序流程
2,对 SQL语句的执行结果做进一步
加工处理
嵌入式 SQL语句与主语言之间的通信 (续 )
– SQL语句用主变量从主语言中接收执行参数,操纵
数据库
– SQL语句的执行状态由 DBMS送至 SQLCA中
– 主语言程序从 SQLCA中取出状态信息,据此决定下
一步操作
– 如果 SQL语句从数据库中成功地检索出数据,则通
过主变量传给主语言做进一步处理
– SQL语言和主语言的不同数据处理方式通过游标来
协调
嵌入式 SQL语句与主语言之间的通信 (续 )
例:带有嵌入式 SQL的一小段 C程序
............
EXEC SQL INCLUDE SQLCA;
/* (1) 定义 SQL通信区 */
EXEC SQL BEGIN DECLARE SECTION;
/* (2) 说明主变量 */
CHAR title_id(7);
CHAR title(81);
INT royalty;
EXEC SQL END DECLARE SECTION;
嵌入式 SQL语句与主语言之间的通信 (续 )
main()
{
EXEC SQL DECLARE C1 CURSOR FOR
SELECT tit_id,tit,roy FROM titles;
/* (3) 游标操作(定义游标) */
/* 从 titles表中查询 tit_id,tit,roy */
EXEC SQL OPEN C1;
/* (4) 游标操作(打开游标) */
嵌入式 SQL语句与主语言之间的通信 (续 )
for(;;)
{
EXEC SQL FETCH C1 INTO,title_id,:title,:royalty;
/* (5) 游标操作(将当前数据放入主变量并推进游标指针) */
if (sqlca.sqlcode <> SUCCESS)
/* (6) 利用 SQLCA中的状态信息决定何时退出循环 */
break;
printf("Title ID,%s,Royalty,%d",:title_id,:royalty);
printf("Title,%s",:title);
/* 打印查询结果 */
}
EXEC SQL CLOSE C1;
/* (7) 游标操作(关闭游标) */
}
3.7 嵌 入 式 SQL
3.7.1 嵌入式 SQL的一般形式
3.7.2 嵌入式 SQL语句与主语言之间的通信
3.7.3 不用游标的 SQL语句
3.7.4 使用游标的 SQL语句
3.7.5 动态 SQL简介
3.7.3 不用游标的 SQL语句
? 不用游标的 SQL语句的种类
– 说明性语句
– 数据定义语句
– 数据控制语句
– 查询结果为单记录的 SELECT语句
– 非 CURRENT形式的 UPDATE语句
– 非 CURRENT形式的 DELETE语句
– INSERT语句
一、说明性语句
? 说明性语句是专为在嵌入式 SQL中说明
主变量,SQLCA等而设置的
? 说明主变量
1,EXEC SQL BEGIN DECLARE SECTION;
2,EXEC SQL END DECLARE SECTION;
– 这两条语句必须配对出现,相当于一个括号,
两条语句中间是主变量的说明
? 说明 SQLCA
3,EXEC SQL INCLUDE SQLCA
二、数据定义语句
例 1 建立一个“学生”表 Student
EXEC SQL CREATE TABLE Student
(Sno CHAR(5) NOT NULL UNIQUE,
Sname CHAR(20),
Ssex CHAR(1),
Sage INT,
Sdept CHAR(15));
数据定义语句(续)
? 数据定义语句中不允许使用主变量
例:下列语句是错误的
EXEC SQL DROP
TABLE,table_name;
三、数据控制语句
例 2 把查询 Student表权限授给用户 U1
EXEC SQL GRANT SELECT ON
TABLE Student TO U1;
四、查询结果为单记录的 SELECT语句
? 语句格式
EXEC SQL SELECT [ALL|DISTINCT]
<目标列表达式 >[,<目标列表达式 >]...
INTO <主变量 >[<指示变量 >]
[,<主变量 >[<指示变量 >]]..,
FROM <表名或视图名 >[,<表名或视图名 >],..
[WHERE <条件表达式 >]
[GROUP BY <列名 1> [HAVING <条件表达式 >]]
[ORDER BY <列名 2> [ASC|DESC]];
查询结果为单记录的 SELECT语句(续)
– 对交互式 SELECT语句的扩充就是多了一个
INTO子句
? 把从数据库中找到的符合条件的记录,放
到 INTO子句指出的主变量中去。
查询结果为单记录的 SELECT语句(续)
? 使用注意事项
– 1,使用主变量
? INTO子句
? WHERE子句的条件表达式
? HAVING短语的条件表达式
查询结果为单记录的 SELECT语句(续)
– 2,使用指示变量
? 指示变量只能用于 INTO子句中
? 如果 INTO子句中主变量后面跟有指示变量,则
当查询得出的某个数据项为空值时,系统会自动
将相应主变量后面的指示变量置为负值,但不向
该主变量执行赋值操作,即主变量值仍保持执行
SQL语句之前的值
? 当发现指示变量值为负值时,不管主变量为何值,
均应认为主变量值为 NULL
查询结果为单记录的 SELECT语句(续)
– 3,查询结果为空集
? 如果数据库中没有满足条件的记录,即查
询结果为空,则 DBMS将 SQLCODE的值
置为 100
– 4,查询结果为多条记录
? 程序出错,DBMS会在 SQLCA中返回错误
信息
查询结果为单记录的 SELECT语句(续)
例 3 根据学生号码查询学生信息。
假设已将要查询的学生的学号赋给了主变量 givensno
EXEC SQL SELECT Sno,Sname,Ssex,Sage,Sdept
INTO,Hsno,:Hname,:Hsex,:Hage,:Hdept
FROM Student
WHERE Sno=:givensno;
– Hsno,Hname,Hsex,Hage,Hdept和 givensno均是主变量,
并均已在前面的程序中说明过了。
查询结果为单记录的 SELECT语句(续)
例 4 查询某个学生选修某门课程的成绩。
假设已将要查询的学生的学号赋给了主变量
givensno,将课程号赋给了主变量 givencno。
EXEC SQL SELECT Sno,Cno,Grade
INTO,Hsno,:Hcno,:Hgrade:Gradeid
FROM SC
WHERE Sno=:givensno AND Cno=:givencno;
查询结果为单记录的 SELECT语句(续)
? 从提高应用程序的数据独立性角度考虑,
SELECT语句在任何情况下都应该使用游

– 对于仅返回一行结果数据的 SELECT语句虽
然可以不使用游标
– 但如果以后数据库改变了,该 SELECT语句
可能会返回多行数据,这时该语句就会出错
五、非 CURRENT形式的 UPDATE语句
? 非 CURRENT形式的 UPDATE语句
– 使用主变量
? SET子句
? WHERE子句
– 使用指示变量
? SET子句
? 非 CURRENT形式的 UPDATE语句可以操作多条元

非 CURRENT形式的 UPDATE语句(续)
例 5 将全体学生 1号课程的考试成绩增加若
干分。
假设增加的分数已赋给主变量 Raise
EXEC SQL UPDATE SC
SET Grade=Grade+:Raise
WHERE Cno='1';
非 CURRENT形式的 UPDATE语句(续)
例 6 修改某个学生 1号 课程的成绩。
假设该学生的学号已赋给主变量 givensno,
修改后的成绩已赋给主变量 newgrade。
EXEC SQL UPDATE SC
SET Grade=:newgrade
WHERE Sno=:givensno and Cno='1';
非 CURRENT形式的 UPDATE语句(续)
例 7 将计算机系全体学生年龄置 NULL值
Sageid=-1;
EXEC SQL UPDATE Student
SET Sage=:Raise:Sageid
WHERE Sdept='CS';
非 CURRENT形式的 UPDATE语句(续)
– 将指示变量 Sageid赋一个负值后,无论主变
量 Raise为何值,DBMS都会将 CS系所有记
录的年龄属性置空值。它等价于:
EXEC SQL UPDATE Student
SET Sage=NULL
WHERE Sdept='CS';
六、非 CURRENT形式的 DELETE语句
? 非 CURRENT形式的 DELETE语句
– 使用主变量
? WHERE子句
? 非 CURRENT形式的 DELETE语句可以操
作多条元组
非 CURRENT形式的 DELETE语句(续)
例 8 某个学生退学了,现要将有关他的所有选课
记录删除掉。
假设该学生的姓名已赋给主变量 stdname
EXEC SQL DELETE
FROM SC
WHERE Sno=
(SELECT Sno
FROM Student
WHERE Sname=:stdname);
七,INSERT语句
? 非 CURRENT形式的 INSERT语句
– 使用主变量
? VALUES子句
– 使用指示变量
? VALUES子句
? 非 CURRENT形式的 INSERT语句一次只
能输入一条元组
INSERT语句(续)
例 9 某个学生新选修了某门课程,将有关记录插入 SC表
假设学生的学号已赋给主变量 stdno,课程号已赋给主变
量 couno。
gradeid=-1;
EXEC SQL INSERT
INTO SC(Sno,Cno,Grade)
VALUES(:stdno,:couno,:gr:gradeid);
– 由于该学生刚选修课程,尚未考试,因此成绩列为空。
所以本例中用指示变量指示相应的主变量为空值。
3.7.4 使用游标的 SQL语句
? 必须使用游标的 SQL语句
– 查询结果为多条记录的 SELECT语句
– CURRENT形式的 UPDATE语句
– CURRENT形式的 DELETE语句
一,查询结果为多条记录的 SELECT语句
? 使用游标的步骤
– 1,说明游标
– 2,打开游标
– 3,移动游标指针,然后取当前记录
– 4,关闭游标
1,说明游标
? 使用 DECLARE语句
? 语句格式
EXEC SQL DECLARE <游标名 > CURSOR
FOR <SELECT语句 >;
? 功能
– 是一条说明性语句,这时 DBMS并不执行
SELECT指定的查询操作。
2,打开游标
? 使用 OPEN语句
? 语句格式
EXEC SQL OPEN <游标名 >;
? 功能
– 打开游标实际上是执行相应的 SELECT语句,把所
有满足查询条件的记录从指定表取到 缓冲区 中
– 这时游标处于活动状态,指针指向查询结果集中 第
一条记录之前
3,移动游标指针,然后取当前记录
? 使用 FETCH语句
? 语句格式
EXEC SQL FETCH [[NEXT|PRIOR|
FIRST|LAST] FROM] <游标名 >
INTO <主变量 >[<指示变量 >]
[,<主变量 >[<指示变量 >]]...;
移动游标指针,然后取当前记录(续)
? 功能
– 指定方向推动游标指针,然后将缓冲区中的当前记
录取出来送至主变量供主语言进一步处理。
– NEXT|PRIOR|FIRST|LAST:指定推动游标指针的方
式。
? NEXT:向前推进一条记录
? PRIOR:向回退一条记录
? FIRST:推向第一条记录
? LAST:推向最后一条记录
? 缺省值为 NEXT
移动游标指针,然后取当前记录(续)
? 说明
– (1) 主变量必须与 SELECT语句中的目标列表达式具
有一一对应关系
– (2) FETCH语句通常用在一个循环结构中,通过循
环执行 FETCH语句逐条取出结果集中的行进行处理
– (3) 为进一步方便用户处理数据,现在一些关系数据
库管理系统对 FETCH语句做了扩充,允许用户向任
意方向以任意步长移动游标指针
4,关闭游标
? 使用 CLOSE语句
? 语句格式
EXEC SQL CLOSE <游标名 >;
? 功能
– 关闭游标,释放结果集占用的缓冲区及其他资源
? 说明
– 游标被关闭后,就不再和原来的查询结果集相联系
– 被关闭的游标可以再次被打开,与新的查询结果相
联系
例题
例 1 查询某个系全体学生的信息(学号、姓名、
性别和年龄)。要查询的系名由用户在程序运
行过程中指定,放在主变量 deptname中
......
.....,
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
例题(续)
......
/* 说明主变量 deptname,HSno,HSname,HSsex,HSage等
*/
......
......
EXEC SQL END DECLARE SECTION;
......
......
gets(deptname); /* 为主变量 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; /* 关闭游标 */
......
......
例题(续)
例 2 查询某些系全体学生的信息。
......
......
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
......
/* 说明主变量 deptname,HSno,HSname,HSsex,HSage
等 */
......
......
例题(续)
EXEC SQL END DECLARE SECTION;
......
......
......
EXEC SQL DECLARE SX CURSOR FOR
SELECT Sno,Sname,Ssex,Sage
FROM Student
WHERE SDept=:deptname; /* 说明游标 */
例题(续)
WHILE (gets(deptname)!=NULL) /* 接收主变量
deptname的值 */
{
/* 下面开始处理 deptname指定系的学生信息,
每次循环中 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; /* 关闭游标 */
}; /* 外循环结束 */
......
......
二,CURRENT形式的 UPDATE语句和 DELETE语句
? CURRENT形式的 UPDATE语句和
DELETE语句的用途
– 非 CURRENT形式的 UPDATE语句和
DELETE语句
? 面向集合的操作
? 一次修改或删除所有满足条件的记录
二,CURRENT形式的 UPDATE语句和 DELETE语句
? CURRENT形式的 UPDATE语句和
DELETE语句的用途(续)
– 如果只想修改或删除其中某个记录
? 用带游标的 SELECT语句查出所有满足条
件的记录
? 从中进一步找出要修改或删除的记录
? 用 CURRENT形式的 UPDATE语句和
DELETE语句修改或删除之
CURRENT形式的 UPDATE语句和 DELETE语句(续)
? 步骤
– (1) DECLARE
? 说明游标
– (2) OPEN
? 打开游标,把所有满足查询条件的记录从指定
表取至缓冲区
– (3) FETCH
? 推进游标指针,并把当前记录从缓冲区中取出来
送至主变量
CURRENT形式的 UPDATE语句和 DELETE语句(续)
– (4) 检查该记录是否是要修改或删除的
记录,是则处理之
– (5) 重复第 (3)和 (4)步,用逐条取出结果
集中的行进行判断和处理
– (6) CLOSE
? 关闭游标,释放结果集占用的缓冲区和
其他资源
CURRENT形式的 UPDATE语句和 DELETE语句(续)
? 说明游标
– 为 UPDATE语句说明游标
? 使用带 FOR UPDATE OF <列名 >短语的
DECLARE语句
? 语句格式
EXEC SQL DECLARE <游标名 > CURSOR
FOR <SELECT语句 > FOR UPDATE
OF <列名 >;
? FOR UPDATE OF <列名 >短语用于指明检索出的
数据在指定列上是可修改的,以便 DBMS进行并
发控制
CURRENT形式的 UPDATE语句和 DELETE语句(续)
– 为 DELETE语句说明游标
? 语句格式
EXEC SQL DECLARE <游标名 > CURSOR
FOR <SELECT语句 >;
CURRENT形式的 UPDATE语句和 DELETE语句(续)
? 修改或删除当前记录
– 经检查缓冲区中记录是要修改或删除的记录,
则用 UPDATE语句或 DELETE语句修改或删
除该记录
– 语句格式
? <UPDATE语句 > WHERE CURRENT OF <游标名 >
? <DELETE语句 > WHERE CURRENT OF <游标名 >
– WHERE CURRENT OF <游标名 >子句表示修改
或删除的是该游标中最近一次取出的记录
CURRENT形式的 UPDATE语句和 DELETE语句(续)
? 当游标定义中的 SELECT语句带有
UNION或 ORDER BY子句时,或者该
SELECT语句相当于定义了一个不可更新
的视图时,不能使用 CURRENT形式的
UPDATE语句和 DELETE语句
例题
例 3 对某个系的学生信息,根据用户的要
求修改其中某些人的年龄字段。
– 思路
? 查询某个系全体学生的信息 (要查询的系
名由主变量 deptname指定)
? 然后根据用户的要求修改其中某些记录
的年龄字段
例题(续)
......
......
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
......
/* 说明主变量
deptname,HSno,HSname,HSsex,HSage,NEWAge等 */
......
例题(续)
......
EXEC SQL END DECLARE SECTION;
......
......
gets(deptname); /* 为主变量 deptname赋值 */
......
例题(续)
EXEC SQL DECLARE SX CURSOR FOR
SELECT Sno,Sname,Ssex,Sage
FROM Student
WHERE SDept=:deptname
FOR UPDATE OF Sage; /* 说明游标 */
EXEC SQL OPEN SX /* 打开游标 */
例题(续)
WHILE(1) {/* 用循环结构逐条处理结果集中的记录 */
EXEC SQL FETCH SX INTO,HSno,:HSname,
:HSsex,:HSage;
/* 将游标指针向前推进一行,然后从结果集
中取当前行,送相应主变量 */
例题(续)
if (sqlca.sqlcode <> SUCCESS)
break;
/* 若所有查询结果均已处理完或
出现 SQL语句错误,则退出循环 */
printf("%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",&NEWAge); /* 输入新的年龄值 */
EXEC SQL UPDATE Student
SET Sage=:NEWAge
WHERE CURRENT OF SX;
/* 修改当前记录的年龄字段 */
};
例题(续)
......
......
};
EXEC SQL CLOSE SX; /* 关闭游标 */
......
......
例题(续)
例 4 对某个系的学生信息,根据用户的要求删
除其中某些人的记录。
......
......
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
......
/* 说明主变量 deptname,HSno,HSname,HSsex,HSage
等 */
例题(续)
......
......
EXEC SQL END DECLARE SECTION;
......
......
gets(deptname); /* 为主变量 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,:HS
age;
/* 将游标指针向前推进一行,然后从结
果集中取当前行,送相应主变量 */
例题(续)
if (sqlca.sqlcode <> SUCCESS)
break;
/* 若所有查询结果均已处理完或
出现 SQL语句错误,则退出循环 */
printf("%s,%s,%s,%d",Sno,Sname,Ssex,Sage);
/* 显示该记录 */
例题(续)
printf("DELETE? "); /* 问用户是否要删除 */
scanf("%c",&yn);
if (yn='y' or yn='Y') /* 需要删除 */
EXEC SQL DELETE
FROM Student
WHERE CURRENT OF SX; /* 删除当前记录 */
例题(续)
......
......
};
EXEC SQL CLOSE SX; /* 关闭游标 */
......
......
3.7 嵌 入 式 SQL
3.7.1 嵌入式 SQL的一般形式
3.7.2 嵌入式 SQL语句与主语言之间的通信
3.7.3 不用游标的 SQL语句
3.7.4 使用游标的 SQL语句
3.7.5 动态 SQL简介
3.7.5 动态 SQL简介
? 静态嵌入式 SQL
? 动态嵌入式 SQL
一、静态 SQL的特点
? 用户可以在程序运行过程中根据实际需
要输入 WHERE子句或 HAVING子句中某
些变量的 值 。
? 语句中主变量的 个数与数据类型 在预编
译时都是确定的,只有主变量的 值 是程
序运行过程中动态输入的。
静态 SQL的不足
静态 SQL语句提供的编程 灵活性 在许多情况下
仍显得不足,不能编写更为通用的程序。
需求
例,对 SC:
– 任课教师想查选修某门课程的所有学生的学
号及其成绩
– 班主任想查某个学生选修的所有课程的课程
号及相应成绩
– 学生想查某个学生选修某门课程的成绩
即:查询 条件是不确定 的,要查询的 属性列 也
是不确定的
二、动态 SQL
1,什么是动态嵌入式 SQL
– 动态 SQL方法允许在程序运行过程中临时,组
装, SQL语句。
2,应用范围
– 在 预编译 时下列信息不能确定时
? SQL语句正文
? 主变量个数
? 主变量的数据类型
? SQL语句中引用的数据库对象(列、索引、基本表、视图
等)
动态 SQL(续)
3,动态 SQL的形式
– 语句可变
? 临时构造完整的 SQL语句
– 条件可变
? WHERE子句中的条件
? HAVING短语中的条件
– 数据库对象、查询条件均可变
? SELECT子句中的列名
? FROM子句中的表名或视图名
? WHERE子句中的条件
? HAVING短语中的条件
? 使用动态 SQL技术更多的是涉及程序设计方面的
知识,而不是 SQL语言本身
SQL SERVER 2000中游标的使

游标是一个实体, 它映射了一个结果集,
并在结果集中单独一行上建立了一个位
置 。
1,使用 declare cursor语句声明游标, 并使
用 open语句填充该游标
2,使用 fetch语句从游标中检索行
3, 使用 close 语 句 关 闭 游 标, 并使用
deallocate语句释放游标
示例
use pubs
declare authorscursor cursor for
select * from authors
order by au_lname //声明游标
open authorscursor //打开游标
fetch next from authorscursor //从游标中检索行
update authors
set phone='415 658-9932'
where current of authorscursor//修改游标中当前行数据
close authorscursor//关闭游标
deallocate authorscursor//释放游标
第三章 关系数据库标准语言 SQL
3.1 SQL概述
3.2 数据定义
3.3 查询
3.4 数据更新
3.5 视图
3.6 数据控制
3.7嵌入式 SQL
3.8 小结
3.8 小 结
SQL的特点
– ⒈ 综合统一
– 2,高度非过程化
– 3,面向集合的操作方式
– 4,同一种语法结构提供两种使用方式
– 5,语言简捷,易学易用
小结(续)
交互式 SQL
– 数据定义
– 查询
– 数据更新
– 数据控制
小结(续)
表 3.1 SQ L 语言的动词
SQ L 功能 动 词
数 据 查 询 SE L E C T
数 据 定 义 C R E A T E, D R O P, A L T E R
数 据 操 纵 I N S E R T, U P D A T E,
DELETE
数 据 控 制 G R A N T, R E V O K E
小结(续)
嵌入式 SQL
– 与主语言的通信方式
1,SQL通信区
– 向主语言传递 SQL语句的执行状态信息
2,主变量
– 1)主语言向 SQL语句提供参数
– 2)将 SQL语句查询数据库的结果交主语言进一步处理
3,游标
– 解决集合性操作语言与过程性操作语言的不匹配
小结(续)
嵌入式 SQL(续 )
– 静态 SQL
? 不用游标
– 不需要返回结果数据的 SQL语句
– 只返回一条结果的 SQL语句
? 使用游标
– 说明游标
– 打开游标
– 推进游标并取当前记录
– 关闭游标
– 动态 SQL