DB2数据库CLI应用开发.docx
- 文档编号:4267515
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:19
- 大小:57.79KB
DB2数据库CLI应用开发.docx
《DB2数据库CLI应用开发.docx》由会员分享,可在线阅读,更多相关《DB2数据库CLI应用开发.docx(19页珍藏版)》请在冰豆网上搜索。
DB2数据库CLI应用开发
DB29应用开发
CLI/ODBC编程简介
什么是CLI/ODBC?
结构化查询语言(StructuredQueryLanguage,SQL)是用于操纵数据库对象和它们包含的数据的一种标准语言。
但是,由于SQL没有过程语言的性质,因此,通常是将高级编程语言的决策和顺序控制与SQL的数据存储、操纵和检索功能相结合来开发数据库应用程序。
有一些方法可以将SQL与高级编程语言相结合,但最简单的方法是将SQL语句直接嵌入到用于创建应用程序的高级编程语言源代码文件中。
这种技术被成为嵌入式SQL编程。
嵌入式SQL编程最大的缺点是所开发的应用程序缺乏互操作性。
用嵌入式SQL为DB2开发的应用程序如果要与其他关系数据库管理系统(RDBMS)交互,必须进行修改(在某些情况下,甚至要完全重写)。
由于不论为何种RDBMS编写的嵌入式SQL应用程序中都存在这样的限制,因此在20世纪90年代初,X/Open公司和SQLAccessGroup(SAG,现在属于X/Open)就为可调用SQL接口联合开发了一种标准的规范。
这种接口被称为X/OpenCLI。
大部分X/OpenCLI规范后来都被接受为ISOCLI国际标准的一部分。
X/OpenCLI的主要目的是通过允许数据库应用程序独立于任何一种数据库管理系统的编程接口,增加数据库应用程序的可移植性。
在1992,Microsoft为MicrosoftWindows操作系统开发了一个名为OpenDatabaseConnectivity(ODBC)的可调用SQL接口。
ODBC基于X/OpenCLI标准规范,它提供了X/OpenCLI没有提供的扩展功能和能力。
ODBC位于一个操作环境之上,在此环境中,一个名为ODBCDriverManager的组件在应用程序运行时动态地装载特定于数据源的ODBC驱动程序。
每个特定于数据源的驱动程序负责实现ODBC规范中定义的一种或全部功能,并提供与该驱动程序所针对的特定数据源的交互。
ODBCDriverManager提供了一个集中控制点;当一个ODBC应用程序执行时,发出的每个ODBC函数调用被发送到ODBCDriverManager,并从那里转发到适当的数据源驱动程序进行处理。
通过驱动程序,可以将应用程序直接链接到一个ODBC驱动程序库,而不必链接到每种特定于产品的数据库本身。
DB2CallLevelInterface(DB2CLI)基于ISOCLI国际标准,它提供了ODBC规范中给出的大部分功能。
使用DB2CLI而不是ODBC的应用程序直接链接到DB2CLI加载库,任何ODBCDriverManager都可以加载这个库作为一个ODBC驱动程序。
DB2UDB应用程序还可以独立地使用DB2CLI装载库。
但是,当以这种方式使用这个库时,应用程序本身不能与其他数据源通信。
嵌入式SQL与CLI/ODBC的区别
在本系列的第四篇教程中可以看到,嵌入式SQL应用程序是通过直接将SQL语句嵌入到使用高级编程语言编写的一个或多个源代码文件中而构建的。
而CLI/ODBC应用程序则依赖于一组标准的应用程序编程接口(API)函数将SQL语句发送到DB2DatabaseManager进行处理。
嵌入式SQL应用程序和CLI/ODBC应用程序在以下方面也有不同之处:
CLI/ODBC应用程序不需要显式地声明和使用主机变量;可以使用任何变量来发送数据或者从一个数据源检索数据。
CLI/ODBC应用程序不必显式地声明游标。
相反,每当执行SQLExecute()函数或SQLExecDirect()函数(稍后会更详细讨论这两个函数)时,会根据需要自动生成游标。
在CLI/ODBC应用程序中,不需要显式地打开游标;当生成游标时,会自动打开游标。
CLI/ODBC函数使用句柄管理环境、连接和与SQL语句相关的信息。
这种技术便于将那些信息当作抽象对象来对待。
通过使用句柄,CLI/ODBC应用程序就不必使用特定于数据库产品的数据结构,例如DB2SQLCommunicationsArea(SQLCA)和SQLDescriptorArea(SQLDA)数据结构。
CLI/ODBC应用程序天生就具有建立到多个数据源或同一个数据源的多个连接的能力。
(嵌入式SQL应用程序只有在使用Type2连接的情况下,才能一次连接到多个数据源。
)
嵌入式SQL应用程序和CLI/ODBC应用程序虽然有这么多不同之处,但是它们在概念上也有一个重要的共同点:
CLI/ODBC应用程序可以执行任何能在嵌入式SQL应用程序中动态准备的任何SQL语句。
这一点是有保障的,因为CLI/ODBC应用程序将所有的SQL语句直接传递到数据源,以便动态执行这些语句。
(CLI/ODBC应用程序还可以执行一些不能动态准备的SQL语句,例如复合SQL语句,但是通常上不支持静态SQL。
)
由于是由数据源来处理CLI/ODBC应用程序提交的所有SQL语句,这就保证了CLI/ODBC应用程序的可移植性。
而嵌入式SQL并不总是如此,因为如果所使用的关系数据库产品不同,动态准备SQL语句的方式也会有所不同。
另外,由于有些数据库产品(包括DB2)可以动态准备COMMIT和ROLLBACKSQL语句,而有些数据库产品又不能,因此CLI/ODBC应用程序中通常不使用这些语句。
相反,CLI/ODBC应用程序依靠SQLEndTran()函数结束活动事务(不使用自动提交的情况下)。
这种技术可保证不管使用何种数据库产品,CLI/ODBC应用程序都能成功地结束事务。
构造CLI/ODBC应用程序
CLI/ODBC应用程序的组成部分
所有CLI/ODBC应用程序都要被构造来执行以下三个不同的任务:
初始化
事务处理
终止
每个任务涉及到的工作是通过调用一个或多个CLI/ODBCAPI函数来实现的。
用于实现这些任务的很多CLI/ODBC函数必须按照特定的顺序来调用,否则会发生错误。
图1标出了用于执行初始化和终止任务的一些基本的CLI/ODBC函数:
图1.CLI/ODBC应用程序执行的基本任务
CLI/ODBC应用程序还可以执行图1中列出的3个任务以外的任务,例如错误处理和消息处理。
在后面的小节诊断和错误处理中,可以看到CLI/ODBC应用程序中如何处理错误。
分配资源
在初始化期间,需要分配(和初始化)处理事务所需的资源,并建立到事务处理任务需要使用的数据源的连接。
CLI/ODBC应用程序使用的资源由通过惟一句柄标识的专用数据存储区组成。
(句柄是一个简单的指针变量,它指向DB2CLI或ODBCDriverManager所控制的数据对象,该数据对象由CLI/ODBC函数调用引用。
)通过使用数据存储区和句柄,CLI/ODBC应用程序不必负责分配和管理全局变量和诸如嵌入式SQL应用程序中使用的SQLCA和SQLDA之类的数据结构。
有四种不同类型的句柄:
环境句柄:
指向一个数据存储区的指针,该数据存储区包含特定于CLI/ODBC的全局信息。
连接句柄:
指向一个数据存储区的指针,该数据存储区包含关于CLI/ODBC管理的数据源(数据库)连接的信息。
语句句柄:
指向指向数据存储区域的指针,该数据存储区包含单个SQL语句有关的特定信息。
描述符句柄:
指向一个数据存储区域的指针,该数据存储区包含一个元数据集合,这些元数据描述被绑定到SQL语句中的参数标记的应用程序变量,或者被绑定到查询结果数据集中列的应用程序变量。
每个CLI/ODBC应用程序必须从分配一个环境句柄开始。
通常每个应用程序只分配一个环境句柄,并且在分配任何其他句柄之前,那个环境句柄必须已经存在。
所有其他句柄都是在环境句柄使用的上下文环境中管理的。
环境句柄可以通过调用SQLAllocHandle()函数并指定SQL_HANDLE_ENV选项来分配。
用于分配环境句柄的源代码如下所示:
SQLHANDLE EnvHandle = 0;
...
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandle);
在CLI/ODBC应用程序中,到数据源的连接是通过连接句柄实现的。
因此,在建立到任何数据源的连接之前,必须存在一个连接句柄。
可以通过调用SQLAllocHandle()函数并指定SQL_HANDLE_DBC选项和一个有效的环境句柄来分配连接句柄。
用于分配连接句柄的源代码如下所示:
SQLHANDLE ConHandle = 0;
...
if (EnvHandle !
= 0)
SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &ConHandle);
CLI/ODBC应用程序的真正骨干是语句句柄。
语句句柄用于:
将应用程序变量绑定到SQL语句中使用的参数标记。
准备和提交SQL语句到适当的数据源,以便执行。
获得关于SQL语句产生的结果数据集的元数据。
将应用程序变量绑定到结果数据集中的列。
从结果数据集中检索(读取)数据。
当SQL未能执行时,获得诊断信息。
CLI/ODBC应用程序中编写的每条SQL语句都必须有它自己的语句句柄。
每个语句句柄只能与一个连接句柄相关联。
但是,一个连接句柄可以与任意数量的语句句柄相关联。
语句句柄可以通过调用SQLAllocHandle()函数并指定SQL_HANDLE_STMT选项和一个有效的连接句柄来分配。
因此,用于分配语句句柄的源代码如下所示:
SQLHANDLE StmtHandle = 0;
...
if (ConHandle !
= 0)
SQLAllocHandle(SQL_HANDLE_STMT, ConHandle, &StmtHandle);
每当分配一个语句句柄时,就会自动分配与语句句柄相关联的4个描述符句柄。
分配后,这些描述符句柄继续与相应的语句句柄相关联,直到它被销毁(那时,描述符句柄也随之被销毁)。
大多数CLI/ODBC操作都可以使用这些隐式定义的描述符句柄来执行。
但是,也可以通过调用SQLAllocHandle()函数并指定SQL_HANDLE_DESC选项和有效的连接句柄来显式地分配描述符句柄。
声明应用程序CLI/ODBC版本
CLI和ODBC使用特定于产品的驱动程序来与数据源(数据库)通信,大多数驱动程序都包含一组动态参数,通过修改这些参数,可以更改驱动程序的行为,以满足应用程序的需求。
这些参数被成为属性,每个环境句柄、连接句柄和语句句柄都有其自己的一组属性。
(后面有一个小节描述用于获取和更改与环境句柄、连接句柄或语句句柄相关联的属性。
)环境属性的一个例子是SQL_ATTR_ODBC_VERSION属性,在分配环境句柄之后,分配任何相应的连接句柄之前,必须为该属性赋予SQL_OV_ODBC3或SQL_OV_ODBC2值。
这告诉DB2CLI和ODBCDriverManager,应用程序打算遵从CLI/ODBC3.x规范或CLI/ODBC2.0(或更早版本)规范。
用于告诉DB2CLI或ODBCDriverManager应用程序打算遵从CLI/ODBC3.x(或更高版本)规范的代码如下所示:
...
SQLSetEnvAttr(EnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3,
SQL_IS_UINTEGER);
让DB2CLI和ODBCDriverManager知道应用程序遵从何种规范很重要,因为CLI/ODBC函数返回的很多返回码(或者被称为SQLSTATE,SQLSTATEs中会详细谈到)的值会因版本的不同而不同。
此外,DB2CLI和ODBC的较高版本允许在某些函数参数中使用通配符,而较早版本则不允许。
建立数据源(数据库)连接
要对数据库执行任何类型的操作,必须首先建立到数据库的连接。
对于CLI/ODBC应用程序,有3个函数可用于建立数据源(数据库)连接:
SQLConnect()
SQLDriverConnect()
SQLBrowseConnect()
应用程序可以使用这3个函数的任意组合连接到任意数目的数据源,但是某些数据源可能会限制所支持的活动连接的数量。
(应用程序可以通过调用SQLGetInfo()函数并指定SQL_MAX_DRIVER_CONNECTIONS信息类型来发现一个数据源支持多少活动连接。
SQLConnect()函数目前是最简单的CLI/ODBC连接函数。
当使用SQLConnect()函数时,它假设建立连接所需的惟一信息就是一个数据源名称,可能还有一个用户ID(授权ID)和密码。
(其他必要的信息存储在db2cli.ini文件的[COMMON]部分、ODBC.INI文件的[ODBC]部分或系统注册表中的ODBC子键中。
)该函数非常适用于只需要用户ID和口令来连接数据源的应用程序,以及需要提供其自己的连接界面或根本无需用户界面的应用程序。
而SQLDriverConnect()函数则允许应用程序使用一个连接字符串将连接信息发送到一个数据源驱动程序(而不是将该信息存储在db2cli.ini文件、ODBC.INI文件或系统注册表中,然后允许驱动程序来检索)。
连接字符串是一系列的键/值对,之间以分号隔开,其中包含建立到数据源连接时所需的信息。
表1列出了一些较常用的键/值对。
表1.和SQLDriverConnect()一起使用的键/值对
键/值
用途
DRIVER=DriverName
指定建立到数据库的连接所需使用的CLI/ODBC驱动程序的名称
DBALIAS=DatabaseAlias
指定要与之建立连接的数据库的别名
DSN=DataSourceName
指定要与之建立连接的数据源的名称(与SQLDataSources()函数返回的值一致)
UID=UserID
指定尝试建立连接的用户的用户ID(授权ID)
PWD=Password
指定所指定用户ID(授权ID)对应的密码。
如果所指定的ID不需要密码,则应该使用一个空的密码字符串(PWD=;)
NEWPWD=NewPassword
指定为所指定用户ID(授权ID)分配的新密码。
如果使用了NEWPWD但是没有提供新密码(NEWPWD=;),则DB2CLI驱动程序提示用户提供一个新密码
因此,若要使用SQLDriverConnect()函数建立到一个已编目的、名为PAYROLL的、使用授权IDdb2admin和密码ibmdb2的数据库的连接,可以使用如下代码:
...
char ConnectStr[512];
...
sprintf(ConString, "driver={IBM DB2 ODBC DRIVER};dbalias=payroll;
uid=db2admin;pwd=ibmdb2");
SQLDriverConnect(ConHandle, NULL, (SQLCHAR *) ConnectStr, SQL_NTS,
NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
...
您可能注意到,有一个名为SQL_NTS的特殊代码被作为SQLDriverConnect()函数的一个参数值。
接受字符串值作为参数的CLI/ODBC函数通常要求同时提供字符串的长度。
可以使用SQL_NTS值代替实际长度值,表明相应的字符串是以null终止的。
当被调用时,SQLDriverConnect()函数使用指定的数据源名称解析连接字符串,并尝试从系统中获取附加的信息,以建立连接。
然后,该函数使用这些信息登录到适当的服务器上,并尝试连接到指定的数据源。
使用SQLDriverConnect()函数的应用程序还可以让驱动程序提示用户提供所需的连接信息。
例如,当用一个空连接字符串调用SQLDriverConnect()函数时,DB2CLI显示一个对话框,提示用户:
从DB2CLI认识的数据源列表中选择一个数据源。
提供一个用户ID和相应的密码。
指定连接模式是独占的还是共享的。
是否显示该对话框由传递给SQLDriverConnect()函数的一个参数值控制:
如果调用该函数时指定了SQL_DRIVER_PROMPT、SQL_DRIVER_COMPLETE或SQL_DRIVER_COMPLETE_REQUIRED选项,那么,如果提供的连接字符串没有包括足够的信息来建立数据源连接,则显示该对话框。
但如果指定了SQL_DRIVER_NOPROMPT选项,但是没有提供足够的信息,那么就会返回错误。
和SQLDriverConnect()函数一样,SQLBrowseConnect()函数使用一个连接字符串将连接信息发送给驱动程序。
SQLDriverConnect()函数在编译时需要一个有效的连接字符串,而SQLBrowseConnect()函数可用于在应用程序运行时构造一个连接。
这点差异使应用程序可以使用它自己的对话框提示用户提供连接信息,从而保留对其外观的控制。
事务处理
CLI/ODBC应用程序执行完适当的初始化之后,焦点就转移到事务处理上来。
在此期间,通过不同的CLI/ODBC函数调用,将查询和操纵数据的SQL语句传递到适当的数据源(在这里通常是DB2数据库)进行处理。
在事务处理期间,CLI/ODBC应用程序依次执行以下五个步骤:
分配一个或多个语句句柄。
准备和执行一个或多个语句。
检索和处理产生的结果。
通过提交或回滚终止当前事务。
释放分配的所有语句句柄。
图2显示了事务处理期间执行的基本步骤,并给出了常用于执行每个步骤的CLI/ODBC函数调用:
图2.在CLI/ODBC应用程序中处理事务
分配语句句柄
正如前面提到的,语句句柄引用一个数据对象,该对象包含单个SQL语句的有关信息。
这些信息包括:
SQL语句的文本
关于与语句相关联的游标的详细信息
所有SQL语句参数标记变量的绑定
所有结果数据集列变量的绑定
语句执行的返回码
状态信息
SQL语句句柄是通过调用SQLAllocHandle()函数并指定SQL_HANDLE_STMT选项和一个有效的连接句柄来分配的。
在CLI/ODBC应用程序执行任何SQL语句之前,必须至少分配一个语句句柄。
准备和执行SQL语句
分配好语句句柄后,就可以将一个SQL语句赋给它,处理SQL语句的方式有两种:
准备和执行:
这种方法将SQL语句的准备与执行分开,通常用于需要重复执行语句的情况。
如果应用程序需要预知存在于执行SQL语句所产生的结果数据集中列的有关信息,也使用该方法。
这种方式使用CLI/ODBC函数SQLPrepare()和SQLExecute()来处理SQL语句。
立即执行:
该方法将SQL语句的准备和执行合并为一个步骤,通常用于语句只执行一次的情况。
如果应用程序不需要关于SQL语句执行时所产生的结果数据集的附加信息,那么也可以使用该方法。
这种方式使用CLI/ODBC函数SQLExecDirect()来处理SQL语句。
这两种方法都允许使用参数标记代替被处理的SQL语句中的常量和表达式。
参数标记用问号(?
)表示,用来指示当执行SQL语句时将在SQL语句中的何处替换一个或多个应用程序变量的当前值。
当一个应用程序变量与SQL语句中一个参数标记关联时,就称该变量被“绑定”到该参数标记。
这种绑定是通过调用SQLBindParameter()函数完成的,应用程序变量被绑定到参数标记之后,参数标记与该变量的关联就一直有效,直到它被重载或者相应的语句句柄被释放。
虽然在SQL语句准备好之后可以随时进行绑定,但是只有到SQL语句执行的时候,才能真正从绑定变量中检索数据。
清单1展示了在一个用C语言编写的CLI/ODBC应用程序中,如何将应用程序变量绑定到简单的SELECTSQL语句中的参数标记。
它还展示了在语句执行之前,将值以何种方式提供给绑定参数。
清单1.绑定参数标记
...
// Define A SELECT SQL Statement That Uses A Parameter Marker
strcpy((char *) SQLStmt, "SELECT empno, lastname FROM ");
strcat((char *) SQLStmt, "employee WHERE JOB = ?
");
// Prepare The SQL Statement
RetCode = SQLPrepare(StmtHandle, SQLStmt, SQL_NTS);
// Bind The Parameter Marker Used In The SQL Statement To
// An Application Variable
RetCode = SQLBindParameter(StmtHandle, 1,
SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
sizeof(JobType), 0, JobType,
sizeof(JobType), NULL);
// Populate The "Bound" Application Variable
strcpy((char *) JobType, "DESIGNER");
// Execute The SQL Statement
RetCode = SQLExecute(StmtHandle);
...
检索和处理结果
在准备并执行了SQL语句之后,需要检索和处理该语句所产生的结果。
如果SQL语句是SELECT或VALUES以外的语句,那么在该语句执行之后,惟一需要做的是检查CLI/ODBC函数返回码,以确认该语句是否按预期执行。
但是,如果执行的SQL语句是一个查询,那么可能还需要进行相应的处理来从产生的结果数据集中检索数据。
当查询返回多个行时,这些行被存储在与执行的SQL语句相关联的连接句柄和语句句柄所
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DB2数据库 CLI应用开发 DB2 数据库 CLI 应用 开发