1、数据库原理咸阳师范学院信息工程学院第八章 数据库编程本章主要教学内容:8.1 嵌入式 SQL8.2 存储过程8.3 ODBC 编程重点及难点:了解 SQL 语言的两种方式;掌握游标的使用;掌握存储过程的使用;掌握 ODBC 编程;数据库编程应用系统中使用 SQL 编程来访问和管理数据库中数据的方式主要有:嵌入式SQL、PL/SQL、ODBC 编程、JDBC 编程和 OLEDB 编程等方式。嵌入式 SQLSQL 语言提供了两种不同的使用方式:交互式嵌入式为什么要引入嵌入式 SQLSQL 语言是非过程性语言事务处理应用需要高级语言这两种方式细节上有差别,在程序设计的环境下,SQL 语句要做某些必要
2、的扩充8.1 嵌 入 式 SQL8.1.1 嵌入式 SQL 的处理过程8.1.2 嵌入式 SQL 语句与主语言之间的通信8.1.3 不用游标的 SQL 语句8.1.4 使用游标的 SQL 语句8.1.5 动态 SQL8.1.1 嵌入式 SQL 的处理过程为了区分 SQL 语句与主语言语句,需要: 前缀:EXEC SQL结束标志:随主语言的不同而不同以 C 为主语言的嵌入式 SQL 语句的一般形式EXEC SQL ;例:EXEC SQL DROP TABLE Student;以 COBOL 作为主语言的嵌入式 SQL 语句的一般形式EXEC SQL END-EXEC例: EXEC SQL DRO
3、P TABLE Student END-EXECDBMS 处理宿主型数据库语言 SQL 的方法预编译修改和扩充主语言使之能处理 SQL 语句预编译1由 DBMS 的预处理程序对源程序进行扫描,识别出 SQL 语句2把它们转换成主语言调用语句,以使主语言编译程序能识别它3最后由主语言的编译程序将整个源程序编译成目标码。嵌入 SQL 语句说明性语句嵌入 SQL 语句 数据定义 可执行语句 数据控制 数据操纵 允许出现可执行的高级语言语句的地方,都可以写可执行 SQL 语句允许出现说明语句的地方,都可以写说明性 SQL 语句8.1 嵌 入 式 SQL8.1.1 嵌入式 SQL 的处理过程8.1.2
4、嵌入式 SQL 语句与主语言之间的通信8.1.3 不用游标的 SQL 语句8.1.4 使用游标的 SQL 语句8.1.5 动态 SQL8.1.2 嵌入式 SQL 语句与主语言之间的通信将 SQL 嵌入到高级语言中混合编程,程序中会含有两种不同计算模型的语句SQL 语句描述性的面向集合的语句负责操纵数据库高级语言语句过程性的面向记录的语句负责控制程序流程工作单元之间的通信方式1. SQL 通信区向主语言传递 SQL 语句的执行状态信息主语言能够据此控制程序流程2. 主变量1)主语言向 SQL 语句提供参数2)将 SQL 语句查询数据库的结果交主语言进一步处理3. 游标解决集合性操作语言与过程性操
5、作语言的不匹配1. SQL 通信区SQLCA: SQL Communication AreaSQLCA 是一个数据结构SQLCA 的用途SQL 语句执行后,DBMS 反馈给应用程序信息描述系统当前工作状态描述运行环境这些信息将送到 SQL 通信区 SQLCA 中应用程序从 SQLCA 中取出这些状态信息,据此决定接下来执行的语句SQLCA 的内容与所执行的 SQL 语句有关与该 SQL 语句的执行情况有关例:在执行删除语句 DELETE 后,不同的执行情况,SQLCA 中有不同的信息:违反数据保护规则,操作拒绝没有满足条件的行,一行也没有删除成功删除,并有删除的行数无条件删除警告信息由于各种原
6、因,执行出错SQLCA 的使用方法定义 SQLCA用 EXEC SQL INCLUDE SQLCA 加以定义使用 SQLCASQLCA 中有一个存放每次执行 SQL 语句后返回代码的变量 SQLCODE如果 SQLCODE 等于预定义的常量 SUCCESS,则表示 SQL 语句成功,否则表示出错应用程序每执行完一条 SQL 语句之后都应该测试一下 SQLCODE 的值,以了解该 SQL 语句执行情况并做相应处理2. 主变量 什么是主变量嵌入式 SQL 语句中可以使用主语言的程序变量来输入或输出数据在 SQL 语句中使用的主语言程序变量简称为主变量(Host Variable)主变量主变量的类型
7、输入主变量由应用程序对其赋值,SQL 语句引用输出主变量由 SQL 语句赋值或设置状态信息,返回给应用程序一个主变量有可能既是输入主变量又是输出主变量主变量主变量的用途输入主变量指定向数据库中插入的数据将数据库中的数据修改为指定值指定执行的操作指定 WHERE 子句或 HAVING 子句中的条件输出主变量获取 SQL 语句的结果数据获取 SQL 语句的执行状态主变量指示变量一个主变量可以附带一个指示变量(Indicator Variable)什么是指示变量整型变量用来“指示”所指主变量的值或条件指示变量的用途输入主变量可以利用指示变量赋空值输出主变量可以利用指示变量检测出是否空值,值是否被截断
8、主变量在 SQL 语句中使用主变量和指示变量的方法1) 说明主变量和指示变量BEGIN DECLARE SECTION. . (说明主变量和指示变量 ).END DECLARE SECTION主变量2) 使用主变量说明之后的主变量可以在 SQL 语句中任何一个能够使用表达式的地方出现为了与数据库对象名(表名、视图名、列名等)区别,SQL 语句中的主变量名前要加冒号(:)作为标志主变量3) 使用指示变量指示变量前也必须加冒号标志必须紧跟在所指主变量之后主变量在 SQL 语句之外(主语言语句中 )使用主变量和指示变量的方法可以直接引用,不必加冒号3. 游标(cursor)为什么要使用游标SQL 语
9、言与主语言具有不同数据处理方式SQL 语言是面向集合的,一条 SQL 语句原则上可以产生或处理多条记录游标主语言是面向记录的,一组主变量一次只能存放一条记录仅使用主变量并不能完全满足 SQL 语句向应用程序输出数据的要求嵌入式 SQL 引入了游标的概念,用来协调这两种不同的处理方式游标什么是游标游标是系统为用户开设的一个数据缓冲区,存放 SQL 语句的执行结果每个游标区都有一个名字用户可以用 SQL 语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理四、建立和关闭数据库连接嵌入式 SQL 程序要访问数据库必须先连接数据库。RDBMS 根据用户信息对连接请求进行合法性验证,只有通过了身
10、份验证,才能建立一个可用的合法连接。四、建立和关闭数据库连接1、建立数据库连接EXEC SQL CONNECT TO targetAS connection-nameUSER user-nameTarget 是要连接的数据库服务器,connection-name 是可选的连接名,连接必须是一个有效的标识符,主要用来识别一个程序内同时建立的多个连接,如果在整个程序内只有一个连接也可以不指定连接名。四、建立和关闭数据库连接2、关闭数据库连接当某个连接上的所有数据库操作完成后,应用程序应该主动释放所占用的连接资源。EXEC SQL DISCONNECTconnectionConnection 是所建
11、立的数据库连接。例 1 依次检查某个系的学生记录,交互式更新某些学生年龄。EXEC SQL BEGIN DECLARE SECTION;Char deptname20;Char HSno9;Char HSname20;Char HSex2;例题例题int HSage;int NEWAGE;EXEC SQL END DECLARE SECTION;Long SQLCODE;EXECSQL INCLUDE sqlca;例题int main(void)int count = 0;char yn;printf(“Please choose the department name(CS/MA/IS):”
12、);scanf(“%s”,例题EXEC SQL CONNECT TO TESTlocalhost:54321 USER “SYSTEM”/”MANAGER”;EXEC SQL DECLARE SX CURSOR FOR SELECT Sno,Sname,Ssex,Sage FROM Student WHERE SDept=:deptname;EXEC SQL OPEN SX;For(;)EXEC SQL FETCH SX INTO :HSno,:HSname,:HSsex,:HSage;例题if (sqlca.,sqlcode !=0)Break;if (count+=0)Printf(“n%
13、 -10s % -20s% -10s% -10sn”,”Sno”,”Sname”,”Ssex”,”Sage”);Printf(“% -10s % -20s% -10s% -10dn”, HSno,HSname,HSsex,HSage);例题printf(“UPDATE AGE(y/n)?”);doscanf(“%c”,while (yn !=N 例题if (yn =y| yn =Y)print (“INPUT NEW AGE:”);scanf(“%d”,EXEC SQL UPDATE StudentSET Sage=:NEWAGEWHERE CURRENT OF SX;例题EXEC SQL C
14、LOSE SX;EXEC SQL COMMIT WORK;EXEC SQL DISCONNECT TEST;8.1 嵌 入 式 SQL8.1.1 嵌入式 SQL 的处理过程8.1.2 嵌入式 SQL 语句与主语言之间的通信8.1.3 不用游标的 SQL 语句8.1.4 使用游标的 SQL 语句8.1.5 动态 SQL8.1.3 不用游标的 SQL 语句不用游标的 SQL 语句的种类说明性语句数据定义语句数据控制语句查询结果为单记录的 SELECT 语句非 CURRENT 形式的增删改语句 一、查询结果为单记录的 SELECT 语句语句格式EXEC SQL SELECT ALL|DISTINCT
15、 ,.INTO ,. FROM , .WHERE GROUP BY HAVING ORDER BY ASC|DESC;查询结果为单记录的 SELECT 语句对交互式 SELECT 语句的扩充就是多了一个 INTO 子句把从数据库中找到的符合条件的记录,放到 INTO 子句指出的主变量中去。查询结果为单记录的 SELECT 语句使用注意事项1. 使用主变量INTO 子句WHERE 子句的条件表达式HAVING 短语的条件表达式查询结果为单记录的 SELECT 语句2. 使用指示变量指示变量只能用于 INTO 子句中如果 INTO 子句中主变量后面跟有指示变量,则当查询得出的某个数据项为空值时,系
16、统会自动将相应主变量后面的指示变量置为负值,但不向该主变量执行赋值操作,即主变量值仍保持执行 SQL 语句之前的值当发现指示变量值为负值时,不管主变量为何值,均应认为主变量值为 NULL查询结果为单记录的 SELECT 语句3. 查询结果为空集如果数据库中没有满足条件的记录,即查询结果为空,则 DBMS 将 SQLCODE 的值置为1004. 查询结果为多条记录程序出错,DBMS 会在 SQLCA 中返回错误信息查询结果为单记录的 SELECT 语句例 2 根据学生号码查询学生信息。假设已将要查询的学生的学号赋给了主变量 givensnoEXEC SQL SELECT Sno, Sname,
17、Ssex, Sage, SdeptINTO :Hsno, :Hname, :Hsex, :Hage, :HdeptFROM StudentWHERE Sno=:givensno;Hsno, Hname, Hsex, Hage, Hdept 和 givensno 均是主变量,并均已在前面的程序中说明过了。查询结果为单记录的 SELECT 语句例 3 查询某个学生选修某门课程的成绩。假设已将要查询的学生的学号赋给了主变量 givensno,将课程号赋给了主变量givencno。EXEC SQL SELECT Sno, Cno, GradeINTO :Hsno, :Hcno, :Hgrade:Gra
18、deidFROM SCWHERE Sno=:givensno ANDCno=:givencno;查询结果为单记录的 SELECT 语句从提高应用程序的数据独立性角度考虑,SELECT 语句在任何情况下都应该使用游标对于仅返回一行结果数据的 SELECT 语句虽然可以不使用游标但如果以后数据库改变了,该 SELECT 语句可能会返回多行数据,这时该语句就会出错二、非 CURRENT 形式的增删改语句非 CURRENT 形式的 UPDATE 语句使用主变量SET 子句WHERE 子句使用指示变量SET 子句非 CURRENT 形式的 UPDATE 语句可以操作多条元组例 4 修改某个学生选修 1
19、号课程的成绩。假设该学生的学号已赋给主变量 givensno,修改后的成绩已赋给主变量 newgrade。EXEC SQL UPDATE SCSET Grade=:newgradeWHERE Sno=:givensno;二、非 CURRENT 形式的增删改语句二、非 CURRENT 形式的增删改语句例 5 将计算机系全体学生年龄置 NULL 值Sageid=-1;EXEC SQL UPDATE StudentSET Sage=:Raise:SageidWHERE Sdept=CS;二、非 CURRENT 形式的增删改语句将指示变量 Sageid 赋一个负值后,无论主变量 Raise 为何值,D
20、BMS 都会将 CS 系所有记录的年龄属性置空值。它等价于:EXEC SQL UPDATE StudentSET Sage=NULLWHERE Sdept=CS;二、非 CURRENT 形式的增删改语句非 CURRENT 形式的 DELETE 语句使用主变量WHERE 子句非 CURRENT 形式的 DELETE 语句可以操作多条元组二、非 CURRENT 形式的增删改语句例 6 某个学生退学了,现要将有关他的所有选课记录删除掉。假设该学生的姓名已赋给主变量 stdnameEXEC SQL DELETEFROM SCWHERE Sno=(SELECT SnoFROM StudentWHERE
21、Sname=:stdname);二、非 CURRENT 形式的增删改语句非 CURRENT 形式的 INSERT 语句使用主变量VALUES 子句使用指示变量VALUES 子句非 CURRENT 形式的 INSERT 语句一次只能输入一条元组二、非 CURRENT 形式的增删改语句例 7 某个学生新选修了某门课程,将有关记录插入 SC 表假设学生的学号已赋给主变量 stdno,课程号已赋给主变量 couno。gradeid=-1;EXEC SQL INSERTINTO SC(Sno, Cno, Grade)VALUES(:stdno, :couno, :gr:gradeid);由于该学生刚选修
22、课程,尚未考试,因此成绩列为空。所以本例中用指示变量指示相应的主变量为空值。8.1 嵌 入 式 SQL8.1.1 嵌入式 SQL 的处理过程8.1.2 嵌入式 SQL 语句与主语言之间的通信8.1.3 不用游标的 SQL 语句8.1.4 使用游标的 SQL 语句8.1.5 动态 SQL8.1.4 使用游标的 SQL 语句必须使用游标的 SQL 语句查询结果为多条记录的 SELECT 语句CURRENT 形式的 UPDATE 语句CURRENT 形式的 DELETE 语句一、 查询结果为多条记录的 SELECT 语句使用游标的步骤1. 说明游标2. 打开游标3. 移动游标指针,然后取当前记录4.
23、 关闭游标1. 说明游标使用 DECLARE 语句语句格式EXEC SQL DECLARE CURSORFOR ;功能是一条说明性语句,这时 DBMS 并不执行 SELECT 指定的查询操作。2. 打开游标使用 OPEN 语句语句格式EXEC SQL OPEN ;功能打开游标实际上是执行相应的 SELECT 语句,把所有满足查询条件的记录从指定表取到缓冲区中这时游标处于活动状态,指针指向查询结果集中第一条记录之前3. 移动游标指针,然后取当前记录使用 FETCH 语句语句格式EXEC SQL FETCH NEXT|PRIOR|FIRST|LAST FROM INTO ,.;移动游标指针,然后取
24、当前记录功能指定方向推动游标指针,然后将缓冲区中的当前记录取出来送至主变量供主语言进一步处理。NEXT|PRIOR|FIRST|LAST:指定推动游标指针的方式。NEXT: 向前推进一条记录PRIOR:向回退一条记录FIRST: 推向第一条记录LAST: 推向最后一条记录缺省值为 NEXT移动游标指针,然后取当前记录说明(1) 主变量必须与 SELECT 语句中的目标列表达式具有一一对应关系(2) FETCH 语句通常用在一个循环结构中,通过循环执行 FETCH 语句逐条取出结果集中的行进行处理(3) 为进一步方便用户处理数据,现在一些关系数据库管理系统对 FETCH 语句做了扩充,允许用户向
25、任意方向以任意步长移动游标指针4. 关闭游标使用 CLOSE 语句语句格式EXEC SQL CLOSE ;功能关闭游标,释放结果集占用的缓冲区及其他资源说明游标被关闭后,就不再和原来的查询结果集相联系被关闭的游标可以再次被打开,与新的查询结果相联系例题例 8 查询某个系全体学生的信息(学号、姓名、性别和年龄) 。要查询的系名由用户在程序运行过程中指定,放在主变量 deptname 中EXEC SQL INCLUDE SQLCA;EXEC SQL BEGIN DECLARE SECTION; 例题/* 说明主变量 deptname,HSno,HSname,HSsex,HSage 等*/EXEC
26、SQL END DECLARE SECTION;gets(deptname); /* 为主变量 deptname 赋值 */例题EXEC SQL DECLARE SX CURSOR FORSELECT Sno, Sname, Ssex, SageFROM StudentWHERE SDept=:deptname; /* 说明游标 */EXEC SQL OPEN SX /* 打开游标 */例题WHILE(1) /* 用循环结构逐条处理结果集中的记录 */EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage;/* 将游标指针向前推进一行,然后从
27、结果集中取当前行,送相应主变量*/例题if (sqlca.sqlcode SUCCESS) break; /* 若所有查询结果均已处理完或出现 SQL 语句错误,则退出循环 */ printf(“%s, %s, %s, %d“, Sno, Sname, Ssex, Sage);/* 显示该记录 */ printf(“UPDATE AGE ? “); /* 问用户是否要修改 */scanf(“%c“,例题if (yn=y or yn=Y) /* 需要修改 */printf(“INPUT NEW AGE: “);scanf(“%d“, /* 输入新的年龄值 */EXEC SQL UPDATE St
28、udentSET Sage=:NEWAgeWHERE CURRENT OF SX; /* 修改当前记录的年龄字段 */;例题;EXEC SQL CLOSE SX; /* 关闭游标 */例题例 10 对某个系的学生信息,根据用户的要求删除其中某些人的记录。EXEC SQL INCLUDE SQLCA;EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname,HSno,HSname,HSsex,HSage 等*/例题EXEC SQL END DECLARE SECTION;gets(deptname); /* 为主变量 deptname 赋值 */例题EX
29、EC SQL DECLARE SX CURSOR FORSELECT Sno, Sname, Ssex, SageFROM StudentWHERE SDept=:deptnameFOR UPDATE; /* 说明游标 */EXEC SQL OPEN SX /* 打开游标 */例题WHILE(1) /* 用循环结构逐条处理结果集中的记录 */EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage;/* 将游标指针向前推进一行,然后从结果集中取当前行,送相应主变量*/例题if (sqlca.sqlcode SUCCESS) break; /*
30、若所有查询结果均已处理完或出现 SQL 语句错误,则退出循环 */printf(“%s, %s, %s, %d“, Sno, Sname, Ssex, Sage); /* 显示该记录 */例题printf(“DELETE ? “); /* 问用户是否要删除 */scanf(“%c“,if (yn=y or yn=Y) /* 需要删除 */EXEC SQL DELETEFROM StudentWHERE CURRENT OF SX; /* 删除当前记录 */ 例题;EXEC SQL CLOSE SX; /* 关闭游标 */8.1 嵌 入 式 SQL8.1.1 嵌入式 SQL 的处理过程8.1.2
31、 嵌入式 SQL 语句与主语言之间的通信8.1.3 不用游标的 SQL 语句8.1.4 使用游标的 SQL 语句8.1.5 动态 SQL8.1.5 动态 SQL 简介静态嵌入式 SQL动态嵌入式 SQL一、静态 SQL 的特点用户可以在程序运行过程中根据实际需要输入 WHERE 子句或 HAVING 子句中某些变量的值。语句中主变量的个数与数据类型在预编译时都是确定的,只有是主变量的值是程序运行过程中动态输入的。静态 SQL 的不足静态 SQL 语句提供的编程灵活性在许多情况下仍显得不足,不能编写更为通用的程序。需求例 对 SC:任课教师想查选修某门课程的所有学生的学号及其成绩班主任想查某个学
32、生选修的所有课程的课程号及相应成绩学生想查某个学生选修某门课程的成绩即:查询条件是不确定的,要查询的属性列也是不确定的二、动态 SQL1. 什么是动态嵌入式 SQL动态 SQL 方法允许在程序运行过程中临时“组装”SQL 语句。2. 应用范围在预编译时下列信息不能确定时SQL 语句正文主变量个数主变量的数据类型SQL 语句中引用的数据库对象(列、索引、基本表、视图等)动态 SQL3. 动态 SQL 的形式语句可变临时构造完整的 SQL 语句条件可变WHERE 子句中的条件HAVING 短语中的条件数据库对象、查询条件均可变SELECT 子句中的列名FROM 子句中的表名或视图名WHERE 子句
33、中的条件HAVING 短语中的条件动态 SQL4. 常用动态 SQL 语句EXECUTE IMMEDIATEPREPAREEXECUTEDESCRIBE使用动态 SQL 技术更多的是涉及程序设计方面的知识,而不是 SQL 语言本身例题例 11 创建基本表 TESTEXEC SQL BEGIN DECLARE SECTION;const char *stmt=“CREATE TABLE test(a int);”;EXEC SQL END DECLARE SECTION;EXEC SQL EXECUTE IMMEDIATE :stmt;例题例 12 向 TEST 中插入元组EXEC SQL BE
34、GIN DECLARE SECTION;const char *stmt=“INSERT INTO test VALUES(?);”;EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE mystmt FROM :stmt;例题EXEC SQL EXECUTE mystmt USING 100;EXEC SQL EXECUTE mystmt USING 200;第八章 数据库编程8.1 嵌入式 SQL8.2 存储过程8.3 ODBC 编程8.2 存储过程SQL99 标准中给出了 SQL-invoked routines 的概念。SQL-invoked ro
35、utines 可以分为存储过程( SQL-invoked procedure)和函数( SQL-invoked function )两类。8.2 存储过程建立存储过程可以指定所使用的程序设计语言。PL/SQL(Procedural Language/SQL)是编写数据库存储过程的一种过程语言。它结合了SQL 的数据操作能力和过程化语言的流程控制能力,是 SQL 的过程化扩展。8.2 存储过程8.2.1PL/SQL 的块结构8.2.2 变量常量的定义8.2.3 控制结构8.2.4 存储过程8.2.1PL/SQL 的块结构基本的 SQL 是高度非过程化的语言。ESQL 将 SQL 语句嵌入程序设计
36、语言,借助高级语言的控制功能实现过程化。PL/SQL 是对 SQL 的扩展,使其增加了过程化语句功能。8.2.1PL/SQL 的块结构PL/SQL 程序的基本结构是块。所有的 PL/SQL 程序都是由块组成的。块之间可以互相嵌套,每个块完成一个逻辑操作。块的基本结构为:8.2.1PL/SQL 的块结构DECLARE /*定义的变量、常量等只能在该基本块中使用*/-变量、常量、游标、异常等/*当基本块执行结束 时,定义就不再存在*/BEGIN-SQL 语句、PL/SQL 的流程控制语句EXCEPTION /*遇到不能继续执行的情况称为异常*/-异常处理部分 /*在出现异常时,采取措施来纠正错误或
37、报告错误*/END;定义部分执行部分8.2 存储过程8.2.1PL/SQL 的块结构8.2.2 变量常量的定义8.2.3 控制结构8.2.4 存储过程8.2.2 变量常量的定义1、PL/SQL 中定义变量的语法形式是:变量名 数据类型NOT NULL:=初值 表达式 或变量名 数据类型NOT NULL 初值表达式8.2.2 变量常量的定义2、常量的定义类似于变量的定义:常量名 数据类型 CONSTANT:=常量表达式常量必须要给一个值,并且该值在存在期间或常量的作用域内不能改变。如果试图修改它,PL/SQL 将返回一个异常。8.2.2 变量常量的定义3、赋值语句变量名称:=表达式8.2 存储过
38、程8.2.1PL/SQL 的块结构8.2.2 变量常量的定义8.2.3 控制结构8.2.4 存储过程8.2.3 控制结构PL/SQL 提供了流程控制语句,主要有条件控制语句和循环控制语句。这些语句的语法、语义和一般的高级语言(如 C 语言)类似。8.2.3 控制结构一、条件控制语句一般有三种形式的 IF 语句:IF-THEN,IF-THEN-ELSE 和嵌套的 IF 语句。8.2.3 控制结构1、IF condition THENSequence_of_statemets; /*条件为真时语句序列才被执行*/END IF; /*条件为假或 NULL 时什么也不做,控制转移至下一个语句*/8.2
39、.3 控制结构2、IF condition THENSequene_of_statements1; /*条件为真时执行语句序列 1*/ELSESequene_of_statements2; /*条件为假或 NULL 时执行语句序列 2*/END IF;8.2.3 控制结构3、在 THEN 和 ELSE 子句中还可以再包括 IF 语句,即 IF 语句可以嵌套。8.2.3 控制结构二、循环控制语句PL/SQL 有三种循环结构:LOOP ,WHILE-LOOP 和 FOR-LOOP。8.2.3 控制结构1、最简单的循环语句 LOOPLOOPSequence_of_statements;END LOO
40、P;8.2.3 控制结构多数数据库服务器的 PL/SQL 都提供 EXIT、BREAK 或 LEAVE 等循环结束语句,以保证LOOP 语句块能够在适当的条件下结束。8.2.3 控制结构2、WHILE-LOOPWHILE condition LOOPSequence_of_statements;END LOOP;8.2.3 控制结构每次执行循环体语句之前,首先对条件进行求值。如果条件为真,则执行循环体内的语句序列。否则跳过循环并把控制传递给下一个语句。8.2.3 控制结构3、FOR-LOOPFOR count IN REVERSE bound1 bound2 LOOPSequence_of_s
41、tatements;END LOOP;8.2.3 控制结构执行过程:将 count 设置为循环的下界 bound1,检查它是否小于上界 bound2。当指定 REVERSE 时则将 count 设置为循环的上界 bound2,检查 count 是否大于下界 bound1。如果越界则执行跳出循环,否则执行循环体,然后按照步长(+1 或-1)更新 count 的值,重新判断条件。8.2.3 控制结构三、错误处理如果 PL/SQL 在执行时出现异常,则应该让程序在产生异常的语句处停下来,根据异常的类型去执行异常处理语句。SQL 标准对数据库服务器提供什么样的异常处理做出了建议,要求 PL/SQL 管
42、理器提供完善的异常处理机制。8.2.3 控制结构相对于 ESQL 简单的提供执行状态信息 SQLCODE,这里的异常处理就复杂多了。根据具体系统的支持情况来进行错误处理。8.2 存储过程8.2.1PL/SQL 的块结构8.2.2 变量常量的定义8.2.3 控制结构8.2.4 存储过程8.2.4 存储过程PL/SQL 块主要有两种类型,即命名块和匿名块。匿名块每次执行时都要进行编译,它不能被存储到数据库中,也不能在其他的 PL/SQL 块中调用。存储过程和函数是命名块,它们被编译后保存在数据库中,可以被反复调用,运行速度较快。8.2.4 存储过程一、存储过程的优点存储过程是由 PL/SQL 语句
43、书写的过程,这个过程经编译和优化后存储在数据库服务器中,因此称它为存储过程,使用时只要调用即可。8.2.4 存储过程使用存储过程具有以下优点:1、运行效率高,提供了在服务器端快速执行 SQL 语句的有效途径。2、降低了客户机和服务器之间的通信量。3、方便实施企业规则。8.2.4 存储过程二、存储过程的用户接口1、创建存储过程CREATE Procedure 过程名 (参数 1,参数 2) /*存储过程首部*/AS/*存储过程体,描述该存储过程的操作*/8.2.4 存储过程存储过程包括过程首部和过程体。过程名:是数据库服务器合法的对象标识。参数列表:用名字来标识调用时给出的参数值,必须指定值的数
44、据类型。存储过程的参数也可以定义输入参数、输出参数或输入/输出参数。默认为输入参数。过程体:是一个。包括声明部分和可执行语句部分。8.2.4 存储过程2、执行存储过程CALL/PERFORM Procedure 过程名(参数 1,参数 2);在 PL/SQL 中,数据库服务器支持在过程体中调用其他存储过程。8.2.4 存储过程例 13 从账户 01003815868 转一万元到 01003813828 账户中。CALL Procedure TRANSFER (01003815868, 01003813828,10000);8.2.4 存储过程3、删除存储过程DROP PROCEDURE 过程名
45、() ;8.2.4 存储过程三、游标当查询返回多条记录时,就要使用游标对结果集进行处理。一个游标与一个 SQL 语句相关联。PL/SQL 中游标由 PL/SQL 引擎管理,可以具有更多内置扩展特性。第八章 数据库编程8.1 嵌入式 SQL8.2 存储过程8.3 ODBC 编程8.3 ODBC 编程8.3.1 数据库互连概述8.3.2 ODBC 工作原理概述8.3.1 数据库互连概述ODBC 产生的原因:是不同的数据库管理系统的存在。ODBC 是微软公司开放服务体系(Windows Open Services Architecture, WOSA)中有关数据库的一个组成部分,它建立了一组规范,并
46、提供一组访问数据库的标准 API。 8.3.1 数据库互连概述作为规范它具有两重功效:一方面规范应用开发另一方面规范 RDBMS 应用接口8.3 ODBC 编程8.3.1 数据库互连概述8.3.2 ODBC 工作原理概述8.3.2 ODBC 工作原理概述ODBC 体系结构如图所示,它由四部分构成:用户应用程序、驱动程序管理器(ODBC Driver Manager) 、数据库驱动程序(ODBC Driver) 、数据源(如 RDBMS 和数据库)8.3.2 ODBC 工作原理概述网络8.3.2 ODBC 工作原理概述一、应用程序应用程序提供用户界面、应用逻辑和事务逻辑。使用 ODBC 开发数据
47、库应用程序时,应用程序调用的是标准的 ODBC 函数和 SQL 语句。应用层使用 ODBC API 调用接口与数据库进行交互。8.3.2 ODBC 工作原理概述ODBC 应用程序包括:请求连接数据库向数据源发送 SQL 语句为 SQL 语句执行结果分配存储空间,定义所读取的数据格式8.3.2 ODBC 工作原理概述获取数据库操作结果,或处理错误进行数据处理并向用户提交处理结果请求事务的提交和回滚操作断开与数据源的连接8.3.2 ODBC 工作原理概述二、驱动程序管理器它是用来管理各种驱动程序的。包含在 ODBC32.DLL 中,对用户是透明的。管理应用程序和驱动程序之间的通信。8.3.2 OD
48、BC 工作原理概述主要功能:装载 ODBC 驱动程序、选择和连接正确的驱动程序、管理数据源、检查 ODBC 调用参数的合法性及记录 ODBC 函数的调用等,当应用层需要时返回驱动程序的有关信息。8.3.2 ODBC 工作原理概述三、数据库驱动程序提供应用系统与数据库平台的独立性。应用程序不能直接存取数据库,其各种操作请求由驱动程序管理器提交给某个 RDBMS 的ODBC 驱动程序,通过调用驱动程序所支持的函数来存取数据库。数据库的操作结果也通过驱动程序返回给应用程序。8.3.2 ODBC 工作原理概述四、ODBC 数据源管理DSN 数据源是连接数据库驱动程序与数据库管理系统 DBMS 的桥梁。
49、定义了:数据库服务器名称;登录名称;登录密码;在连接中,用数据源名来代表用户名、服务器名、所连接的数据库名等。最终用户无需知道 DBMS、网络以及有关 ODBC 驱动程序的细节,数据源对最终用户是透明的。8.3.2 ODBC 工作原理概述用户数据源:用户创建的数据源,称为“用户数据源” 。此时只有创建者才能使用,并且只能在所定义的机器上运行。任何用户都不能使用其他用户创建的用户数据源。系统数据源:所有用户和在 Windows NT 下以服务方式运行的应用程序均可使用系统数据源。文件数据源:文件数据源是 ODBC 3.0 以上版本增加的一种数据源,可用于企业用户,ODBC 驱动程序也安装在用户的计算机上。