DB2数据库嵌入式SQL开发

如有转载,请注明出处:http://blog.csdn.net/embedded_sky

BY:super_bert@csdn


1.1 DB2应用程序开发概述

1.1.1    程序结构

DB2应用程序包括以下几个部分:

1.声明和初始化变量

2.连接到数据库

3.执行一个或者多个事务

4.与数据库断开连接

5.结束程序

一个事务是一组数据库操作,在提交给数据库之前,必须确认完全成功执行。在嵌入式SQL应用程序中,当应用程序成功地连接到一个数据库时,一个事务就自动开始了,结束于执行一条COMMIT语句或者ROLLBACK语句。同时,下一条SQL语句开始一个新的事务。

每一个应用程序的开始必须包括:

l  数据库管理器用来与宿主程序交互的所有变量和数据结构的声明

l  设置SQL通信区(SQLCA),提供错误处理的SQL语句

注意:用JAVA写的DB2应用程序在SQL语句出错时抛出一个SQLException异常,需要在catch块里处理,而不是使用SQLCA。

每个应用程序的主体包括访问和管理数据的SQL语句。这些语句组成事务,事务必须包括下列语句:

l  CONNECT语句,其建立一个与数据库服务器的连接

l  一条或多条:

▲数据操纵语句(例如,SELECT语句)

▲数据定义语句(例如,CREATE语句)

▲数据控制语句(例如,GRANT语句)

l  COMMIT或者ROLLBACK语句结束事务

 

应用程序的结束通常包括释放程序与数据库服务器的连接和释放其他资源的SQL语句。

 

1.1.2    开发方法选择

可使用几种不同的程序设计接口来存取 DB2 数据库。您可以:

l  将静态和动态 SQL 语句嵌入应用程序。

l  在应用程序中编写“DB2 调用层接口”(DB2 CLI) 的函数调用,以调用动态 SQL 语句。

l  开发调用“Java 数据库链接”应用程序设计接口 (JDBC API) 的 Java 应用程序和小程序。

l  开发符合“数据存取对象 (DAO) ”和“远程数据对象 (RDO) ” 规范的 Microsoft Visual Basic 和 Visual C++ 应用程序,以及使用“对象链接和嵌入数据库 (OLE DB) 桥接”的“ActiveX 数据对象”(ADO) 应用程序。

l  使用 IBM 或第三方工具如 Net.Data、Excel、Perl、“开放式数据库链接”(ODBC)最终用户工具如 LotusApproach 及其程序设计语言LotusScript 来开发应用程序。

l  要执行备份和复原数据库等管理功能,应用程序可以使用 DB2 API。

应用程序存取 DB2 数据库的方式将取决于想要开发的应用程序类型。例如,如果想开发数据输入应用程序,可以选择将静态 SQL 语句嵌入应用程序。如果想开发在万维网 (WWW) 上执行查询的应用程序,可能要选择 Net.Data、Perl 或 Java。

1.2相关概念

1.2.1 嵌入式SQL编程

嵌入式SQL应用程序就是将SQL语句嵌入某个宿主语言中,SQL语句提供数据库接口,宿主语言提供应用程序的其他执行功能。

“结构化查询语言”(SQL) 是一种数据库接口语言,它用来存取并处理 DB2 数据库中的数据。可以将SQL 语句嵌入应用程序,使应用程序能执行 SQL 支持的任何任务,如检索或存储数据。通过使用 DB2,可以用 C/C++、COBOL、FORTRAN、Java (SQLJ) 以及 REXX 程序设计语言来编写嵌入式SQL 应用程序。

嵌入了 SQL 语句的应用程序称为主程序。用于创建主程序的程序设计语言称为宿主语言。用这种方式定义程序和语言,是因为它们包含了 SQL 语句。

对于静态 SQL 语句,您在编译前就知道SQL 语句类型以及表名和列名。唯一未知的是语句正搜索或更新的特定数据值。可以用宿主语言变量表示那些值。在运行应用程序之前,要预编译、编译和捆绑静态 SQL 语句。静态 SQL 最好在变动不大的数据库上运行。否则,这些语句很快会过时。

相反,动态 SQL 语句是应用程序在运行期构建并执行的那些语句。一个提示最终用户输入 SQL 语句的关键部分(如要搜索的表和列的名称)的交互式应用程序是动态 SQL 一个很好的示例。 应用程序在运行时构建 SQL 语句,然后提交这些语句进行处理。

可以编写只有静态 SQL 语句或只有动态 SQL 语句,或者兼有两者的应用程序。

一般来说,静态 SQL 语句最适合用于带有预定义事务的高性能应用程序。预订系统是这种应用程序一个很好的示例。

一般来说,动态 SQL 语句最适合于必须在运行期指定事务的、要快速更改数据库的应用程序。交互式查询界面是这种应用程序一个很好的示例。

将 SQL 语句嵌入应用程序时,必须按以下步骤预编译应用程序并将其与数据库捆绑:

1. 创建源文件,以包含带嵌入式 SQL 语句的程序。

2. 连接数据库,然后预编译每个源文件。

预编译程序将每个源文件中的 SQL 语句转换成对数据库管理程序的DB2 运行期 API 调用。预编译程序还在数据库中生成一个存取程序包,并可选择生成一个捆绑文件(如果您指定要创建一个的话)。

存取程序包包含由 DB2 优化器为应用程序中的静态SQL 语句选择的存取方案。这些存取方案包含数据库管理程序执行静态 SQL 语句所需的信息,以便该管理程序可以用优化器确定的最有效的方式来执行这些语句。对于动态 SQL 语句,优化器在您运行应用程序时创建存取方案。

捆绑文件包含创建存取程序包所需要的 SQL 语句和其他数据。可以使用捆绑文件在以后重新捆绑应用程序,而不必首先预编译应用程序。重新捆绑创建针对当前数据库状态的优化存取方案。如果应用程序将存取与预编译时所用数据库不同的数据库,则必须重新捆绑应用程序。如果数据库统计信息自上次捆绑后已经更改,建议您重新捆绑应用程序。

3. 使用主语言编译程序编译修改的源文件(以及其他无 SQL 语句的文件)。

4. 将目标文件与 DB2 和主语言库连接,以生成一个可执行程序。

5. 如果在预编译时未对捆绑文件进行捆绑;或者准备存取不同数据库,则应对捆绑文件进行捆绑以创建存取程序包。

6. 运行该应用程序。此应用程序使用程序包中的存取方案存取数据库。

1.2.2 预编译

创建源文件之后,必须对每一个含有SQL语句的宿主语言文件用PREP命令进行预编译。预编译器将源文件中的SQL语句注释掉,对那些语句生成DB2运行时API调用。

在预编译一个应用之前,必须连接到一个数据库服务器,不论是自动连接还是显性连接。即使你在客户端工作站上预编译应用程序、预编译器在客户端产生的修改后源文件和信息,预编译器也需要使用服务器连接来执行一些确认任务。

预编译器也创建数据库管理器在处理针对某个数据库的SQL语句时需要的信息。这些信息存储在一个程序包或者一个捆绑文件或者两者之中,视预编译器的选项而定。

下面是使用预编译器的一个典型例子。预编译一个名叫filename.sqc的C嵌入式SQL源文件,发出下面的命令创建一个C源文件,默认名字为filename.c,和一个捆绑文件,默认名字为filename.bnd:

    DB2 PREP filename.sqc BINDFILE

预编译器最多产生四种类型的输出:

l  修改后的源文件

l  程序包

l  捆绑文件

l  信息文件

1、修改后的源文件

这个文件是预编译器将SQL语句转化为DB2运行时API调用后,原始源文件的新版本。它被赋予了相应宿主语言的扩展名。

2、程序包

如果使用了PACKAGE选项(默认的),或者没有指定任何BINDFILE、SYNTAX、SQLFLAG选项,程序包存储在所连接到的数据库中。程序包仅仅包含执行访问本数据的SQL语句时需要的所有信息。除非你用PACKAGE USING选项指定一个不同的名字,否则预编译器将使用源文件名字的前8个字符作为程序包名。

使用PACKAGE选项时,在预编译处理过程中使用的数据库必须拥有源文件中静态SQL语句参考到的所有数据库对象。例如不能够预编译一条SELECT语句,如果参考的表在数据库中不存在。

3、捆绑文件

如果使用了BINDFILE选项,预编译器将创建一个捆绑文件(扩展名为.bnd),它包含创建程序包的一些数据。这个文件可以在后面用BIND命令将应用捆绑到一个或多个数据库。如果指定了BINDFILE选项,没有指定PACKAGE选项,捆绑被延缓直到执行BIND命令。注意,对于命令行处理器(CLP),PREP默认不指定BINDFILE选项。因此,如果你使用CLP,又想延缓捆绑,那么你必须指定BINDFILE选项。

 如果在预编译时请求一个捆绑文件但是没有指定PACKAGE选项,不会在数据库中创建程序包;对象不存在和没有权限的SQLCODE被看作警告而不会被看作错误。这使得你能够预编译程序和创建一个捆绑文件,不需要参考到的对象必须存在,也不需要你拥有执行正被预编译的SQL语句的权限。

4、信息文件(MessageFile)

如果使用了MESSAGES选项,预编译器将信息重定向到指定的文件中。这些信息包括警告和错误信息,它们描述了在预编译过程中产生的问题。如果源文件没有预编译成功,使用警告和错误信息来断定问题,改正源文件,然后再预编译。如果没有使用MESSAGE选项,预编译信息被写到标准输出上。

1.2.3 程序包

程序包就是存储在相对应数据库中的包含数据库系统在捆绑时对特定SQL语句所产生的访问策略。

所有SQL语句经过编译优化后就产生可以直接对数据库进行访问的访问策略,存储于相应的数据库中。这些访问策略可以在应用程序调用相对应的SQL语句时得到访问。程序包对应于特定的应用程序,但是并不是与应用程序一起存放,而是同相对应的数据库一起存放。

1.2.4 捆绑

捆绑(bind)是创建数据库管理器在应用执行时为了访问数据库而需要的程序包的过程。捆绑可以在预编译时指定PACKAGE选项隐含地完成,或者使用BIND命令依据预编译过程中产生的捆绑文件显性地完成。

下面是使用BIND命令的一个典型例子。将名为filename.bnd的捆绑文件捆绑到数据库,使用下面的命令:

    DB2 BIND filename.bnd

每一个独立预编译的源代码模块都需要创建一个程序包。如果一个应用有5个源文件,其中3个需要预编译,那么要创建3个程序包或者3个捆绑文件。默认上,每一个程序包的名字与产生.bnd文件的源文件名字相同,但是只要前8个字符。如果新建的程序包名字与已存在于数据库中的程序包名相同,新的程序包将替换原先存在的程序包。要显性地指定一个不同的程序包名,必须在PREP命令使用PACKAGEUSING选项。

1.2.5 工作单元

一个工作单元是一个单一的逻辑事务。它包含一个SQL语句序列,在这个序列中的所有操作,被看作一个整体,要么都成功,要么都失败。DB2支持两种类型的连接(connection)。连接类型决定一个应用程序如何与远程数据库工作,并且决定该应用程序同时能与多少个数据库工作。

(1)连接类型1

应用程序在每个工作单元中只能连接单个数据库,此时,这个工作单元称为远程工作单元(RUOW, Remote Unit of Work)

(2)连接类型2

允许应用程序在每个工作单元中连接多个数据库,此时,这个工作单元称为分布式工作单元(DUOW, Distributed Unit of Work)

我们来看下面的例子:

(1)Remote Unit of Work – Type 1 Connect

DB2数据库嵌入式SQL开发_第1张图片

在这个例子中,连接类型为1,工作单元为远程工作单元(RUOW),应用程序在连接到数据库DB2_2之前,必须结束当前的工作单元(即事务,通过执行COMMIT语句)。

(2)Distributed Unit of Work – Type 2 Connect

DB2数据库嵌入式SQL开发_第2张图片

在这个例子中,连接类型为2,工作单元为分布式工作单元(DUOW)。应用程序在连接到数据库DB2_2之前,不需要结束当前的事务。在一个工作单元中,可以有多个数据库连接,但是只有一个处于激活状态,其它都处于睡眠状态。用SET CONNECTION TO db_name语句切换数据库连接。

1.2.6 应用程序、捆绑文件与程序包之间的关系

一个程序包是一个存储在数据库中的对象,它包含在执行某个源文件中特定SQL语句时所需的信息。数据库应用程序对用来创建应用程序的每一个预编译源文件使用一个程序包。每一个程序包是一个独立的实体,同一个或不同应用程序所使用的程序包之间没有任何关系。程序包在对源文件执行附带绑定的预编译时创建,或者通过绑定绑定文件创建。

数据库应用程序使用程序包的原因:提高性能和紧凑性。通过预编译SQL语句,使得SQL语句在创建应用程序时被编译进程序包,而不是在运行时。每一条语句都被分析,高效率的操作数串存储在程序包中。在运行时,预编译器产生的代码调用数据库管理器运行时服务APIs,根据输入输出数据的变量信息,执行程序包。

预编译的优点仅仅对静态SQL语句有效。动态执行的SQL语句不用预编译,但是它们在需要在运行时完成处理的整个步骤。注意:不要认为一条SQL语句的静态版本的执行效率一定比其动态版本的高。在某个方面,静态SQL语句快是因为不需要动态语句的准备开销。在另一方面,同样的语句,动态执行会快些,是因为优化器能利用当前数据库的统计信息,而不是以前的统计信息。有关静态SQL与动态SQL的比较,参照下表: 

 

表-静态SQL与动态SQL的比较

考虑因素                                            最好的选择

执行SQL语句的时间:

少于两秒                                              静态

2 到10 秒                                             两者均可

多于10秒                                              动态

 

数据一致性

统一的数据分布                                   静态

轻微不统一分布                                   两者均可

高度不统一分布                                   动态

 

范围谓词(<,>,BETWEEN,LIKE)使用

很少使用                                              静态

偶然使用                                              两者均可

经常使用                                              动态

 

执行的重复性

很多次(10或者更多)                          两者均可

几次(少于10次)                                  两者均可

一次                                                      静态

 

查询的种类

随机                                                     动态

固定                                                     两者均可

 

 

运行时环境(DML/DDL)

事务处理(DML Only)                                                              两者均可

混合(DML和DDL – DDL affects packages)                      动态

混合(DML和DDL – DDL does not affect packages)       两者均可       

 

运行runstats的频度

很低                                                     静态

正常                                                     两者均可

频繁                                                     动态

 

1.2.7 定界符

如果源程序中有SQL语句,源程序不能立即被源语言编译器处理。它首先要经过一个翻译过程,将SQL语句翻译成源语言编译器能够理解的东西。做翻译工作的程序就叫做预编译器。预编译器识别SQL语句的方法是通过定界符将SQL语句标识出来。

定界符的作用是使预编译器能够识别出需被翻译的SQL语句,并且必须标识出每一条嵌入的SQL语句。不同的宿主语言使用不同的定界符,下表列出了四种常用语言的定界符:

 

语言

定界符

C;C++

EXEC  SQL

sql statement         ;

COBOL

EXEC  SQL

sql statement     END-EXEC.

FORTRAN

EXEC  SQL

sql statement

JAVA

#sqlj {sql statement} ;

 

例子:

l  SQL语句

UPDATE TEMPL

SET WORKDEPT=  ‘C02’

WHERE WORKDEPT =‘C01’

l  在C程序中的SQL语句

EXEC SQL

  UPDATE TEMPL

SET WORKDEPT =  ‘C02’

WHERE WORKDEPT = ‘C01’  ;

l  在COBOL程序中的SQL语句

EXEC SQL

  UPDATE TEMPL

SET WORKDEPT =  ‘C02’

WHERE WORKDEPT = ‘C01’

END-EXEC.


2.1编程方法

2.1.1 访问数据

在关系数据库中,必须使用SQL访问请求的数据,但是可以选择如何将SQL结合到应用程序中去。可以从下表列出的接口和它们支持的语言中选择:

 

接口

支持的语言

嵌入SQL

C/C++, COBOL, FORTRAN, Java (SQLJ), REXX

DB2 CLI 和ODBC

C/C++, Java (JDBC)

Microsoft Specifications, including ADO, RDO, and OLE DB

Visual Basic, Visual C++

Perl DBI

     Perl

Query Products

Lotus Approach, IBM Query Management Facility

一、嵌入SQL

嵌入SQL有其优势,它可以包含静态SQL或者动态SQL,或者两种类型混合使用。如果在开发应用程序时,SQL语句的格式和内容已经确定,应该考虑在程序中采用嵌入的静态SQL。利用静态SQL,执行应用程序的人暂时继承将应用程序捆绑到数据库中的用户的权限,而不需要对此人赋予其它权限(除了应用程序的执行权)。动态SQL的执行需要执行应用程序的人的权限,但也有例外情况,就是在捆绑应用程序的时候使用DYNAMICRULES BIND选项。一般来讲,如果直到执行时才能确定SQL语句,那么应该采用嵌入的动态SQL。这比较安全,而且可以处理更多形式的SQL。

注意:JAVA语言的嵌入SQL(SQLJ)应用程序只能嵌入静态SQL语句。然而,在SQLJ应用程序中,可以通过使用JDBC调用动态SQL语句。

在使用编程语言编译器前,必须对源文件进行预编译,将嵌入的SQL语句转换为宿主语言的数据库服务APIs。在应用程序运行之前,必须将程序中的SQL捆绑到数据库里。

我们在第三章“静态SQL应用编程”中有详细介绍。

二、DB2 CLI和ODBC

DB2调用级接口(DB2 CLI)是IBM公司数据库服务器的DB2系列可调用SQL接口,它是一个关系数据库数据访问的C和C++语言编程接口,它用函数调用的方式,将动态SQL语句作为参数传递给数据库管理器。也就是说,一个可调用的SQL接口就是一个调用动态SQL语句的应用程序编程接口(API)。CLI可以替代嵌入动态SQL,但是与嵌入SQL不同,它不需要预编译或者捆绑。

DB2 CLI是基于微软开放数据库连接(ODBC)规范和X/Open规范开发的。IBM选择这些规范是为了遵循业界标准,使熟悉这些数据库接口的应用程序开发人员能在短期内掌握CLI的开发方法。

JDBC:  

DB2在Java语言方面的支持包括JDBC,JDBC是一个与厂商无关的动态SQL接口,利用它使得应用程序可以通过标准Java方法调用实现数据的访问。

JDBC与DB2 CLI一样不需要作预编译或者捆绑,作为一个与厂商无关的标准,JDBC应用程序具有良好的移植性。用JDBC开发的应用程序只采用动态SQL。

三、微软规范

你可能感兴趣的:(IBM,DB2,DB2,嵌入式SQL)