1 / 43

第八章

第八章. 数据库编程. 主要内容. 嵌入式 SQL ( ESQL ) 存储过程( PL/SQL ) ODBC JDBC. 主要数据库访问方式. 嵌入式 SQL ( Embedded SQL ). 为什么学? 在高级语言中实现数据库操作 ,( e.g. C , 称为宿主语言, host Language) 学什么? 高级语言和 SQL 之间的如何通信,其中 SQL 语句是描述性的面向 集合 的语句,负责操纵数据库 高级语言是过程性的面向 记录 的语句;负责控制程序流程. 嵌入式 SQL ( Embedded SQL ). 格式

taya
Download Presentation

第八章

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第八章 数据库编程

  2. 主要内容 • 嵌入式SQL(ESQL) • 存储过程(PL/SQL) • ODBC • JDBC

  3. 主要数据库访问方式

  4. 嵌入式SQL(Embedded SQL) • 为什么学? • 在高级语言中实现数据库操作,( e.g. C, 称为宿主语言,host Language) • 学什么? • 高级语言和SQL之间的如何通信,其中 • SQL语句是描述性的面向集合的语句,负责操纵数据库 • 高级语言是过程性的面向记录的语句;负责控制程序流程

  5. 嵌入式SQL(Embedded SQL) • 格式 EXEC SQL <embedded SQL statement > END_EXEC 或 EXEC SQL <embedded SQL statement >; • 预编译方法,参见P238 图8.1 • ESQL三大关键概念 • SQLCA:向主语言传递数据库执行状态信息 • 主变量(指示变量):主语言和SQL之间传递参数 • 游标:协调面向集合和面向记录两种不同的处理方式

  6. 关键概念-SQLCA • SQLCA:SQL通信区 • 定义 EXEC SQL INCLUDE SQLCA; • 常用代码; • Sqlcode。该代码的定义可在头文件 sqlerr.h 中找到。 SQLCODE=0,表示操作成功; SQLCODE>0,表示警告, SQLCODE>0,表示错误。 • sqlcaid 8 字节字符字段,包含作为 SQLCA 结构标识的字符串 SQLCA。在您查看内存内容时,该字段可帮助进行调试。 • sqlcabc 包含 SQLCA 结构长度(136 字节)的长整数。 • sqlerrml sqlerrmc 字段中信息的长度。 • sqlerrmc 可以包含准备插入到错误消息中的一个或多个字符串。一些错误消息包含占位符字符串 (%1),它将被该字段中的文本代替。 • sqlerrp 保留。 • sqlerrd 长整数的实用程序数组。 • sqlstate SQLSTATE 状态值。

  7. 关键概念-主变量 • 输入主变量和输出主变量 • 默认为全局变量 • SQL 语句中使用主变量时,必须在变量名之前添加冒号 (:) • 可以使用主变量代替任何 SQL 语句中的常量值,不能用于代替表或列的名称; • 不允许使用 typedef 类型和结构 • 定义 EXEC SQL BEGIN DECLARE SECTION; long employee_number = 0; EXEC SQL END DECLARE SECTION;

  8. 指示符的值 向数据库提供值 从数据库接收值 0 主变量的值 读取的非 NULL 值 –1 NULL 值 读取的 NULL 值 关键概念-指示变量 • 一个整形变量,用于指示输入和输出主变量是否为空值。 • 要检测或指定 NULL 值,可将指示变量放在 SQL 语句中紧随主变量之后的位置上。 • 例 EXEC SQL INSERT INTO Employee VALUES (:employee_number, :employee_name, :employee_initials, :employee_phone:ind_phone ); • 应用方式

  9. 关键概念-游标(Cursor) • 游标用来协调集合和记录这两种不同的处理方式 • 游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果 • 每个游标区都有一个名字 • 用户可以通过游标逐一获取记录,并赋给主变量,交由主语言进一步处理

  10. 嵌入式SQL语句的处理 • 不用游标的SQL语句 • 对数据集不需要逐个处理的SQL语句 • Create table等 • 非current形式的update、delete • 结果为单记录的select语句 • 使用游标的SQL语句 • current形式的update、delete • 结果为多记录的select语句

  11. 举例:非current形式的语句 • 删除给定学号学生的选课信息,学号已存入主变量xx EXEC SQL delete from sc Where sno=:xx; • 把计算机系全体学生年龄置为NULL Sageid=-1; EXEC SQL Update student Set Sage=:Raise:Sageid Where Sdept=‘CS’;

  12. 举例:结果为单记录的select语句 EXEC SQL CONNECT TO target; EXEC SQL SELECT sno,cno,grade INTO :hsno, :hcno, :hgrade:gradeid FROM student WHERE sno= :givensno; EXEC SQL DISCONNECT ALL;

  13. 举例:结果为单记录的select语句 • 单行查询最多从数据库中检索一行。 • 单行查询 SELECT 语句可在选择列表之后和 FROM 子句之前有一个 INTO子句。当执行 SELECT 语句时,数据库服务器检索结果并将其放在主机变量中。 • INTO 子句包含一个主机变量的列表,用来接收每个选择列表项的值。主机变量和选择列表项的数目必须相同。 • 主机变量可以和指示符变量一起使用,以指示 NULL 结果。 • 出错处理 • 如果查询选择了多行,则数据库服务器返回 SQLE_TOO_MANY_RECORDS 错误。 • 如果查询没有选择任何行,则返回 SQLE_NOTFOUND 警告

  14. 游标的使用 • 使用游标的步骤 • 1. 说明游标 • 2. 打开游标 • 3. 移动游标指针,然后取当前记录 • 4. 关闭游标

  15. 1. 说明游标 • 使用DECLARE语句 • 语句格式 EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句>; • 功能 • 是一条说明性语句,这时DBMS并不执行SELECT指定的查询操作。

  16. 2. 打开游标 • 使用OPEN语句 • 语句格式 EXEC SQL OPEN <游标名>; • 功能 • 打开游标实际上是执行相应的SELECT语句,把所有满足查询条件的记录从指定表取到缓冲区中 • 这时游标处于活动状态,指针指向查询结果集中第一条记录之前

  17. 3. 移动游标指针,然后取当前记录 • 使用FETCH语句 • 语句格式 EXEC SQL FETCH [[NEXT|PRIOR| FIRST|LAST] FROM] <游标名> INTO <主变量>[<指示变量>] [,<主变量>[<指示变量>]]...; 缺省值为NEXT

  18. 3.移动游标指针,然后取当前记录(续) • 说明 (1) 主变量必须与SELECT语句中的目标列表达式具有一一对应关系 (2) FETCH语句通常用在一个循环结构中,通过循环执行FETCH语句逐条取出结果集中的行进行处理 (3) 为进一步方便用户处理数据,现在一些关系数据库管理系统对FETCH语句做了扩充,允许用户向任意方向以任意步长移动游标指针

  19. 4. 关闭游标 • 使用CLOSE语句 • 语句格式 EXEC SQL CLOSE <游标名>; • 功能 • 关闭游标,释放结果集占用的缓冲区及其他资源 • 说明 • 游标被关闭后,就不再和原来的查询结果集相联系 • 被关闭的游标可以再次被打开,与新的查询结果相联系

  20. 结果集为多记录的SELECT 例1 查询某个系全体学生的信息(学号、姓名、性别和年龄)。要查询的系名由用户在程序运行过程中指定,放在主变量deptname中 ...... ...... EXEC SQL INCLUDE SQLCA;

  21. 例题(续) ...... EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname,HSno,HSname,HSsex,HSage等*/ ...... ...... EXEC SQL END DECLARE SECTION; ...... ...... gets(deptname); /* 为主变量deptname赋值 */ ......

  22. 例题(续) EXEC SQL DECLARE SX CURSOR FOR SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept=:deptname; /* 说明游标 */

  23. 例题(续) EXEC SQL OPEN SX /* 打开游标 */ WHILE(1) /* 用循环结构逐条处理结果集中的记录 */ { EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; …… if (sqlca.sqlcode <> SUCCESS) break; …… }; EXEC SQL CLOSE SX; /* 关闭游标 */

  24. CURRENT形式的UPDATE语句和DELETE语句(1) • 为UPDATE语句说明游标 • 使用带FOR UPDATE OF <列名>短语的DECLARE语句 • 语句格式 EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句> FOR UPDATE OF <列名>; • FOR UPDATE OF <列名>短语用于指明检索出的数据在指定列上是可修改的,以便DBMS进行并发控制

  25. CURRENT形式的UPDATE语句和DELETE语句(2) • 为DELETE语句说明游标 • 使用带FOR Delete短语的DECLARE语句 • 语句格式 EXEC SQL DECLARE <游标名> CURSOR FOR <SELECT语句> FOR Delete; • FOR delete短语提示DBMS进行并发控制

  26. CURRENT形式的UPDATE语句和DELETE语句(3) • 修改或删除当前记录 • 经检查缓冲区中记录是要修改或删除的记录,则用UPDATE语句或DELETE语句修改或删除该记录 • 语句格式 • <UPDATE语句> WHERE CURRENT OF <游标名> • <DELETE语句> WHERE CURRENT OF <游标名> • WHERE CURRENT OF <游标名>子句表示修改或删除的是该游标中最近一次取出的记录

  27. CURRENT形式的UPDATE语句和DELETE语句(4) • 注意问题--以下两种情况除外 • 当游标定义中的SELECT语句带有UNION或ORDER BY子句 • 或者该SELECT语句相当于定义了一个不可更新的视图时

  28. 例题 例 对某个系的学生信息,根据用户的要求修改其中某些人的年龄字段。 • 思路 • 查询某个系全体学生的信息(要查询的系名由主变量deptname指定) • 然后根据用户的要求修改其中某些记录的年龄字段

  29. 例题(续) ...... EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; /* 说明主变量 deptname,HSno,HSname,HSsex,HSage,NEWAge等*/ ...... EXEC SQL END DECLARE SECTION; ...... gets(deptname); /* 为主变量deptname赋值 */ ......

  30. 例题(续) EXEC SQL DECLARE SX CURSOR FOR SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept=:deptname FOR UPDATE OF Sage; /* 说明游标 */ EXEC SQL OPEN SX /* 打开游标 */

  31. 例题(续) WHILE(1) {/* 用循环结构逐条处理结果集中的记录 */ EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 将游标指针向前推进一行,然后从结果集 中取当前行,送相应主变量*/

  32. 例题(续) if (sqlca.sqlcode <> SUCCESS) break; /* 若所有查询结果均已处理完或 出现SQL语句错误,则退出循环 */ printf("%s, %s, %s, %d", HSno, HSname, HSsex, HSage); /* 显示该记录 */ printf("UPDATE AGE ? "); /* 问用户是否要修改 */ scanf("%c",&yn);

  33. 例题(续) if (yn='y' or yn='Y') /* 需要修改 */ { printf("INPUT NEW AGE: "); scanf("%d",&NEWAge); /* 输入新的年龄值 */ EXEC SQL UPDATE Student SET Sage=:NEWAge WHERE CURRENT OF SX; /* 修改当前记录的年龄字段 */ };

  34. 例题(续) ...... ...... }; EXEC SQL CLOSE SX; /* 关闭游标 */ ...... ......

  35. 例题(续) 例4 对某个系的学生信息,根据用户的要求删除其中某些人的记录。 ...... EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; ...... /* 说明主变量 deptname,HSno,HSname,HSsex,HSage等*/ EXEC SQL END DECLARE SECTION; ...... gets(deptname); /* 为主变量deptname赋值 */ ......

  36. 例题(续) EXEC SQL DECLARE SX CURSOR FOR SELECT Sno, Sname, Ssex, Sage FROM Student WHERE SDept=:deptname FOR UPDATE; /* 说明游标 */ EXEC SQL OPEN SX /* 打开游标 */

  37. 例题(续) WHILE(1){ /* 用循环结构逐条处理结果集中的记录 */ EXEC SQL FETCH SX INTO :HSno, :HSname, :HSsex, :HSage; /* 将游标指针向前推进一行,然后从结 果集中取当前行,送相应主变量*/

  38. 例题(续) if (sqlca.sqlcode <> SUCCESS) break; /* 若所有查询结果均已处理完或 出现SQL语句错误,则退出循环 */ printf("%s, %s, %s, %d", HSno, HSname, HSsex, HSage); /* 显示该记录 */

  39. 例题(续) printf("DELETE ? "); /* 问用户是否要删除 */ scanf("%c",&yn); if (yn='y' or yn='Y') /* 需要删除 */ EXEC SQL DELETE FROM Student WHERE CURRENT OF SX; /* 删除当前记录 */ ...... }; EXEC SQL CLOSE SX; /* 关闭游标 */ ......

  40. 静态嵌入式SQL • 静态嵌入式SQL的特点 • 语句中主变量的个数与数据类型在预编译时都是确定的,只有是主变量的值是程序运行过程中动态输入的。 • 静态嵌入式SQL的不足 • 查询条件是不确定的,要查询的属性列也是不确定的 • 任课教师想查选修某门课程的所有学生的学号及其成绩 • 班主任想查某个学生选修的所有课程的课程号及相应成绩 • 学生想查某个学生选修某门课程的成绩

  41. 动态嵌入式SQL简介 • 用于执行时才能确定SQL语句和查询条件 • 动态组装SQL语句 • 动态参数

  42. 动态组装SQL语句 • 举例 EXEC SQL BEGIN DECLARE SECTION; Const char * stmt =“ CREATE TABLE test(a int);”; EXEC SQL END DECLARE SECTION; …… EXEC SQL EXECUTE IMMEDIATE :stmt;

  43. 动态参数SQL语句 • 举例 EXEC SQL BEGIN 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;

More Related