VC下利用Pro*C开发Oracle接口


摘要 本文介绍了使用Pro*C/C++在Visual C++环境下开发Oracle数据库接口程序的方法。

关键词 程序设计,数据库接口程序,Oracle

概述

在Visual C++下开发Oracle库接口主要有两种方法。一种方法是利用Visual C++提供的多种数据库访问技术,如开放数据库连接ODBC、数据存取对象DAO、对象连接和嵌入数据库OLE DB和ActiveX数据对象ADO等。另一种方法是在Visual C++中嵌入SQL语句,这就是所指的Pro*C/C++(本文简称PROC)。前一种方法由于有MFC 强大的类库支持,熟悉VC编程时则实现方便,且可移植性强;但是,与PROC 相比,应用程序需要经过两层才能和数据库通信接口建立联系,编程相对复杂,执行效率相对较低。PROC支持嵌入式PL/SQL 块等直接调用Oracle 库,将过程化语言和非过程化语言相结合,形成一种更强的开发工具,可开发出满足各种复杂要求的优化应用程序,执行效率高。适合熟悉Oracle技术的人员应用。但是用PROC 开发出的应用程序无法向异构数据库平台移植。

本文详细描述实际利用PROC在Visual C++环境下开发Oracle数据库接口程序的方法和具体操作步骤,并给出了编程实例。叙述以Visual C++ 6.0版和Oracle8i版为例,其他版本可根据实际情况变更。

几个特殊文件

PROC在VC下开发Oracle库接口时,需要用到几个特殊文件。

1、PROC的可执行文件PROCUI. EXE

用Oracle_HOME代表Oracle安装后的根目录,当其以缺省方式安装在计算机的D盘时,则Oracle_HOME位置是D: \ Oracle。这时PROC的可执行文件在Oracle_HOME \ Ora81 \ BIN \ PROCUI. EXE,对缺省安装即在D: \ Oracle \ Ora81 \ BIN \ PROCUI. EXE。

2、Oracle支持SQL在VC环境的库文件OraSQL8. LIB

根据以上约定,OraSQL8. LIB文件在Oracle_HOME \ Ora81 \ PRECOMP \ LIB \ MSVC \ OraSQL8.LIB,对缺省安装即在D: \ Oracle \ Ora81 \ PRECOMP \ LIB \ MSVC \ OraSQL8.LIB。

3、Oracle支持SQL在VC环境的头文件

根据以上约定,头文件 *.h在Oracle_HOME \ Ora81 \ PRECOMP \ PUBLIC \ *.h,对缺省安装即在D: \ Oracle \ Ora81 \ PRECOMP \ PUBLIC \ *.h。

*.h 是头文件的总称,通常有十多个,具体内容可在指定路径下查到。

将PROC集成到VC环境中

为了方便完成用PROC在VC下开发Oracle库接口,通常将PROC集成到Visual C++ 6.0 环境中,直接在C / C++环境中使用PROC预编译器来预编译应用程序,然后进行编译和链接,最终生成可执行程序。将PROC集成到VC环境中应完成如下工作。

1、增加PROC到Tools菜单列表

a) 运行Microsoft Visual C++ 6.0;

b) 从菜单项Tools中选择Customize项。为表述简单起见,书写成如下格式:菜单Tools/ Customize 项。以下采用类似的表达方法。此时出现Customize对话框;

c) 单击Tools选项卡(或属性页),用鼠标移动“Menu contents”框滚动条到底部区域;

d) 双击点划线矩形区域,在空白区域上输入“PROC”,然后按回车键;

e) 在“Command”框中,输入PROC的可执行文件名。根据2.1节的说明,对缺省安装即输入D: \ Oracle \ Ora81 \ BIN \ PROCUI. EXE;

f) 在“Arguments”框中输入“$(TargetName)”。其作用在从菜单Tools中选择PROC项时,VC会将当前项目名传递给PROC,尔后PROC会直接打开该项目文件目录下扩展名为 .pre的同名文件;

g) 在“Initial directory”框中输入“$(WkspDir)” / 单击“Close”按钮,完成将PROC集成到VC环境中的工作。

2、指定头文件路径

为了确保VC顺利完成编译链接,需要将Oracle提供的头文件增加到VC环境中。指定头文件路径的具体步骤如下。

a) 菜单Tools / Options项,出现“Options”对话框;

b) 单击“Directories”选项卡,从“Show directories for:”列表框中选择“Include files”;

c) 移动“Directories”框的滚动条到底部区域;

d) 双击点划线矩形区域,在空白区域上输入包含Oracle支持SQL在VC环境头文件的子目录,根据2.3节的说明,对缺省安装即输入D: \ Oracle \ Ora81 \ PRECOMP \ PUBLIC。

VC下开发Oracle接口程序过程

1、创建新工程

下面叙述中,假定新建的工程名为:Exam01。当运行Visual C++ 6.0后,操作步骤如下:

a) 菜单File / New项 / Project卡;

b) 选择Win32 console Application 项;

c) 由浏览选择或直接输入工程将位于的路径 / 填入创建的工程名如Exam01;

d) 单击OK按钮 / 依缺省值单击Finish / 单击OK,完成创建控制台应用工程框架。

2、创建预编译源文件

假定创建的预编译源文件名为:Exam01.pc。在Visual C++ 6.0的环境下操作步骤如下:

a) 菜单Project / Add To Project 项 / New项;

b) Files 卡 / SQL script File 项;

c) Files编辑框中输入Exam01.pc / 单击OK;

d) 在编辑状态下输入Exam01.pc源文件,或者,从其他文件中拷贝后再修改形成Exam01. pc源文件;

e) 选择恰当路径,保存源文件。例如,路径为:E: \ PROCW \ Exam01。

3、预编译

通过预编译,将预编译源文件如Exam01.pc转换成为Exam01.c的C程序源文件。在PROC集成到VC环境下时操作步骤如下:

a) 菜单Tools / PROC 项;

b) 当出现没有Exam01.pre 的对话框时单击OK,此时弹出PROC预编译对话框;

c) 利用菜单中的加入项或单击“+”按钮,将进行预编译的源文件如Exam01.pc及其路径添加到预编译对话框的Input项中,即Input项中出现E: \ PROCW \ Exam01 \ Exam01.pc。此时在Output项中自动显示输出文件如Exam01.c和路径(必要时可修改文件名和路径),即Output项中出现E: \ PROCW \ Exam01 \ Exam01.c;

d) 若有需要,双击预编译对话框的Options选项处,对弹出的Options选项对话框,选择需要的预编译选项(一般情况下不做该步,即采用缺省预编译选项);

e) 单击工具条最右边的预编译图标,进行预编译;

f) 预编译结束,若出现询问保存Exam01.pre 文件时,应选择OK进行保存,完成预编译;

g) 如果预编译结束,预编译对话框左边显示的状态图标为黄色(警告)或红色(预编译失败)时,应双击该标识观察帮助或出错信息。预编译失败,应当重做4.2节中编辑工作,修改源程序,再进行预编译,直到通过预编译。

4、编译准备

为了使工程能通过编译,需要将预编译输出的工程源文件和Oracle支持SQL在VC环境下的运行库文件加入到工程中,下面具体介绍增加这两个文件的步骤。

  1. 将预编译的输出文件加入工程

a) 菜单Project / Add To Project 项 / Files 项;

b) 在文件对话框中选择正确路径(见4.2节和4.3节),选定预编译输出的文件如Exam01.c,单击“打开”按钮,即将预编译输出的工程源文件加入工程。

  1. 将运行库文件加入工程

a) 菜单Project / Add To Project 项 / Files 项;

b) 将文件对话框的文件类型改为“所有文件”;

c) 路径选为Oracle_HOME \ Ora81 \ PRECOMP \ LIB \ MSVC;

d) 选择OraSQL8.LIB文件,单击“打开”钮,完成将运行库文件加入工程。

5、编译链接

a) 按F7键或单击编译图标,对工程进行编译链接。如果没有出现错误,则通过编译链接,生成可执行文件如Exam01.exe ;

b) 如果编译链接出现错误,返回到4.2节,选择相应的预编译源文件如Exam01.pc进行修改并保存;然后按4.3节做预编译,预编译通过后,单击OK按钮用新的 .c文件代替原来的C源文件;此时重新按F7键进行编译链接,直到排除所有错误,生成可执行文件如Exam01.exe。

6、运行工程

a) 按Ctrl_F5键或单击执行图标运行工程Exam01.exe。按工程中的提示,逐步正确运行;

b) 如果运行中出现错误,返回到4.2节修改相应预编译源文件,再按4.3节做预编译,按4.5节进行编译链接,生成新的可执行文件,然后重新运行工程,直到正确实现工程的规定任务。

编程举例

1、程序内容

一般SQL嵌入式程序主要有说明、包含头文件、子程序声明、主程序和子程序等部分组成,在主程序中调用有关子程序。必备的子程序通常有连接到数据库子程序、断开数据库子程序、错误处理子程序和完成某项具体事务(如查询、插入、修改、删除等)的工作子程序。

2、程序举例

下面是一完整的可通过预编译、编译链接和运行的示例程序。

/* exam01.pc 开发Oracle接口程序举例 /
/
说明:本程序介绍用PROC开发Oracle库接口的编程特点。通过向AUTHS

  • 表输入作家代码,查询作家姓名及工资。运行前应建表、插入数据并提交。*/
    #include
  1<stdio.h>   
  2#include <string.h>   
  3#include <stdlib.h>   
  4/* 包含SQL通讯区,它用于处理错误。*/   
  5#include <sqlca.h>   
  6void connect(); /* 连接到Oracle Server */   
  7void disconnect(); /* 断开到Oracle Server的连接 */   
  8void sql_error(char *); /* 处理错误句柄 */   
  9void select(); /* 查询子程序 */   
 10extern sqlglm(char *,int *,int *);   
 11/* 主程序 */   
 12void main()   
 13{   
 14/* 安装错误处理句柄 */   
 15EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle错误--\n");   
 16/* 连接到数据库 */   
 17connect();   
 18/* 执行查询 */   
 19select();   
 20/* 断开数据库连接 */   
 21disconnect();   
 22}   
 23/* 子程序 */   
 24/* 连接子程序 connect() */   
 25void connect()   
 26{   
 27EXEC SQL BEGIN DECLARE SECTION;   
 28VARCHAR username[10], password[10], server[10];   
 29EXEC SQL END DECLARE SECTION;   
 30/* 输入用户名、口令以及服务器名 */   
 31printf("\n输入用户名:");   
 32gets(username.arr);   
 33username.len=(unsigned short)strlen((char *)username.arr);   
 34printf("\n输入口令:");   
 35gets(password.arr);   
 36password.len=(unsigned short)strlen((char *)password.arr);   
 37printf("\n输入服务器名:");   
 38gets(server.arr);   
 39server.len=(unsigned short)strlen((char *)server.arr);   
 40/* 连接到Oracle服务器上 */   
 41EXEC SQL CONNECT :username IDENTIFIED BY :password USING :server;   
 42printf("\n以用户%s成功地连接到了服务器%s上!\n", username.arr, server.arr);   
 43}   
 44/* 断开连接子程序 disconnect() */   
 45void disconnect()   
 46{   
 47char temp;   
 48printf("\n是否在断开连接前提交所有事务? (Y/N)");   
 49scanf("%c", &amp;temp);   
 50fflush(stdin);   
 51if(temp !='Y' &amp;&amp; temp != 'y')   
 52{   
 53/* 回退事务,断开连接。 */   
 54EXEC SQL ROLLBACK WORK RELEASE;   
 55printf("\n回退事务,断开连接,退出程序!\n\n");   
 56}   
 57else   
 58{   
 59/* 提交事务,断开连接。 */   
 60EXEC SQL COMMIT WORK RELEASE;   
 61printf("\n提交事务,断开连接,退出程序!\n\n");   
 62exit(1);   
 63}   
 64}   
 65/* 查询子程序 select()   
 66* 首先输入作家代码,然后查询作家姓名和工资。*/   
 67void select()   
 68{   
 69EXEC SQL BEGIN DECLARE SECTION;   
 70char author_code[8], name[10];   
 71float salary;   
 72short salary_ind;   
 73EXEC SQL END DECLARE SECTION;   
 74printf("\n输入作家代码: ");   
 75gets(author_code);   
 76/* 查询作家姓名和工资 */   
 77EXEC SQL SELECT name, salary INTO :name, :salary:salary_ind   
 78FROM auths   
 79WHERE author_code = :author_code;   
 80/* 根据指示变量的值来确定该作家的工资是否为空。*/   
 81if (salary_ind ==0)   
 82{   
 83printf("\n作家代码\t作家姓名\t作家工资\n");   
 84printf("--------\t--------\t--------\n");   
 85printf("%8s\t%8s\t%8.2f\n", author_code, name, salary);   
 86}   
 87else   
 88{   
 89printf("作家%s的工资未录入,为空值!\n", name);   
 90}   
 91}   
 92/* 错误处理子程序 sql_error() */   
 93void sql_error(char *msg)   
 94{   
 95char err_msg[128];   
 96size_t buf_len, msg_len;   
 97/* 出现SQL错误,继续往下执行。 */   
 98EXEC SQL WHENEVER SQLERROR CONTINUE;   
 99printf("\n%s\n", msg);   
100buf_len=sizeof(err_msg);   
101/* 调用函数sqlglm()获得错误消息。 */   
102sqlglm(err_msg, &amp;buf_len, &amp;msg_len);   
103printf("%.*s\n", msg_len, err_msg);   
104/* 回退事务,断开连接,退出程序。 */   
105EXEC SQL ROLLBACK RELEASE;   
106exit(EXIT_FAILURE);   
107} 
108
1093、建表和插入数据记录 
110
111上述示例程序如要正确运行,还需以Oracle库的合法用户登录,并创建AUTHS表和插入一些数据记录。建表文件、建表命令和插入数据记录的示例命令如下所述。这里叙述的工作完成后,上节生成的可执行文件才能正确运行。 
112
113REM 以下为建表文件auths.SQL 
114
115DROP TABLE auths CASCADE CONSTRAINTS   
116/   
117CREATE TABLE auths(   
118AUTHOR_CODE VARCHAR2(8) NOT NULL,   
119NAME VARCHAR2(10),   
120BIRTHDATE DATE,   
121ENTRY_DATE_TIME DATE,   
122SALARY NUMBER(7,2),   
123remark VARCHAR2(255))   
124/   
125REM 下一行为在PL/SQL环境中运行建表文件的命令   
126REM @ E: \ PROCW \ Exam01 \ auths.sql   
127REM 下一行为在PL/SQL环境中向auths表插入数据的命令,插入后应提交(COMMIT)!   
128REM INSERT INTO auths(author_code,name,salary) VALUES('A00001','王达琳',1200);</sqlca.h></stdlib.h></string.h></stdio.h>
Published At
Categories with 数据库类
Tagged with
comments powered by Disqus