《DB2数据库对象基础知识.docx》由会员分享,可在线阅读,更多相关《DB2数据库对象基础知识.docx(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、DB2数据库对象基本数据库对象 数据库对象是一个数据库的构造块(building block)。DB2 提供了不同类型的数据库对象来存储和表示不同信息。通过使用数据定义语言(DDL),可以创建、修改和删除数据库对象。要操纵数据库对象,可以使用数据操纵语言(DML),例如 SELECT、UPDATE、INSERT 和 SELECT 语句。常用的数据库对象有:表 用户定义数据类型 约束 视图 索引 除了 Family Fundamentals 教程里介绍的一些数据库对象外,还有一些其他的对象,很多开发人员在开发 DB2 应用程序时会发现这些对象比较有用。本节我们将介绍这些对象。在继续之前,有一点要
2、注意:在下面看到的一些例子中,对象名称是以小写形式指定的。无论 DB2 在哪个平台上运行,它总是以大写形式存储名称,除非标识符的名称以双引号()括起来了。例如,下面的语句创建一个名为 employee(小写)的表,该表的列定义与表 EMPLOYEE(大写)是一样的。CREATE TABLE employee LIKE employee别名 别名(alias) 是指一个已有的表、视图的另一个名称,也叫昵称(nickname)。别名也可以作为另一个别名的昵称。与这些对象一样,别名也可以被创建或删除,可以有与之相关的注释。下面是 CREATE ALIAS 语句的一些例子:CREATE ALIAS a
3、liastab1 FOR tab1;CREATE ALIAS bob.aliastab1 FOR tom.tab1;CREATE SYNONYM bob.aliastab2 FOR bob.aliastab1;可以看到,CREATE ALIAS 语句比较简单。可以在源对象所在的同一模式中创建别名(如第 1 行),或者也可以全限定别名(如第 2 行)。为了与 DB2 for zSeries 兼容,使用关键字 SYNONYM 代替 ALIAS 也是合法的(如第 3 行)。使用别名时无需专门的授权或权限。不过,需要获得与别名所引用的底层对象相关的授权。关于数据库对象权限的完整清单,请参考 DB2 D
4、BA 认证教程 Server management(请参阅 参考资料)。前面已提到,我们也可以为 昵称 创建别名。昵称是引用位于联邦系统上的数据表或视图的数据库对象。联邦数据库支持超出了本教程的范围。在本教程系列的第 2 部分,Data manipulation ,我们将学习更多有关联邦系统的知识。要为别名添加注释,可以发出以下语句:COMMENT ON aliastab1 IS My first alias on tab1要删除一个别名,使用 DROP 语句,这与所有其他数据库对象是一样的:DROP ALIAS aliastab1序列对象 序列(sequence)是一种数据库对象,这种对象允
5、许自动生成值。序列对象与标识列(identity column)不同,标识列是要与一个特定的表绑在一起的,而序列是一种全局的、独立的对象,同一个数据库中的任何表都可以使用它。标识列是序列对象的一种特例。因此,标识列的特征也适用于序列对象。下面就例释了一条 CREATE SEQUENCE 语句:CREATE SEQUENCE myseq AS INTEGER START WITH 360 INCREMENT BY 10 NO MAXVALUE CYCLE CACHE 20 任何包括 0 在内的数字数据类型都可用于序列值。这些类型包括 SMALLINT、INTEGER、BIGINT 或 DECIM
6、AL。基于这些数据类型的任何用户定义独特类型(distinct type)也都可以用于序列值。这进一步扩展了用户定义独特类型在应用程序中的使用。 如上面的例子所示,您可以为序列对象指定起始值,从而自定义序列对象。在这个例子中,序列的第一个值是 360。后续值的生成是由 INCREMENT BY 子句控制的。这里还支持正、负常量,以产生升序和降序值。 缺省情况下,一个序列所生成的最小值和最大值是由该序列数据类型的取值范围来界定的。例如,INTEGER 类型的序列值必须处在 -2,147,483,647 到 2,147,483,647 之间的范围内。在 DB2 SQL Reference Guid
7、e 中可以找到所有数字数据类型的取值范围。为了改变这种缺省行为,可以使用 MINVALUE 和 MAXVALUE 选项来为生成的值设置一个边界。如果达到了最小值或最大值,那么可以使用另一个选项,即 CYCLE 或 NO CYCLE 来规定序列值是否应该循环。注意,如果 CYCLE 生效,则序列就可以生成重复的值。CACHE 选项允许 DB2 将一些预先分配好空间的值保留在内存中,以提高性能。CACHE 20 是缺省的行为。关于这个选项有一点要谨记:如果在所有缓存的值被使用之前关闭 DB2,那么任何缓存的值和未使用的值都将被丢弃。当 DB2 重新启动时,又会生成和缓存下一块的值,从而造成值之间的
8、不连续,即值之间存在间隔。如果应用程序不允许值之间有间隔,可以考虑使用 NOCACHE 选项。如果没有使用缓存,则性能就会下降,因为要频繁地生成序列数字。每当生成一个新值的时候,都会写下一条日志记录。因此,更高效的做法是根据请求来获取值,并将这些值缓存在内存中。通过 ALTER SEQUENCE 语句,可以更改序列对象的特征。除了序列值的数据类型以外,上面所讨论的所有的设置都可以修改。要获得完整的语法,请参考 DB2 SQL Reference Guide (请参阅 参考资料)。删除一个序列对象与删除任何其他的数据库对象是一样的,不同之处是这里还要使用到一个 RESTRICT 关键字。这样可以
9、防止在有依赖的情况下删除序列。DROP SEQUENCE myseq RESTRICT生成和获取序列值 序列是一种数据库对象,因此对序列的访问也是由权限来控制的。缺省情况下,只有序列的创建者,即 SYSADM 和 DBADM 拥有该对象的 USAGE 权限。如果希望其他用户也能够使用序列,则需要使用下面的语句:GRANT USAGE ON SEQUENCE seq_object_name TO PUBLIC有两种表达式可用于生成和获取序列值。NEXTVAL FOR seq-name 用于获取下一个序列值,而 PREVVAL FOR seq-name 则用于获取上一个生成的序列值。下面的例子例释
10、了这些表达式的使用。INSERT INTO t1 VALUES (NEXTVAL FOR myseq, BOB);INSERT INTO t1 VALUES (NEXTVAL FOR myseq, PAT);COMMIT;INSERT INTO t1 VALUES (NEXTVAL FOR myseq, GENE);ROLLBACK;INSERT INTO t1 VALUES (NEXTVAL FOR myseq, PAUL);VALUES PREVVAL FOR myseq INTO :hostvar假设我们以一个空表 t1 开始,myseq 的下一个序列值是 1。如果禁用了 autocom
11、mit,则在执行上述语句之后,t1 将包含下面几行:1NAME-1BOB2PAT4PAUL 3 record(s) selected.虽然为 GENE 生成的值被回滚了,但是 DB2 并没有再次使用它。因而,下一个为 PAUL 生成的序列值就是 4,而不是 3。 这个例子中的最后一条语句展示了如何使用 PREVVAL 表达式。宿主变量 :hostvar 存储当前会话中生成的最后一个值。如果想保存前面生成的值,那么应该在生成下一个值之前保存 PREVVAL 值。临时表 顾名思义,临时表(temporary table)不是永久性的数据库对象。临时表与普通的表在行为上是一样的,不同之处是,并非所有
12、的功能和选项都是受支持的和/或是必需的。临时表只能维持在一次连接期间。当连接关闭时,在此连接内声明的所有临时表都将自动删除掉。 只有声明临时表的会话或应用程序才能访问临时表。如果两个应用程序用相同的名字创建了一个临时表,该临时表的每个实例仍然是惟一的。因而,完全不必担心出现临时数据冲突的情况。由于临时表只允许单连接(single-connection)访问,因此这里无需使用锁。这正是临时表的一个主要的性能优势。声明临时表 要声明一个临时表,必须存在一个 USER 临时表空间(不同于 SYSTEM 临时表空间),用以存储临时表的定义和内容。SYSTEM 临时表空间只是 DB2 在内部用来执行诸如
13、排序之类操作的。下面这条简单的语句将创建一个用户临时表空间。CREATE USER TEMPORARY TABLESPACE usertempspace MANAGED BY SYSTEM USING (usertempspace)声明全局临时表时,可以使用很多可选子句。下面的例子对这些子句的特性作了说明。DECLARE GLOBAL TEMPORARY TABLE t_dept ( deptid CHAR(6), deptname CHAR(20) )ON COMMIT DELETE ROWS NOT LOGGEDIN usertempspace在这个例子中,声明了临时表 t_dept,这个
14、表有两列。ON COMMIT DELETE ROWS 子句规定在每次执行 COMMIT 操作时删除临时表的内容。在 DB2 V8 中,可以选择记录对临时表的更改,以便回滚。这个例子规定对该表的更改是 NOT LOGGED。这意味着对该表的任何操作,包括创建以及更改,都不做日志记录。如果在一个工作单位内创建表,然后回滚,则临时表将被删除。另一方面,如果在此工作单位内删除该表,则该表在恢复时将没有任何行。无需使用 IN 子句来指定该临时表将要使用的用户临时表空间。如果没有指定该信息,DB2 就会搜索最适用的表空间。如果找不到用户临时表空间,DB2 将产生一个错误。让我们看看另一个例子:DECLAR
15、E GLOBAL TEMPORARY TABLE t_proj LIKE project ON COMMIT PRESERVE ROWS WITH REPLACE IN usertempspace临时表 t_proj 是用 LIKE 关键字声明的,因此它拥有与名为 project 的持久表或视图相同的列定义。ON COMMIT PRESERVE ROWS 子句表明,在执行 COMMIT 语句时,该临时表中的所有行都将被保留。因此,这些行就可以在下一次事务中用于进一步的处理。在同一次会话中使用相同的名称声明另一个临时表之前,首先必须删除该临时表。可以显式地删除该表,也可以像这里一样使用 WITH
16、 REPLACE 选项。如果使用了 WITH REPLACE 选项,DB2 将隐式地删除所有数据,删除该临时表,并用新的定义重新创建该临时表。如果使用了 连接池(connection pooling),WITH REPLACE 选项用起来就十分方便了。连接池是用于重用数据库连接的一种机制,这样就不必完全按照要求分配和回收资源。这些操作的开销都是相当大的,尤其是在有大量执行很短事务的连接时,更是如此。由于没有释放连接,先前使用的临时表就可能得不到清除。下一个使用该连接的应用程序就可能使用上一次执行时遗留下来的数据。因此,使用 WITH REPLACE 选项可以保证用新的定义刷新所声明的临时表。模
17、式与数据库对象 大多数数据库对象都是用一个 模式(schema) 和一个 对象名(object name)标识的。数据库模式为数据库对象提供逻辑上的分类。下面例释了这种分为两部分的对象名:DB2ADMIN.EMPLOYEEHRPROD.AUDIT_VIEWHRPROD.AUDIT_TRIG如果在访问数据库对象时没有指定模式,则用于建立数据库连接的用户 ID 将被设为缺省的模式。例如,如果用户 db2admin 连接到一个数据库,并创建表 T1,则 DB2 将创建一个名为 db2admin.T1 的表。此后所有引用非全限定(unqualified)表名 T1 的 SQL 语句都解析为 db2ad
18、min.T1。DB2 专用寄存器:CURRENT SCHEMA 您在进行自己的数据库工作时可能已经发现,用同为对象的模式的用户 ID 连接到一个数据库并非总是可行的。而硬编码(hard-coding)应用程序以完全限定对象也不是最好的解决办法。幸运的是,DB2 允许使用 SET CURRENT SCHEMA 命令更改当前模式。缺省情况下,CURRENT SCHEMA DB2 专用寄存器被设置为连接到数据库的 USER。如果更改 CURRENT SCHEMA,那么任何非全限定的数据库对象都会在前面加上新的值。当前模式可以通过下面这个命令获得:VALUES CURRENT SCHEMA要对它进行更
19、改,只需使用下面的命令:SET SCHEMA=db2adminDB2应用程序开发数据库对象例程 在本节中,我们将介绍更多类型的数据库对象。这些对象统统都叫做 例程(routine)。从功能上分,主要有三种例程:存储过程(stored procedure)、函数(function)和方法(method)。(要了解这些类型之间的更多不同之处,请参阅 存储过程、函数和方法。)例程是封装了与某一特定任务相关的编程和数据库逻辑的数据库对象。有效地使用例程可以简化应用程序的代码,并增加代码的可重用性。例如,如果将某种业务逻辑封装在一个例程中,那么对此业务规则的更改只会影响那个特定的例程。从而可最小化对应用
20、程序的更改。例程是在数据库服务器上定义和处理的。这样就允许应用程序利用数据库服务器的能力,从而减少客户机上的处理负载。通常,复杂的业务逻辑需要多条 SQL 语句。这些语句要分别地从客户机发送到服务器,如果数据库活动很多,就会产生大量的网络传输。如果将这些操作放在一个例程中,那么客户机和服务器之间的网络传输就会大大减少,从而可以提高应用程序的总体性能。加强安全的能力是使用例程的另一个关键优势。例程可用于屏蔽对底层数据库对象的直接访问。用 EXECUTE 权限调用一个例程就足够了,无需拥有访问底层数据库对象的显式的权限。例程的不同实现 例程有几种可能的实现:内置(built-in)例程是 DB2
21、系统附带的。这些例程定义在一个系统模式中,例如 SYSIBM、SYSPROC、SYSFUN 和 SYSTOOLS。 Sourced 例程只适用于函数。sourced 例程复制另一个函数的语义。 外部(external)例程是用一种外部的编程语言实现的。对于 DB2 V8.1,可以用下列受支持的语言开发例程: Java 语言 C/C+ OLE(仅用于存储过程) OLE DB(仅用于表函数) SQL 例程是用 SQL Procedural Language (SQL PL)实现的。DB2 SQL PL 是 SQL Persistent Stored Modules (SQL/PSM) 语言标准的一
22、个子集。该标准是与 SQL 一起用来编写存储过程、函数和方法的结构化编程语言的基础。它将 SQL 数据访问的容易性与简单编程语言的流控制结构相结合。这就是 SQL PL 如此流行的一个主要原因。存储过程、函数和方法 存储过程 是一种数据库对象,它包含用于访问和修改一个或多个表中数据的专门程序。在一个存储过程内,可以以一定的流逻辑包装多条 SQL 语句。存储过程可以作为对客户机应用程序或其他例程的子例程扩展。存储过程的执行和管理是由一个关系数据库管理系统(RDBMS)控制的。函数 是可以自定义的 SQL 扩展。可以在 SQL 语句(例如一个 select-list 或 FROM 子句)中调用函数
23、。有四种类型的函数:聚合(aggregate)函数、标量(scalar)函数、行(row)函数以及 表(table)函数。 存储过程通常用于封装复杂的应用程序逻辑,以及执行开销较大的数据库操作,例如多表联结和游标操作。而函数 尤其是 SQL 函数 通常包含更简单的操作。编写在 SQL 函数中的语句将展开到引用它们的 SQL 语句中,与这些 SQL 语句一起执行。这导致这些语句在执行时动态编译。如果一条 SQL 语句中使用了一个复杂的 SQL 函数,则 DB2 要求使用附加的资源来编译它,并生成一个数据访问计划。这样将影响整个运行时性能。 方法 用于封装为结构类型提供行为的逻辑,结构类型包含一个
24、或多个指定的属性,各属性有其自己的数据类型。DB2 专用寄存器:CURRENT PATH 与大多数 DB2 数据库对象一样,一个完整的例程名由一个模式和一个例程名组成。 DB2 专用寄存器 CURRENT SCHEMA可以为大多数数据库对象解析模式,但不能为例程解析模式。相反,DB2 是使用 CURRENT PATH 专用寄存器来定位例程的。通过下面的命令可以获得 CURRENT PATH 设置:VALUES CURRENT PATH缺省路径包含三个系统模式,后面跟有连接到数据库的当前用户。例如:SYSIBM,SYSFUN,SYSPROC,DB2ADMIN下面是一些例子和技巧,您可以用它们来更
25、新 PATH:SET PATH=CURRENT PATH,USER2VALUES CURRENT PATH-SYSIBM,SYSFUN,SYSPROC,DB2ADMIN,USER21 record(s) selected.嵌入式 SQL 程序嵌入式 SQL 简介 DB2 为开发人员提供了不同的编程方法来编写应用程序。最直接的一种方法是嵌入式 SQL 编程。这种编程方法是 直接的,因为程序嵌入了直接与 DB2 交互的 SQL 语句。程序可以用下列受支持的编程语言中的任何一种来编写:C/C+ FORTRAN COBOL Java 语言 (SQLJ) 如何构造嵌入式 SQL 语句取决于所选择的编程语
26、言。C/C+ 和 FORTRAN 中的嵌入式 SQL 语句前面要加上 EXEC SQL 关键字:EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 FROM employee WHERE deptno=OPERATIONS;COBOL 中的嵌入式 SQL 语句非常类似于 C/C+ 中的那些嵌入式 SQL 语句,不同的是在语句的后面要使用 END-EXEC 关键字:EXEC SQL SELECT lastname,empid INTO :hostvar1, :hostvar2 FROM employee WHERE deptno=OP
27、ERATIONS END-EXEC;Java 语言中的嵌入式 SQL 语句与前面两个例子中展示的那些嵌入式 SQL 语句稍微有些不同,这里必须指定语句将来执行时所在的连接上下文。下面是一个例子:#sql myConnCtx SELECT lastname, empid INTO :hostvar1, :hostvar2 FROM employee WHERE deptno=OPERATIONS;为了让您更好地了解嵌入式 SQL 语句是什么样子的,下面给出了用 C 编写的一个程序的代码片断。在本系列(请参阅 参考资料)的第 3 篇教程中,您将了解到更多关于程序预编译和实际代码开发的知识。int
28、TbBasic(void) int rc = 0; struct sqlca sqlca; EXEC SQL BEGIN DECLARE SECTION; char hostVarStmt50; EXEC SQL END DECLARE SECTION; /* delcare cursor */ EXEC SQL DECLARE c1 CURSOR FOR SELECT deptnumb, deptname FROM org WHERE deptnumb = 40; /* open cursor */ EXEC SQL OPEN c1; /* fetch cursor */ EXEC SQL
29、FETCH c1 INTO :deptnumb, :deptname; while (sqlca.sqlcode != 100) printf( %8d %-14sn, deptnumb, deptname); EXEC SQL FETCH c1 INTO :deptnumb, :deptname; /* close cursor */ EXEC SQL CLOSE c1; /* prepare the statement */ strcpy(hostVarStmt, DELETE FROM org WHERE deptnumb = 15); EXEC SQL PREPARE Stmt FRO
30、M :hostVarStmt; /* execute the statement */ EXEC SQL EXECUTE Stmt; /* ROLLBACK the transaction */ EXEC SQL ROLLBACK; return 0;静态 SQL 在前一小节中,我们演示了两种不同类型的嵌入式 SQL 语句:静态嵌入式 SQL 和动态嵌入式 SQL。这个例子中的 SELECT 语句说明了静态 SQL 的使用。编写静态 SQL 时,必须指定完整的语句。表名、列名以及所引用的数据类型都是已知的。惟一可以在运行时指定的信息是使用宿主变量的 SQL 语句的 WHERE 子句中的值。编译
31、静态 SQL 语句(或者,用 DB2 术语更确切地说,准备好的(prepared)SQL 语句)时,将为其生成数据访问计划,并存储在数据库中的一个包里面。当调用包含该语句的应用程序时,这个包将被执行。由于在运行时不需要编译语句,因此执行静态 SQL 时没用编译开销。在准备语句时,DB2 使用数据库统计信息和配置参数来估计和获得访问计划。如果数据库统计信息有变化,则预先生成的访问计划可能不如一开始生成时那样是最佳的。创建包和将包与数据库绑定时,要对准备静态 SQL 语句的人进行授权。只要执行包的人拥有包的 EXECUTE 权限,他就不需要具备该包中所引用的数据库对象上的显式的权限。动态 SQL
32、动态(Dynamic SQL) 语句是在运行时动态处理的。语句的结构直到执行应用程序时才需要。注意,嵌入式 SQL 简介 中展示的例子 SQL 语句使用动态 SQL 来 PREPARE 和 EXECUTE 一条 DELETE 语句。DELETE 语句的文本存储在一个宿主变量 hostVarStmt 中。当该语句 PREPARE 好后,系统将生成该语句的一个可执行格式,并将其存储在数据库中的一个包里面。一旦生成了数据访问计划,准备好的语句就可以 EXECUTE 了。听起来好像有点熟悉,不是吗?是的:这两个处理阶段与静态 SQL 语句正好是一样的。惟一的不同点是,动态 SQL 的 PREPARE
33、和 EXECUTE 都是在运行时进行,而静态 SQL 在预编译时准备访问计划,并将其保存在数据库中。动态 SQL 语句必须总是在执行之前准备好,不管是否有相同的语句(相同的访问计划)一次又一次地重复使用。为了最小化这些准备工作的开销,DB2 提供了 包缓存(也叫 动态查询缓存),用以将经常使用的访问计划保存在内存中。包缓存(package cache)明显地减少了重复的 SQL 准备请求的代价,然而发起和响应准备请求的开销仍然存在。在准备语句时,总是使用当前数据库统计信息。因此,就可以生成最佳的数据访问路径。SQL 语句的授权是在运行时决定的。执行应用程序的人必须有适当的权限来访问语句中所引用
34、的数据库对象。下一小节将更详细地讨论 DB2 权限。安全考虑 要预编译嵌入式静态 SQL 程序,用户需要程序中所引用数据库对象的显式的权限。由于预编译或 PREPARE 阶段会生成一个包,并将其存储在数据库中,因此该用户还必须拥有 BINDADD 权限,以便添加新的包到数据库中。为了执行带有静态 SQL 的程序,用户只需具有相关包上的 EXECUTE 权限。编译嵌入式动态 SQL 程序的用户也需要 BINDADD 权限。这里不再需求其他的权限,因为动态 SQL 不是在编译时准备的。在程序执行时,用户需要所有必需的权限来发出每条 SQL 语句,同时还需要为嵌入式 SQL 程序创建的包上的 EXE
35、CUTE 权限。下面的表总结了预编译和执行一个只有静态 SQL 或只有动态 SQL 的程序所需的权限。 静态 SQL 与动态 SQL在下面的表中,让我们总结并详细阐述我们所学到的关于静态 SQL 和动态 SQL 的知识:基于驱动程序的 API基于驱动程序的 API虽然大多数供应商都支持嵌入式 SQL 数据库访问,但如果您想要使用同样的源代码,并将嵌入式 SQL 应用程序部署到多个数据库系统上,那么还需要一个额外的工作。必须用不同供应商的特定的预编译器预编译程序。还必须生成数据访问计划,并绑定到目标数据库。为了增加应用程序的可移植性,还应考虑使用本节介绍的 基于驱动程序的解决方案。基于驱动程序的
36、解决方案需要一个驱动程序管理器(driver manager),这是与应用程序打交道的界面。驱动程序管理器提供了一套工业标准的应用程序编程接口(API),用于访问数据源。应用程序调用这些 API,然后被编译,再与管理器的库链接。因为驱动程序遵从标准,所以应用程序可以很容易地使用(或装载)正确的驱动程序来访问不同供应商的数据源。 在下面几小节中,我们将看看 DB2 支持的一些 API。在本系列后面的教程中,您将更详细地了解这些 API。CLI 和 ODBC API DB2 Call Level Interface (CLI) 是 IBM 对 DB2 数据库服务器的可调用 SQL 接口。CLI 是
37、用于数据访问的一个 C/C+ 应用程序编程接口(API)。您可以使用 DB2 CLI 开发动态应用程序,就像使用嵌入式动态 SQL 语句进行开发一样。在这两种情况下,SQL 语句都是在运行时准备和处理的。嵌入式动态 SQL 要求有一个预编译器,而 DB2 CLI 则没有这种要求。您只需编译应用程序,并与 DB2 CLI 驱动程序库链接。DB2 CLI 是基于 Microsoft Open Database Connectivity (ODBC) 和 X/Open CLI 标准的。在 ODBC 环境中,应用程序与数据库服务器之间的联系要通过 ODBC 驱动程序管理器。该管理器动态地加载应用程序需
38、连接的数据库服务器所需的驱动程序。ODBC 提供某些级别的功能支持,当前的 DB2 CLI 遵从 ODBC 3.51。要开发 DB2 CLI 应用程序,需要 DB2 Application Development Client。它包括编译和链接 CLI 应用程序时所有必需的头文件和库。而要开发 ODBC 应用程序,则需要 Microsoft 提供的一个 ODBC Developers Software Kit。下面的图对 DB2 CLI 与 ODBC 环境作了快速的比较。OLE DB 与 ADO.NET API Microsoft Object Link Embedded Database (
39、OLE DB) 是一套接口,它为应用程序提供了对存储在不同信息源上的数据的统一访问,这些不同的信息源包括关系数据源和非关系数据源。OLE DB 架构由 OLE DB 提供者和 OLE DB 消费者组成。DB2 同时支持这两种角色。为了使 DB2 能够充当 OLE DB 提供者,必须要有 IBM OLE DB Provider for DB2。这是一个本地驱动程序,支持通过 OLE 接口提取或查询 DB2 数据。下面的图展示了一个可作为 OLE DB 消费者的 DB2 数据库,它可以访问来自任何遵从 OLE DB 的数据源(例如一个电子表格)的数据。同样的 DB2 服务器也可以作为一个 OLE
40、DB 提供者,为 OLE DB 消费者提供数据。ActiveX Data Object .NET (ADO.NET) 是 Microsoft 提供的另一种数据访问应用程序接口。它是一种新的数据访问模型,将其前任(ADO)最好的特性与传统的数据库访问相结合,集成了 XML 支持,是一种断开连接的(disconnected)数据架构。有三种方法从一个 .NET 应用程序连接到一个 DB2 数据库,如下图所示。 JDBC 和 SQLJ API 至今为止,Java 平台已经享誉多时,但仍有很多人正在致力于扩展其功能和提高其性能。访问和操纵 DB2 的 Java 程序可以使用 Java Database
41、 Connectivity (JDBC) API,以及 Embedded SQL for Java (SQLJ) 标准。这两个选项都是供应商无关的 SQL 接口,通过标准化的 Java 方法为应用程序提供数据访问。JDBC 是用于关系数据库访问的 实际上的 标准 Java API,这种访问通过强大的面向对象的接口,使用动态 SQL。JDBC 将动态 SQL 传递给 DB2 附带的一个 JDBC 驱动程序。DB2 通过 JDBC API 执行 SQL 语句,结果被传回给 Java 代码。JDBC 类似于 DB2 CLI,您无需预编译或绑定 JDBC 程序,因为 JDBC 使用动态 SQL。而 S
42、QLJ 程序则包含静态嵌入式 SQL 语句。准备一个 SQLJ 程序时需要通过类似于预编译和绑定的步骤。在编译 SQLJ 源文件之前,必须用 SQLJ 翻译器对其进行翻译,以创建本地 Java 源代码。完成翻译后,需要使用 DB2 for Java profile customizer (db2profc) 创建 DB2 包。DB2 遗留的基于CLI 的 JDBC 驱动程序 根据 Java 2 Platform, Enterprise Edition (J2EE) 规范,用于获得数据访问的 Java 方法和接口可以打包成 JDBC 驱动程序。DB2 JDBC 驱动程序分为遗留的基于 CLI 的
43、驱动程序和新的通用 JDBC 驱动程序。遗留的基于 CLI 的 JDBC 驱动程序建立在本地 DB2 CLI 之上。这里有两个实现类。第一个是 JDBC Type 2 driver,也叫 app driver。它是由类 com.ibm.db2.jdbc.app.DB2Driver 实现的。另一个实现是 JDBC Type 3 driver,也叫 net driver。要使用 app driver,必须在 JDBC 程序执行时所在的客户机上安装一个 DB2 客户机。所有 JDBC 调用都被转换成 DB2 CLI 调用。DB2 JDBC Type 3 driver 也将 JDBC 调用映射为 DB
44、2 CLI。有了这个驱动程序,就不必在客户机上安装 DB2 客户机。然而,还是需要一个 JDBC 侦听器(或 JDBC 监护程序)。DB2 V8 中摒弃了 net driver,而推荐 Type 4 driver。在下一小节我们将讨论 Type 4 driver。DB2 Universal JDBC 驱动程序 Fixpak 2 of DB2 V8 引入了 DB2 Universal JDBC 驱动程序。之所以称之为 通用(universal) 驱动程序,是因为它使用 Distributed Relational Database Architecture (DRDA) 协议,所有 DB2 家族
45、的数据库都共用该协议。该驱动程序支持与使用 Type 4 driver 架构的 DB2 服务器建立直接 Java 连接。该驱动程序也有两个实现类,分别叫做 Java Common Client (JCC) Type 2 driver 和 JCC Type 4 driver。实现类的名称是 com.ibm.db2.jcc.DB2Driver。结束语 本教程介绍了 DB2 应用程序开发的基础。在进行开发之前,您需要熟悉不同类型的数据库对象。在本教程中,介绍了一些高级的数据库对象。别名、序列对象以及临时表常用于简化应用程序的代码。存储过程、函数和方法主要用于封装程序和数据库逻辑。本教程讨论了使用例程
46、的一些优点,例如减少网络传输,加强安全,以及提高代码的可重用性。您应该根据应用程序逻辑的复杂性,选择将逻辑封装在过程和函数中。存储过程可作为程序的子例程,通常包含复杂的应用程序逻辑。而用户定义函数则是对 SQL 的一种扩展。它们以简单的语句和逻辑高效地执行。 在本教程中,我们还介绍了一些编程方法。嵌入式 SQL 编程允许将 SQL 语句嵌入在用 C/C+、FORTRAN、COBOL 或 Java 语言编写的程序中。本教程还强调了静态 SQL 代码和动态 SQL 代码的特征。您需要理解两者之间的不同之处,以便在使用静态 SQL 语句与使用动态 SQL 语句之间作出选择。应用程序编程接口,例如 CLI、ODBC、ADO、OLE DB 和 JDBC 都是动态程序。DB2 提供了本地驱动程序,使得应用程序能够通过这