3.6 嵌 入 式 SQL
嵌入式 SQL的一般形式嵌入式 SQL语句与主语言之间的通信
3.6 嵌 入 式 SQL
SQL语言提供了两种不同的使用方式:
交互式
嵌入式
为什么要引入嵌入式 SQL
SQL语言是非过程性语言
事务处理应用需要高级语言
这两种方式细节上有差别,在程序设计的环境下,SQL语句要做某些必要的扩充一,嵌入式 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
DBMS处理宿主型数据库语言 SQL 的方法
预编译目的:
修改和扩充主语言使之能处理 SQL语句
预编译:
1,由 DBMS的预处理程序对源程序进行扫描,识别出 SQL语句
2.把它们 转换 成主语言调用语句,以使主语言编译程序能识别它
3.最后由主语言的编译程序将整个源程序 编译 成目标码。
二、嵌入式 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的使用方法
定义 SQLCA
用 EXEC SQL INCLUDE SQLCA加以定义
使用 SQLCA
SQLCA中有一个存放每次执行 SQL语句后返回代码的 变量 SQLCODE
如果 SQLCODE等于预定义的常量 SUCCESS,
则表示 SQL语句成功,否则表示出错
应用程序 每执行完一条 SQL 语句之后都应该测试一下 SQLCODE的值,以了解该 SQL语句执行情况并做相应处理
2,主变量
什么是主变量
嵌入式 SQL语句中可以使用 主语言的程序变量 来输入或输出数据
在 SQL语句中使用的主语言程序变量简称为主变量( Host
Variable)
主变量的类型
输入主变量
由应用程序对其赋值,SQL语句引用
输出主变量
由 SQL语句赋值或设置状态信息,返回给应用程序
一个主变量有可能既是输入主变量又是输出主变量主变量(续)
主变量的用途
输入主变量
指定 向数据库中 插入 的数据
将数据库中的数据 修改 为指定值
指定执行的操作
指定 WHERE子句或 HAVING子句中的条件
输出主变量
获取 SQL语句的 结果数据
获取 SQL语句的 执行状态主变量(续)
在 SQL语句中使用主变量的方法
1) 说明主变量和指示变量
BEGIN DECLARE SECTION
........,
........,(说明主变量 )
.........
END DECLARE SECTION
2) 使用主变量
说明之后 的主变量可以在 SQL语句中任何一个能够使用表达式的地方出现
为了与数据库对象名(表名、视图名、列名等)区别,
SQL语句中的主变量名前要加冒号(,)作为标志
3,游标( cursor)
为什么要使用游标
SQL语言与主语言具有 不同数据处理方式
SQL语言是面向集合的
主语言是面向记录的
什么是游标
游标是系统为用户开设的 一个数据缓冲区,存放
SQL语句的 执行结果
每个游标区都有一个名字
用户可以用 SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理嵌入式 SQL语句与主语言之间的通信 小结
在嵌入式 SQL中,SQL语句与主语言语句分工非常明确
SQL语句:直接与数据库打交道
主语言语句
1,控制程序流程
2,对 SQL语句的执行结果做进一步加工处理
SQL语句用主变量从主语言中接收执行参数,操纵数据库
SQL语句的执行状态由 DBMS送至 SQLCA中
主语言程序从 SQLCA中取出状态信息,据此决定下一步操作
如果 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 事务处理一、什么是事务二、如何定义事务三、事务的特性四,并发事务处理 —— 加锁一、什么是事务
事务 (Transaction)是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位
事务和程序是两个概念
在关系数据库中,一个事务可以是一条 SQL语句,
一组 SQL语句或整个程序
一个应用程序通常包含多个事务
事务是 恢复和并发控制 的基本单位二、如何定义事务
显式定义方式
BEGIN TRANSACTION BEGIN TRANSACTION
SQL 语句 1 SQL 语句 1
SQL 语句 2 SQL 语句 2
。。。。。 。。。。。
COMMIT ROLLBACK
隐式方式当用户没有显式地定义事务时,
DBMS按缺省规定自动划分事务事务结束
COMMIT
事务正常结束提交 事务的所有操作( 读 +更新 )
事务中所有对数据库的更新 永久 生效
ROLLBACK
事务异常终止
事务运行的过程中发生了故障,不能继续执行回滚事务的所有 更新 操作
事务回滚到 开始 时的状态三、事务的特性 (ACID特性 )
1,原子性( Atomicity)
事务是数据库的逻辑工作单位
事务中包括的诸操作要么都做,
要么都不做
2,一致性( Consistency)
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态
一致性状态,
数据库中只包含成功事务提交的结果银行转帐:
从帐号 A中取出一万元,存入帐号 B。
定义一个事务,该事务包括两个操作
这两个操作要么全做,要么全不做
全做或者全不做,数据库都处于一致性状态。
如果只做一个操作,数据库就处于不一致性状态。
B=B+1
A=A-1
BA
3,隔离性 ( Isolation)
对并发执行而言一个事务的执行不能被其他事务干扰读 A=16
A← A-3
写回 A=13
① 读 A=16

③ A← A-1
写回 A=15

T2T1
T1的修改被 T2覆盖了!
4,永久性 ( Permanence)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
事务的特性
保证事务 ACID特性是事务处理的任务
破坏事务 ACID特性的因素
多个事务并行运行时,不同事务的操作交叉执行
事务在运行过程中被强行停止
关系数据库系统 通过日志和加锁来实现事务处理 。
T1的修改被 T2覆盖了!
读 A=16
A← A-3
写回 A=13
① 读 A=16

③ A← A-1
写回 A=15

事务 T2事务 T1
数据不一致实例:
飞机订票系统四、并发事务处理 ——加锁多事务的并发执行带来的问题并发操作带来三种数据不一致性
T1 T2
① 读
A=16


A← A-1
写回
A=15


A=16
A← A-1
写回
A=15
(a) 丢失修改读 B=100
B← B*2
写回 B=200
① 读 A=50
读 B=100
求和 =150

③ 读 A=50
读 B=200
求和 =250
(验算不对 )
T2T1
(b) 不可重复读读 C=200
① 读 C=100
C← C*2
写回 C

③ ROLLBACK
C恢复为 100
T2T1
(c) 读“脏”数据实现并发控制的技术 ——封锁
封锁就是事务 T在对某个数据对象(例如表、记录等)操作之前,
先向系统发出请求,对其加锁
加锁后事务 T就对该数据对象有了一定的控制,在事务 T释放它的锁之前,其它的事务不能更新此数据对象。
什么是封锁基本封锁类型排它锁 ( eXclusive lock,X锁,写锁)若事务 T对数据对象 A加上 X锁,
则只允许 T读取和修改 A,其它任何事务都不能再对 A加任何类型的锁,
直到 T释放 A上的锁共享锁 ( Share lock,S锁,读锁)若事务 T对数据对象 A加上 S锁,则其它事务只能再对 A加 S锁,而不能加 X锁,直到 T释放 A上的 S锁
1级封锁协议
T1 T2
① Xlock A
获得
② 读 A=16
③ A← A-1
写回 A=15
Commit
Unlock A


Xlock A
等待等待等待等待获得 Xlock A
读 A=15
A← A-1
写回 A=14
Commit
Unlock A
没有丢失修改读 A=15
① Xlock A
获得
② 读 A=16
A← A-1
写回 A=15

④ Rollback
Unlock A
T2T1
读“脏”数据
Xlock B
获得读 B=100
B← B*2
写回 B=200
Commit
Unlock B
① 读 A=50
读 B=100
求和 =150

③ 读 A=50
读 B=200
求和 =250
(验算不对 )
T2T1
不可重复读
事务 T在 修改数据 R之前 必须先对其加 X锁,
直到 事务结束才 释放
2级封锁协议不可重复读
① Sclock A
获得读 A=50
Unlock A
② Sclock B
获得读 B=100
Unlock B
③ 求和 =150
Xlock B
等待等待获得 Xlock B
读 B=100
B← B*2
写回 B=200
Commit
Unlock B
T2T1
④ Sclock A
获得读 A=50
Unlock A
Sclock B
获得读 B=200
Unlock B
求和 =250
(验算不对 )
T2T1 (续 )
1级封锁协议 +事务 T在 读取数据 R前 必须 先加 S
锁,读完后 即可释放 S锁可以防止丢失修改和读“脏”
数据,不能保证可重复读。
3级封锁协议
T1 T2
① Slock A
读 A=50
Slock B
读 B=100
求和 =150

③ 读 A=50
读 B=100
求和 =150
Commit
Unlock A
Unlock B


Xlock B
等待等待等待等待等待等待等待等待获得 Xlock B
读 B=100
B← B*2
写回 B=200
Commit
Unlock B 可重复读
1级封锁协议 + 事务 T在 读取数据 R之前 必须先对其加 S锁,直到 事务结束才释放
3级封锁协议可防止丢失修改、读脏数据和不可重复读。
封锁协议小结什么操作需要申请封锁 —— 写前( X锁)、读前( S锁)
何时释放锁(即持锁时间)
对数据对象施加锁,带来问题
封锁技术可以有效地解决并行操作的一致性问题,但也带来一些新的问题
死锁
活锁解决死锁的方法
1,预防死锁
2,死锁的诊断与解除在操作系统中广为采用的预防死锁的策略并不很适合数据库的特点,DBMS在解决死锁的问题上 更普遍采用的是诊断并解除死锁的方法。
3.7 事务处理小结
数据库的并发控制以事务为单位
数据库的并发控制通常使用封锁机制
两类最常用的封锁
不同级别的封锁协议提供不同的数据一致性保证,提供不同的数据共享度。
三级封锁协议
对数据对象施加封锁,带来问题
活锁、死锁
3.8 触发器(自学)
触发器 ( Trigger)也是一种基于事件机制的事件处理过程(就是 SQL语句序列),它由更新、插入、删除等操作激发,
触发器是建立在表一级上的,它与指定的数据修改相对应,一般每个表最多可以建立三个触发器,分别对应于:
INSERT,DELETE和 UPDATE。
触发器的主要优点,当对触发器所保护的表中数据进行操作时,触发器都能被自动地被激活。这样就可以使用触发器来对这些数据 实施完整性 检查。
注意,只有表所有者才有权建立触发器,因此,表所有者和触发器所有者的名字是相同的。
定义触发器的语法格式为:
CREATE TRIGGER 触发器名 ON 表名 FOR
[INSERT,UPDATE,DELETE] AS SQL语句序列
例,为了维护两个关系:选修课程表 C、学生选修课程表 SC间的完整性,设表 C的主键课程号 CNO是表 SC的外键。则可以定义一个触发器,作用是每当删除修课表 C中的某门课程时,都自动地删除学生修课表中选修了此门课程的所有学生的元组。
触发器的代码为:
CREATE TRIGGER del_trigger ON C FOR
DELETE AS DELETE FROM SC
WHERE SC.CNO = deleted.CNO
3.9 存储过程(自学)
存储过程( Procedure):
由 SQL语句和流程控制语句组成的函数。
由用户调用执行
所有的存储过程均被保存在服务器上,且在服务器端运行。
存储过程的优点:
1.提高运行效率,存储过程是由 SQL语句构成的,存储过程在创建时已经经过分析,编译了,可以提高执行效率 。
2.减少服务器和客户之间的信息交换,使用存储过程可以显著减少服务器和客之间的数据交换,这对于网络带宽比较窄的部门来说,尤为重要 。
3.提高共享,存储过程是作为数据库对象保存在服务器端并在服务器端运行的,所有的程序员都可以共享 。
建立存储过程的 SQL语句简化格式为:
CREATE PROC[edure] 存储过程名 AS SQL语句序列
例,建立一个显示所有男生的学号,姓名,年龄并按年龄的升序排列的存储过程的代码为:
CREATE PROC disp_man AS SELECT SNO,SN,AGE FROM S
WHERE SEX = ‘男 ’ ORDER BY AGE
执行过程的语句格式:
EXEC 存储过程名例,EXEC disp_man
第三章 小 结
非过 程式数据库查询语言 SQL提供了数据定义、
数据操纵和数据控制功能,已经成为关系数据库系统的标准查询语言,获得了几乎所有的关系数据库系统的支持。
SQL的特点
非过程化
面向集合的操作方式
同一种语法结构提供两种使用方式小结(续)
交互式 SQL
数据定义
数据操纵
数据控制嵌入式 SQL
与主语言的通信方式
SQL通信区
向主语言传递 SQL语句的执行状态信息
主变量
主语言向 SQL语句提供参数
将 SQL语句查询数据库的结果交主语言进一步处理
游标
解决集合性操作语言与过程性操作语言的不匹配
数据库的并发控制以事务为单位
数据库的并发控制通常使用封锁机制
支持事务处理、触发器和存储过程已经成为当代关系数据库系统的标志。