第8章 数据库编程
复习笔记
一、嵌入式SQL
01嵌入式SQL的处理过程
(1)嵌入式SQL定义
嵌入式 SQL是将 SQL 语句嵌入程序设计语言中,被嵌入的程序设计语言,如C、C++、Java,称为宿主语言,简称主语言。
(2)嵌入式SQL处理过程
对ESQL,RDBMS一般采用预编译方法处理,即由RDBMS的预处理程序对源程序进行扫描,识别出ESQL 语句,把它们转换成主语言调用语句,以使主语言编译程序能识别它们,然后由主语言的编译程序将纯的主语言程序编译成目标码,如图8-1所示。
图8-1 嵌入式SQL基本处理过程
(3)ESQL执行语句
在ESQL中,为了能够区分SQL语句与主语言语句,所有SQL语句都必须加前缀"EXECSQL",以";"结束成为一个程序片断:"EXECSQL<SQL语句>;"。
02嵌入式SQL语句与主语言之间的通信
将SQL嵌入到高级语言中混合编程,SQL语句负责操纵数据库,高级语言语句负责控制逻辑流程。这时程序中会含有两种不同计算模型的语句,它们之间应该如何通信呢?
(1)数据库工作单元与源程序工作单元之间的通信内容
①向主语言传递SQL语句的执行状态信息,使主语言能够据此信息控制程序流程,主要用SQL通信区(SQL CommunicationArea,SQLCA)实现。
②主语言向SQL语句提供参数,主要用主变量(host variable)实现。
③将SQL语句查询数据库的结果交主语言处理,主要用主变量和游标(cursor)实现。
(2)SQL通信区
SQL语句执行后,系统要反馈给应用程序若干信息,这些信息将送到SQL通信区中,应用程序从SQL通信区中取出这些状态信息,据此决定接下来执行的语句。
SQL通信区中有一个变量SQLCODE,用来存放每次执行SQL语句后返回的代码。
应用程序每执行完一条SQL语句之后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理。
(3)主变量
①定义
SQL语句中使用的主语言程序变量简称为主变量。
②输入主变量和输出主变量
主变量分为输入主变量和输出主变量。输入主变量由应用程序对其赋值,SQL语句引用;输出主变量由SQL语句对其赋值或设置状态信息,返回给应用程序。
③指示变量
指示变量是一个整型变量,用来"指示"所指主变量的值或条件。指示变量可以指示输入主变量是否为空值,可以检测输出主变量是否空值,值是否被截断。
④执行语句格式
所有主变量和指示变量必须在SQL语句BEGIN DECLARE SECTION 与 END DECLARE SECTION 之间进行说明。
为了与数据库对象名(表名、视图名、列名等)区别,SQL 语句中的主变量名和指示变量前要加冒号“:”作为标志。
(4)游标
游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每个游标区都有一个名字。用户可以通过游标逐一获取记录,并赋给主变量,交由主语言进一步处理。
(5)建立和关闭数据库连接
嵌入式 SQL 程序要访问数据库必须先连接数据库。RDBMS 根据用户信息对连接请求进行合法性验证,只有通过身份验证,才能建立一个可用的合法连接。
①建立数据库
连接建立连接的ESQL语句是:
EXEC SQL CONNECT TO target[AS connection-name][USER user-name];
a. target是要连接的数据库服务器,它可以是一个常见的服务器标识串,或者是包含服务器标识的SOL串常量,也可以是DEFAULT。
b.connection-name是可选的连接名,连接必须是一个有效的标识符,主要用来识别一个程序内同时建立的多个连接,如果在整个程序内只有一个连接也可以不指定连接名。
②关闭数据库连接
当某个连接上的所有数据库操作完成后,应用程序应该主动释放所占用的连接资源。
关闭数据库连接的ESQL语句是:
EXEC SQL DISCONNECT[connection-name];
其中connection-name是EXEC SQL CONNECT所建立的数据库连接。
03不用游标的SQL语句
有的嵌入式 SQL 语句不需要使用游标。它们是:说明性语句、数据定义语句、数据控制语句、查询结果为单记录的 SELECT语句、非CURRENT形式的增删改语句。
(1)查询结果为单记录的 SELECT 语句
这类语句不需要使用游标,因为查询结果只有一个,只需要用INTO子句指定存放查询结果的主变量。
使用单记录的SELECT语句需要注意以下几点:
①INTO子句、WHERE子句和HAVING短语的条件表达式中均可以使用主变量;
②查询结果为空值的处理
查询返回的记录中,可能某些列为空值NULL。当指示变量值为负值时,不管主变量为何值,均认为主变量值为NULL,指示变量只能用于INTO子句中。
③如果查询结果实际上并不是单条记录,而是多条记录,则程序出错,RDBMS会在SQLCA中返回错误信息。
(2)非CURRENT形式的增删改语句
有些增删改语句不需要使用游标,不是CURRENT形式的。在UPDATE的SET子句和WHERE子句中可以使用主变量,SET子句还可以使用指示变量。
04使用游标的SQL语句
必须使用游标的SQL语句有查询结果为多条记录的 SELECT语句、CURRENT形式的 UPDATE 和 DELETE语句。
(1)查询结果为多条记录的SELECT语句
一般情况下,SELECT语句查询结果是多条记录,因此需要用游标机制将多条记录一次一条地送主程序处理,从而把对集合的操作转换为对单个记录的处理。
使用游标的步骤为:
①说明游标
用DECLARE 语句为一条SELECT语句定义游标:
EXEC SQL DECLARE<游标名>CURSOR FOR<SELECT语句>;
定义游标仅仅是一条说明性语句,这时关系数据库管理系统并不执行SELECT语句。
②打开游标
用OPEN语句将定义的游标打开。
EXEC SQL OPEN<游标名>;
打开游标实际上是执行相应的 SELECT 语句,把查询结果取到缓冲区中。这时游标处于活动状态,指针指向查询结果集中的第一条记录。
③推进游标指针并取当前记录
EXEC SQL FETCH<游标名>
INTO<主变量>[<指示变量>][,<主变量>[<指示变量>]]…;
其中主变量必须与SELECT语句中的目标列表达式具有一一对应关系。
用FETCH语句把游标指针向前推进一条记录,同时将缓冲区中的当前记录取出来送至主变量供主语言进一步处理。通过循环执行FETCH语句逐条取出结果集中的行进行处理。
④关闭游标
用CLOSE语句关闭游标,释放结果集占用的缓冲区及其他资源。
EXEC SQL CLOSE<游标名>;
游标被关闭后就不再和原来的查询结果集相联系。但被关闭的游标可以再次被打开,与新的查询结果相联系。
(2)CURRENT形式的 UPDATE 和 DELETE 语句
UPDATE 语句和DELETE 语句都是集合操作,UPDATE 语句和DELETE 语句中要用子句"WHERE CURRENT OF<游标名>"来表示修改或删除的是最近一次取出的记录,即游标指针指向的记录。
05动态SQL
某些应用到执行时才能够确定要提交的SQL语句、查询的条件,需要使用动态SOL来解决。动态SOL支持动态组装SQL语句和动态参数两种形式。
(1)使用SQL语句主变量
程序主变量包含的内容是SQL语句的内容,而不是原来保存数据的输入或输出变量,这样的变量称为SQL 语句主变量。SQL语句主变量在程序执行期间可以设定不同的SQL语句,然后立即执行。
(2)动态参数
动态参数是SQL语句中的可变元素,使用参数符号"?"表示该位置的数据在运行时设定。动态参数的输入是通过 prepare 语句准备主变量和执行(execute)时绑定数据或主变量来完成。使用动态参数的步骤有:
①声明SQL语句主变量
②准备SQL语句(PREPARE)
PREPARE将分析含主变量的SQL语句内容,建立语句中包含的动态参数的内部描述符,并用<语句名>标识它们的整体。
EXEC SQL PREPARE<语句名>FROM<SQL语句主变量>;
③执行准备好的语句(EXECUTE)
EXECUTE将SQL语句中分析出的动态参数和主变量或数据常量绑定作为语句的输入或输出变量。
EXEC SQL EXECUTE<语句名>[INTO<主变量表>][USING<主变量或常量>];
二、过程化 SQL
01过程化SQL的块结构
过程化 SQL 是对 SQL 的扩展,使其增加了过程化语句功能。过程化 SQL程序的基本结构是块。所有的过程化SQL程序都是由块组成的。这些块之间可以互相嵌套,每个块完成一个逻辑操作。图8-2是过程化SQL块的基本结构。
图8-2 过程化SQL块的基本结构
02变量和常量的定义
(1)变量定义
变量名数据类型[[NOT NULL]:=初值表达式] 或
变量名数据类型[[NOT NULL]初值表达式]
(2)常量的定义
常量名数据类型CONSTANT:=常量表达式
常量必须要给一个值,并且该值在存在期间或常量的作用域内不能改变。如果试图修改它,过程化 SQL将返回一个异常。
(3)赋值语句
变量名:=表达式
03流程控制
(1)条件控制语句
①IF语句
IF condition THEN
Sequence_of_statements; /*条件为真时语句序列才被执行*/
END IF; /*条件为假或NULL时什么也不做,控制转移至下一个语句*/
②IF-THEN 语句
IF condition THEN
Sequence_of_statementsl; /*条件为真时执行语句序列1*/
ELSE
Sequence_of_statements2; /*条件为假或NULL时执行语句序列2*/
END IF;
③嵌套的IF语句
在THEN和ELSE子句中还可以再包含IF语句,即IF语句可以嵌套。
(2)循环控制语句
①最简单的循环语句LOOP
LOOP
Sequence_of_statements; /*循环体,一组过程化SQL语句*/
END LOOP;
多数数据库服务器的过程化SQL都提供EXIT、BREAK或LEAVE等循环结束语句,以保证LOOP语句块能够在适当的条件下提前结束。
②WHILE-LOOP循环语句
WHILE condition LOOP
Sequence_of_statements; /*条件为真时执行循环体内的语句序列*/
END LOOP;
每次执行循环体语句之前首先要对条件进行求值,如果条件为真则执行循环体内的语句序列,如果条件为假则跳过循环并把控制传递给下一个语句。
③FOR-LOOP循环语句
FOR count IN [REVERSE]boundl..bound2 LOOP
Sequence_of_statements;
END LOOP;
(3)错误处理
如果过程化 SQL 在执行时出现异常,则应该让程序在产生异常的语句处停下来,根据异常的类型去执行异常处理语句。
SQL标准对数据库服务器提供什么样的异常处理做出了建议,要求过程化SQL管理器提供完善的异常处理机制。
三、存储过程和函数
过程化SQL块主要有两种类型,即命名块和匿名块。匿名块每次执行时都要进行编译,它不能被存储到数据库中,也不能在其他过程化 SQL 块中调用。过程和函数是命名块,它们被编译后保存在数据库中,称为持久性存储模块(PersistentStored Module,PSM),可以被反复调用,运行速度较快。
01存储过程
(1)存储过程的优点
①运行效率高。
②降低了客户机和服务器之间的通信量。
③方便实施企业规则。
(2)存储过程的用户接口
用户通过下面的SQL语句创建、执行、修改和删除存储过程。
①创建存储过程
CREATE OR REPLACE PROCEDURE过程名([参数1,参数 2.]) /*存储过程首部制
AS<过程化SQL块>; /*存储过程体,描述该存储过程的操作*/
②执行存储过程
CALL/PERFORM PROCEDURE 过程名([参数1,参数2…]);
③修改存储过程
a.使用ALTER PROCEDURE重命名一个存储过程
ALTER PROCEDURE过程名1 RENAME TO过程名2;
b.使用ALTER PROCEDURE重新编译个存储过程
ALTER PROCEDURE 过程名COMPILE;
④删除存储过程
DROP PROCEDURE 过程名O;
02函数
(1)函数的定义语句格式
CREATE OR REPLACE FUNCTION 函数名([参数1,参数2....])RETURNS<类型>
AS <过程化SQL块>;
(2)函数的执行语句格式
CALL/SELECT 函数名([参数1,参数2.....]);
(3)修改函数
①使用ALTERFUNCTION重命名一个自定义函数
ALTER FUNCTION过程名1RENAME TO过样名2;
②使用ALTER FUNCTION重新编译一个函数
ALTER FUNCTION 函数名 COMPILE;
03过程化SQL中的游标
在过程化 SQL中如果 SELECT 语句只返回一条记录,可以将该结果存放到变量中。当查询返回多条记录时,就要使用游标对结果集进行处理。一个游标与一个SQL语句相关联。
四、ODBC编程01ODBC概述
ODBC是微软公司开放服务体系(Windows Open ServicesArchitecture,WOSA)中有关数据库的一个组成部分,它建立了一组规范,并提供一组访问数据库的应用程序编程接口(ApplicationProgramminglnterface,APD)。ODBC具有两重功效或约束力:一方面规范应用开发,另一方面规范关系数据库管理系统应用接口。
02ODBC工作原理概述
使用ODBC开发应用系统,体系结构如图8-3所示,它由四部分构成:用户应用程序、驱动程序管理器(ODBC Driver Manager)、数据库驱动程序(ODBC Driver)、数据源(如 RDBM和数据库)。
图8-3 ODBC应用系统的体系结构
(1)应用程序
应用程序提供用户界面、应用逻辑和事务逻辑。使用ODBC来开发应用系统的程序简称为ODBC应用程序,包括的内容有:
①请求连接数据库。
②向数据源发送SQL语句。
③为SQL语句执行结果分配存储空间,定义所读取的数据格式。
④获取数据库操作结果,或处理错误。
⑤进行数据处理并向用户提交处理结果。
⑥请求事务的提交和回滚操作。
⑦断开与数据源的连接。
(2)驱动程序管理器
驱动程序管理器是管理应用程序和驱动程序之间的通信。
驱动程序管理器的主要功能包括:
①装载ODBC驱动程序选择和连接正确的驱动程序。
②管理数据源。
③检查ODBC调用参数的合法性及记录ODBC函数的调用。
④当应用层需要时返回驱动程序的有关信息。
ODBC驱动程序管理器可以建立、配置或删除数据源,并查看系统当前所安装的数据库 ODBC 驱动程序。
(3)数据库驱动程序
①作用
ODBC通过驱动程序来提供应用系统与数据库平台的独立性。ODBC的各种操作请求由驱动程序管理器提交给某个 RDBMS 的 ODBC 驱动程序,通过调用驱动程序所支持的函数来存取数据库。数据库的操作结果也通过驱动程序返回给应用程序。
②分类
ODBC驱动程序主要有单束和多束两类。
a.单束驱动程序
单束驱动程序一般是数据源和应用程序在同一台机器上,驱动程序直接完成对数据文件的I/O操作。
b.多束驱动程序
多束驱动程序由驱动程序完成数据库访问请求的提交和结果集接收,应用程序使用驱动程序提供的结果集管理接口操纵执行后的结果数据。
(4)ODBC数据源管理
数据源是最终用户需要访问的数据,包含了数据库位置和数据库类型等信息,是一种数据连接的抽象。ODBC给每个被访问的数据源指定唯一的数据源名(简称 DSN),在连接中,用数据源名来代表用户名、服务器名、所连接的数据库名等。最终用户无需知道DBMS或其他数据管理软件、网络以及有关ODBC驱动程序的细节。
03ODBCAPI基础
(1)一致性
各个数据库厂商的ODBC应用程序接口(简称ODBCAPI)都要符合两方面的一致性:
①API一致性
API一致性级别有核心级、扩展1级、扩展2级;
②语法一致性
语法一致性级别有最低限度SQL语法级、核心SQL语法级、扩展SQL语法级。
(2)函数概述
ODBC3.0标准提供了76个函数接口,大致可以分为:
①分配和释放环境句柄、连接句柄、语句句柄;
②连接函数(SQLDriverconnect等);
③与信息相关的函数(如获取描述信息函数SQLGetinfo、SQLGetFunction);
④事务处理函数(如 SQLEndTran);
⑤执行相关函数(SQLExecdirect、SQLExecute等);
⑥编目函数。
(3)句柄及其属性
句柄是32位整数值,代表一个指针。ODBC3.0中句柄可以分为环境句柄、连接句柄、语句句柄或描述符句柄四类,对于每种句柄不同的驱动程序有不同的数据结构,这四种句柄的关系如图8-4所示。
图8-4 应用程序句柄之间的关系
①环境句柄
每个ODBC应用程序需要建立一个ODBC环境,分配一个环境句柄,存取数据的全局性背景如环境状态、当前环境状态诊断、当前在环境上分配的连接句柄等;
②连接句柄
一个环境句柄可以建立多个连接句柄,每一个连接句柄实现与一个数据源之间的连接;③语句句柄
在一个连接中可以建立多个语句句柄,它不只是一个SQL语句,还包括SQL语句产生的结果集以及相关的信息等;
④描述句柄
在 ODBC3.0中提出了描述符句柄的概念,它是描述 SQL语句的参数、结果集列的元数据集合。
(4)数据类型
ODBC定义了两套数据类型,即SQL数据类型和C数据类型。SQL数据类型用于数据源,而C数据类型用于应用程序的C代码。它们之间的转换情况如表8-1所示。
表8-1 SQL数据类型和C数据类型之间的转换规则
SQL数据类型 |
C数据类型 |
|
SQL数据类型 |
数据源之间转换 |
应用程序变量传送到语句参数(SQLBindparameter) |
C数据类型 |
从结果集列中返回剑应用程序变量(SQLBindcol) |
应用程序变量之间转换 |
04ODBC的工作流程
使用ODBC的应用系统大致的工作流程如图8-5所示。
图8-5 ODBC的工作流程
(1)配置数据源
配置数据源有两种方法:
①运行数据源管理工具来进行配置:
②使用Driver Manager提供的ContigDsn函数来增加、修改或删除数据源。这种方法特别适用于在应用程序中创建的临时使用的数据源。
(2)初始化环境
应用程序通过调用连接数和某个数据源进行连接后,Driver Manager 调用所连的驱动程序中的SQLAllocHandle,分配环境句柄的数据结构。
(3)建立连接
应用程序调用SOLAllocHandle分配连接句柄,通过SOLConnect、SOLDriverconnect、SQLBrowseconnect 与数据源连接。
(4)分配语句句柄
语句句柄含有具体的SQL语句以及输出的结果集等信息。在后面的执行函数中,语句句柄都是必要的输入参数。应用程序还可以通过SQLGetStmtAttr来设置语句属性(也可以使用默认值)。
(5)执行SQL语句
应用程序处理SQL语句的方式有两种:预处理(SQLPrepare、SQLExecute适用于语句的多次执行)或直接执行(SQLExecdirect)。
(6)结果集处理
ODBC中使用游标来处理结果集数据。
①游标分类
a.forward-only游标
只能在结果集中向前滚动,它是0DBC的默认游标类型。
b. 可滚动游标
又可以分为静态(static)、动态(dynamic),码集驱动和混合型(mixed)四种。
②游标打开方式
当结果集刚刚生成时,游标指向第一行数据之前,应用程序通过SOLBindCol,把查询结果绑定到应用程序缓冲区中,通过SQLFetch或是SQLFetchScroll来移动游标获取结果集中的每一行数据。最后通过SQLCloseCursor 来关闭游标。
(7)中止处理
处理结束后,应用程序将首先释放语句句柄,然后释放数据库连接,并与数据库服务器断开,最后释放ODBC 环境。
五、OLE DB
01定义
OLE DB是基于组件对象模型(Component ObjectModel,COM)来访问各种数据源的 ActiveX 的通用接口,它提供访问数据的一种统一手段,而不管存储数据时使用的方法如何。OLE DB支持的数据源可以是数据库,也可以是文本文件、Excel表格、ISAM等各种不同格式的数据存储。
02结构
图8-6是一个基于OLE DB体系结构设“程序的编程模型。OLE DB 体系结构中包含消费者(consumer)和提供者(provider)两部分。
图8-6 OLE DB基本体系结构
(1)消费者
OLE DB的消费者利用OLE DB提供者提供的接口访问数据源数据的客户端应用程序或其他工具。在OLE DB实现中,OLE DB组件本身也可能作为消费者存在。
(2)提供者
OLE DB的提供者是一个由COM组件构成的数据访问中介,位于数据源和消费者应用程序之间,向消费者提供访问数据源数据的各种接口。提供者主要有服务提供者和数据提供者。
①服务提供者。这类提供者自身没有数据,它通过OLE DB接口封装服务,从下层获取数据并向上层提供数据,具有提供者和消费者双重身份。一个服务提供者还可以和其他服务提供者或组件组合定义新的服务组件。
②数据提供者。数据提供者自己拥有数据并通过接口形成表格形式的数据。它不依赖于其他服务类或数据类的提供者,直接向消费者提供数据。
03编程模型
OLE DB基于COM对象技术形成一个支持数据访问的通用编程模型:数据管理任务必须由消费者访问数据,由提供者发布(deliver)数据。OLE DB编程模型有两种:RowSet模型和Binder模型。
六、JDBC编程
JDBC是Java的开发者Sun制定的Java数据库连接技术的简称,为DBMS提供支持无缝连接应用的技术。JDBC是Java实现数据库访问的应用程序编程接口。