作者:super_bert@csdn
基于C语言的DB2数据库开发
本文探讨了C语言环境下DB2数据库系统的开发过程,着重分析了DB2的开发关键过程及不同于其他数据库的特别之处,并提供了解决关键性问题的程序示例。
引言
IBM公司的DB2数据库作为当前三大主流数据库之一,在数据库系统开发中占优很大的市场份额,特别是金融行业中,因往往使用IBM自身的AIX系统以及AS400/RS600等服务器,有关的应用系统开发更是越来越偏重于采用DB2数据库。然而,在开发过程中,由于DB2内部的机制及编程方面的限制,使刚开始从事DB2数据库开发或从其他数据库移植到DB2的开发人员感到迷惑重重,难以从其他数据库的开发习惯中适应过来。另外市面上不像ORACLE/SQL SERVER那样有成排的资料书籍,DB2除了IBM自己提供的英文资料外,对开发有参考价值的技术资料相对很少。因此笔者结合自己最近开发的几套DB2应用系统,着重从基于C语言环境下的DB2开发过程做一探讨,并针对和其他数据库开发的不同之处,以及部分关键性问题的解决作详细分析和应用示例。
1.DB2应用程序开发概述
在进行DB2应用开发之前,了解DB2应用程序的结构,掌握相关概念是很必要的。
1.1嵌入式SQL编程
嵌入式SQL应用程序就是将SQL语句嵌入某个宿主语言中,SQL语句提供数据库接口,存取并处理 DB2 数据库中的数据,宿主语言提供应用程序的其他执行功能。嵌入式SQL语句包括静态 SQL 语句和动态 SQL 语句。
1.2宿主语言
用于创建主程序的程序设计语言称为宿主语言,例如DB2可以用 C/C++、COBOL、FORTRAN、Java (SQLJ) 以及 REXX 程序设计语言来编写嵌入式SQL 应用程序,这些程序设计语言都称为宿主语言。
1.3静态 SQL 语句
在编译前就知道 SQL 语句内容以及以及将要存取的表名和列名。唯一未知的是语句正搜索或更新的特定数据值。可以用宿主语言变量表示那些值。在运行应用程序之前,要预编译、编译和捆绑静态 SQL 语句。
1.4动态 SQL 语句
是应用程序在运行期构建并执行的那些语句。一个提示最终用户输入 SQL 语句的关键部分(如要搜索的表和列的名称)的交互式应用程序是动态 SQL 一个很好的示例。 应用程序在运行时构建 SQL 语句,然后提交这些语句进行处理。
可以编写只有静态 SQL 语句或只有动态 SQL 语句,或者兼有两者的应用程序。
1.5宿主变量(Hostvariables)
在主应用程序中由嵌入式SQL语句引用的变量。宿主变量是该应用程序中的程序设计变量,并且是在数据库中的表与应用程序工作区之间传送数据的主要机制。我们称之为“宿主变量”,是为了与通常方法声明的源语言变量区分开来,通常方法声明的变量不能被SQL语句引用。宿主变量在宿主语言程序模块中以一种特殊的方式声明:必须在BEGIN DECLARE SECTION和END DECLARE SECTION程序节内定义。
2.静态SQL程序开发
2.1静态SQL例程
在程序结构上,DB2和其他数据库非常相似,下面先来看一个静态SQL程序的C语言例子static.sqc:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL INCLUDE SQLCA; /*包含结构SQLCA, 以便获取SQL执行信息*/
#define CHECKERR(CE_STR) if (sqlca.sqlcode != 0)\
{printf("%s. sqlcode = [%s]\n", CE_STR, sqlca.sqlcode); return 1;}
int main(int argc, char *argv[])
{
EXEC SQL BEGIN DECLARE SECTION;
char firstname[12 + 1];
char userid[8 + 1];
char passwd[18 + 1];
EXEC SQL END DECLARE SECTION;
printf("Sample C program: STATIC\n");
if (1 == argc)
{
EXEC SQL CONNECT TO sample;
CHECKERR ("CONNECT TO SAMPLE");
}
else if (3 == argc)
{
strcpy(userid, argv[1]);
strcpy(passwd, argv[2]);
EXEC SQL CONNECT TO sample USER :userid USING :passwd;
CHECKERR ("CONNECT TO SAMPLE");
}
else
{
printf("\nUSAGE: static [userid passwd]\n\n");
return 1;
}
EXEC SQL SELECT FIRSTNME INTO :firstname
FROM employee
WHERE LASTNAME = 'BERT' and ;
CHECKERR ("SELECT statment");
printf("First name = %s\n", firstname);
EXEC SQL CONNECT RESET;
CHECKERR(CONNECT RESET);
return 0;
}
例程1-静态SQL例程
2.2静态SQL程序的结构和特点
从上面的例程可以看到,典型的静态SQL程序结构包含以下关键部分:
1)包括结构SQLCA: INCLUDESQLCA语句定义和声明了SQLCA结构,SQLCA结构中定义了SQLCODE和SQLSTATE域。数据库管理器在执行完每一条SQL语句或者每一个数据库管理器API调用,都要更新SQLCA结构中的SQLCODE域的诊断信息。
2)声明宿主变量:SQL BEGIN DECLARE SECTION和END DECLARE SECTION 语句界定宿主变量的声明。宿主变量用来将数据传递给数据库管理或者接收数据库管理器返回的数据。在SQL语句中引用宿主变量时,必须在宿主变量前加前缀冒号(:)。详细信息看2.4节。
3)连接到数据库:应用程序必须先连接到数据库,才能对数据库进行操作。这个程序连接到SAMPLE数据库,请求以共享方式访问。其他应用程序也可以同时以共享访问方式连接数据库
4)输入宿主变量赋值:在SQL语句执行之前,如果要引用宿主变量作为条件或插入值(称之为输入宿主变量),则要求先进行赋值。
5)提取或处理数据。SELECT INTO语句基于一个查询提取了一行值。这个例子从EMPLOYEE表中,将LASTNAME列的值为JOHNSON的相应行的FISRTNME列的值提取出来,置于宿主变量firstname中。
6)处理错误:CHECKERR 宏/函数是一个执行错误检查的外部函数,判断前面的SQL语句是否执行成功。
7)程序运行结束,断开数据库连接。
2.3DB2预编译及绑定
为了使用包含嵌入式 SQL 的程序,不仅要进行典型的准备步骤(编译、链接和运行),还必须执行 DB2预编译和绑定步骤。这些步骤将为数据库管理器创建执行时需要的程序包其编译过程如(图一)所示:
图1-预编译过程
2.3.1预编译
将嵌入式 SQL 源语句转换为数据库管理器可使用的形式。以例程1为例,预编译命令如下:
DB2 PREP static.sqc [PACKAGE[USING mypack]] [BINDFILE [USING mytest.bnd]]
其中PACKAGE、BINDFILE为可选项,当PACKAGE选项(默认的),或者没有指定任何BINDFILE、SYNTAX、SQLFALG选项,预编译后自动在数据库中生成以文件名前8位命名的程序包,USING mypack 指定生成的程序包名为mypack;BINDFILE在预编译时同时产生文件名前8位.bnd,USING mytest.bnd指定生成的绑定文件名为mytest.bnd文件(详细命令请参考IBM提供的《IBM DB2Universal Database Command Refe