摘要:本文深入浅出地阐述了C语言连接和处理Oracle数据库系统的Pro*C程序,结合作者实践经验,举例说明如何编写、编译和运行Pro*C程序。
关键词:Oracle数据库;Pro*C程序;嵌入式SQL
中图分类号:TP311.13 文献标识码:A文章编号:1009-3044(2007)15-30622-02
Briefly Bewrite the Pro*C Program in the Oracle Database
YU Qiu-ming
(Jiangxi University of Science and Technology, Nanchang 330013, China)
Abstract:This article elaboratedthe Pro*Cprogramabout the C language conjunction and process Oracle database system.Combining author’s practices experience, illustrating with example how to edit, compile and run thePro *C program
Key words:Oracle database;Pro*C program;embedded SQL
1 引言
Oracle关系型数据库管理系统是数据库厂商Oracle(甲骨文)推出的当今世界上最流行的数据库,又是一个极其强大、灵活和复杂的系统.
C语言是国际上广泛流行的计算机高级语言,既可以用来写系统软件,也可以用来写应用软件。现已成为世界上应用最为广泛的几种计算机语言之一。
鉴于当前介绍Pro*C程序少之又少而单独介绍Oracle数据库或C语言的书籍非常多,本文将结合作者C语言的Oracle编程实践经验,简要剖析Pro*C程序的特点及如何编写Pro*C程序。
2 Pro*C程序
2.1 什么是Pro*C程序
在Oracle数据库管理和系统中, Pro*C程序把过程化语言C和非过程化语言SQL最完善地结合起来, 具有完备的过程处理能力,又能完成任何数据库的处理品任务,使用户可以通过编程完成各种类型的报表。在Pro*C程序中可以嵌入SQL语言, 利用这些SQL语言可以完成动态地建立、修改和删除数据库中的表,也可以查询、插入、修改和删除数据库表中的行, 还可以实现事务的提交和回滚。在Pro*C程序中还可以嵌入PL/SQL块(Oracle公司在标准SQL语言的基础上发展起来专用于Oracle数据库程序设计的语言), 以改进应用程序的性能。
2.2 Pro*C程序剖析
Pro*C程序的组成结构
每一个Pro*C程序都包括两部分:(1)应用程序首部;(2)应用程序体
应用程序首部定义了Oracle数据库的有关变量,为在C语言中操纵Oracle数据做好了准备。应用程序体基本上由Pro*C的SQL语句调用组成。主要指查询SELECT、INSERT、UPDATE、DELETE等语句。
2.2.1 应用程序首部
应用程序的首部就是Pro*C的开始部分。它包括以下三部分:
C变量描述部分;
SQL变量描述部分(DECLARE部分);
SQL通信区。
描述部分说明程序的SQL变量及C变量, 定义部分以EXEC SQL BEGIN DECLARE SECTION 开始和以 EXEC SQL END DECLARE SECTION 结束。
例如:
EXEC SQL BEGIN DECLARE SECTION;
char*uid=“scott/tiger”; /*C语言变量描述,字符指针uid*/
SQL_CURSOR generic_cv:/*游标变量,属于SQL变量描述*/
inttable_num;/*C语言变量描述,整型变量定义*/
EXEC SQL END DECLARE SECTION;
SQL通信区是用下列语句描述的:
EXEC SQL INCLUDE SQLCA;
此部分提供了用户运行程序的成败记录和错误处理.
SQLCA的组成
SQLCA是一个结构类型的变量,它是Oracle和应用程序的一个接口。在执行 Pro*C程序时, Oracle 把每一个嵌入SQL语句执行的状态信息存入SQLCA中, 根据这些信息,可判断SQL语句的执行是否成功,处理的行数,错误信息等,其组成如表所示:
Struct sqlca
{char sqlcaid [ 8 ] ; ----标识通讯区
long sqlabc; ---通讯区的长度
long sqlcode; ---保留最近执行的SQL语句的状态码
struct{unsigned short sqlerrml; -----信息文本长度
} sqlerrm;
char sqlerrp[8];
long sqlerrd[6];
char sqlwarn[8];
char sqlext[8]; }
struct sqlca sqlca;
其中, sqlcode在程序中最常用到,它保留了最近执行的SQL语句的状态码。程序员根据这些状态码做出相应的处理。这些状态码值如下:
0: 表示该SQL语句被正确执行,没有发生错误和例外。
>0:ORACLE执行了该语句,但遇到一个例外(如没找到任何数据)。
<0:表示由于数据库、系统、网络或应用程序的错误,ORACLE未执行该SQL语句。
当出现此类错误时,当前事务一般应回滚。
2.2.2 应用程序体
在Pro*C程序中, 可以把SQL语句和C语句自由地混合书写,并能在SQL语句中使用SQL变量,嵌入式SQL语句的书写语法是:
以关键字EXEC SQL开始, 以C语言的语句终结符(分号)终结
SQL语句的作用主要用于同数据库打交道。C语言程序用于控制,输入,输出和数据处理等。在Pro*C程序中常用的内嵌的SQL语句有:
连接到Oracle数据库,语法如下:
EXEC SQL CONNECT:< 用户名 > IDENTIFIED BY : < 口令 >
或EXEC SQL CONNECT: < 用户名 > / < 口令 >
在使用上述两种格式进行登入时, 应当首先在说明段定义包含用户名和口令的 SQL 变量,并在执行CONNECT之前设置它们,否则会造成登录失败。不能把用户名和口令直接编写到CONNECT语句中,或者把用引号(’)括起来的字母串在CONNECT 语句中, 如下面的语句是无效的。
EXEC SQL CONNECT SCOTT INENTIFIED BY TIGER;
EXEC SQL CONNECT ‘SCOTT’ IDENTIFIED BY ‘TIGER‘;
SQL插入、更新和删除
SQL数据库查询及游标的使用
PL/SQL程序块
以上三种在Oracle或其他数据库SQL中有详细介绍,在此不再说明。
2.3 Pro*C程序的编写
下面我们举一个例子说明如何编写Pro*C程序,该程序提示用户选择数据库,打开游标变量,提取查询返回行。
/*声明Pro*C应用程序首部*/
char temp[32];
EXEC SQL BEGIN DECLARE SECTION;
char *uid="scott/tiger";/*用户名和密码事先存放于某个变量中*/
SQL_CURSOR generic_cv;/*游标变量*/
int table_num;
用C语言定义一个结构体变量emp_rec 用来存储scott方案下EMP数据表中数据
用C语言定义一个结构体变量dept_rec用来存储scott方案下DEPT数据表中数据
用C语言定义一个结构体变量bonus_rec用来存储scott方案下BONUS数据表中数据
EXEC SQL END DECLARE SECTION;/*到此结束Pro*C应用程序首部,*/
/*Pro*C应用程序体部分*/
EXEC SQL WHENEVER SQLERROR DO sql_error();/*处理Oracle错误*/
EXEC SQL CONNECT:uid;/*连接Oracle*/
EXEC SQL ALLOCATE:generic_cv /*初始化游标变量*/
EXEC SQL WHENEVER NOT FOUND DO break; /*当取完后退出*/
for(;;)
{printf("\n 1=EMP, 2=DEPT, 3=BONUS");
printf("\n Enter table number(0 to quit):");
gets(temp);
table_num=atoi(temp);
if(table_num<=0) break;
EXEC SQL EXECUTE/*打开游标变量*/
BEGIN
IF :table_num=1 THEN
OPEN :generic_cv FOR SELECT * FROM emp;
ELSIF:table_num=2 THEN
OPEN :generic_cv FOR SELECT * FROM dept;
ELSIF:table_num=3 THEN
OPEN :generic_cv FOR SELECT * FROM bonus;
END IF;
END;
END-EXEC;
for(;;) /*有选择地提取游标中数据到C语言结构体变量中*/
{switch(table_num)
{case 1: EXEC SQL FETCH:generic_cv INTO :emp_rec; break;
case 2: EXEC SQL FETCH:generic_cv INTO :dept_rec;break;
case 3: EXEC SQL FETCH:generic_cv INTO :bonus_rec;break;} }
EXEC SQL CLOSE :generic_cv;/*关闭游标*/
exit(0);
void sql_error()
{/*处理SQL错误* / }
2.4 Pro*C程序的编译和运行
Pro*C程序的编译和运行按照如下步骤进行:
(1)先用Oracle Pro*C/C++预编译器对编制好的Pro*C程序进行预处理,该编译器将源程序中嵌入的SQL语言翻译成C语言,产生一个能被C语言编译器直接编译的文件。生成文件的扩展名为.c;
(2)用C语言编译器对经Oracle预编译器预处理为扩展名为.c的文件编译,产生目标代码文件,其扩展名.obj;
(3)使用MAKE命令,连接目标代码文件以及数据库,生成C语言可运行文件。
为了加深理解,我们以图1来说明。
图1
3 结束语
本文通过分析Pro*C的程序体系结构,我们发现与纯粹的C语言程序比较在数据说明方面多一些SQL变量的声明,在程序体处理方面多了一些嵌入的SQL语句,如连接,查询,数据操纵等,如此,C语言可以像处理自定义的普通数据变量一样来处理大型数据库Oracle内的数据。
参考文献:
[1]谭浩强.C语言程序设计[M].北京:北京大学出版社,2000,6.
[2]赵松涛.Oracle9i中文版入门与提高[M].北京:人民邮电出版社,2002,7.
[3]飞思科技产品研发中心.Oracle基础与提高[M].北京:电子工业出版社,2003.
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。