摘要 本文介绍了使用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++ 版和Oraclei版为例其他版本可根据实际情况变更
几个特殊文件
PROC在VC下开发Oracle库接口时需要用到几个特殊文件
PROC的可执行文件PROCUI EXE
用Oracle_HOME代表Oracle安装后的根目录当其以缺省方式安装在计算机的D盘时则Oracle_HOME位置是D: \ Oracle这时PROC的可执行文件在Oracle_HOME \ Ora \ BIN \ PROCUI EXE对缺省安装即在D: \ Oracle \ Ora \ BIN \ PROCUI EXE
Oracle支持SQL在VC环境的库文件OraSQL LIB
根据以上约定OraSQL LIB文件在Oracle_HOME \ Ora \ PRECOMP \ LIB \ MSVC \ OraSQLLIB对缺省安装即在D: \ Oracle \ Ora \ PRECOMP \ LIB \ MSVC \ OraSQLLIB
Oracle支持SQL在VC环境的头文件
根据以上约定头文件 *h在Oracle_HOME \ Ora \ PRECOMP \ PUBLIC \ *h对缺省安装即在D: \ Oracle \ Ora \ PRECOMP \ PUBLIC \ *h
*h 是头文件的总称通常有十多个具体内容可在指定路径下查到
将PROC集成到VC环境中
为了方便完成用PROC在VC下开发Oracle库接口通常将PROC集成到Visual C++ 环境中直接在C / C++环境中使用PROC预编译器来预编译应用程序然后进行编译和链接最终生成可执行程序将PROC集成到VC环境中应完成如下工作
增加PROC到Tools菜单列表
a) 运行Microsoft Visual C++
b) 从菜单项Tools中选择Customize项为表述简单起见书写成如下格式菜单Tools/ Customize 项以下采用类似的表达方法此时出现Customize对话框
c) 单击Tools选项卡(或属性页)用鼠标移动Menu contents框滚动条到底部区域
d) 双击点划线矩形区域在空白区域上输入PROC然后按回车键
e) 在Command框中输入PROC的可执行文件名根据节的说明对缺省安装即输入D: \ Oracle \ Ora \ BIN \ PROCUI EXE
f) 在Arguments框中输入$(TargetName)其作用在从菜单Tools中选择PROC项时VC会将当前项目名传递给PROC尔后PROC会直接打开该项目文件目录下扩展名为 pre的同名文件
g) 在Initial directory框中输入$(WkspDir) / 单击Close按钮完成将PROC集成到VC环境中的工作
指定头文件路径
为了确保VC顺利完成编译链接需要将Oracle提供的头文件增加到VC环境中指定头文件路径的具体步骤如下
a) 菜单Tools / Options项出现Options对话框
b) 单击Directories选项卡从Show directories for:列表框中选择Include files
c) 移动Directories框的滚动条到底部区域
d) 双击点划线矩形区域在空白区域上输入包含Oracle支持SQL在VC环境头文件的子目录根据节的说明对缺省安装即输入D: \ Oracle \ Ora \ PRECOMP \ PUBLIC
VC下开发Oracle接口程序过程
创建新工程
下面叙述中假定新建的工程名为Exam当运行Visual C++ 后操作步骤如下
a) 菜单File / New项 / Project卡
b) 选择Win console Application 项
c) 由浏览选择或直接输入工程将位于的路径 / 填入创建的工程名如Exam
d) 单击OK按钮 / 依缺省值单击Finish / 单击OK完成创建控制台应用工程框架
创建预编译源文件
假定创建的预编译源文件名为Exampc在Visual C++ 的环境下操作步骤如下
a) 菜单Project / Add To Project 项 / New项
b) Files 卡 / SQL script File 项
c) Files编辑框中输入Exampc / 单击OK
d) 在编辑状态下输入Exampc源文件或者从其他文件中拷贝后再修改形成Exam pc源文件
e) 选择恰当路径保存源文件例如路径为E: \ PROCW \ Exam
预编译
通过预编译将预编译源文件如Exampc转换成为Examc的C程序源文件在PROC集成到VC环境下时操作步骤如下
a) 菜单Tools / PROC 项
b) 当出现没有Exampre 的对话框时单击OK此时弹出PROC预编译对话框
c) 利用菜单中的加入项或单击+按钮将进行预编译的源文件如Exampc及其路径添加到预编译对话框的Input项中即Input项中出现E: \ PROCW \ Exam \ Exampc此时在Output项中自动显示输出文件如Examc和路径(必要时可修改文件名和路径)即Output项中出现E: \ PROCW \ Exam \ Examc
d) 若有需要双击预编译对话框的Options选项处对弹出的Options选项对话框选择需要的预编译选项(一般情况下不做该步即采用缺省预编译选项)
e) 单击工具条最右边的预编译图标进行预编译
f) 预编译结束若出现询问保存Exampre 文件时应选择OK进行保存完成预编译
g) 如果预编译结束预编译对话框左边显示的状态图标为黄色(警告)或红色(预编译失败)时应双击该标识观察帮助或出错信息预编译失败应当重做节中编辑工作修改源程序再进行预编译直到通过预编译
编译准备
为了使工程能通过编译需要将预编译输出的工程源文件和Oracle支持SQL在VC环境下的运行库文件加入到工程中下面具体介绍增加这两个文件的步骤
) 将预编译的输出文件加入工程
a) 菜单Project / Add To Project 项 / Files 项
b) 在文件对话框中选择正确路径(见节和节)选定预编译输出的文件如Examc单击打开按钮即将预编译输出的工程源文件加入工程
) 将运行库文件加入工程
a) 菜单Project / Add To Project 项 / Files 项
b) 将文件对话框的文件类型改为所有文件
c) 路径选为Oracle_HOME \ Ora \ PRECOMP \ LIB \ MSVC
d) 选择OraSQLLIB文件单击打开钮完成将运行库文件加入工程
编译链接
a) 按F键或单击编译图标对工程进行编译链接如果没有出现错误则通过编译链接生成可执行文件如Examexe
b) 如果编译链接出现错误返回到节选择相应的预编译源文件如Exampc进行修改并保存然后按节做预编译预编译通过后单击OK按钮用新的 c文件代替原来的C源文件此时重新按F键进行编译链接直到排除所有错误生成可执行文件如Examexe
运行工程
a) 按Ctrl_F键或单击执行图标运行工程Examexe按工程中的提示逐步正确运行
b) 如果运行中出现错误返回到节修改相应预编译源文件再按节做预编译按节进行编译链接生成新的可执行文件然后重新运行工程直到正确实现工程的规定任务
编程举例
程序内容
一般SQL嵌入式程序主要有说明包含头文件子程序声明主程序和子程序等部分组成在主程序中调用有关子程序必备的子程序通常有连接到数据库子程序断开数据库子程序错误处理子程序和完成某项具体事务(如查询插入修改删除等)的工作子程序
程序举例
下面是一完整的可通过预编译编译链接和运行的示例程序
/* exampc 开发Oracle接口程序举例 */
/* 说明本程序介绍用PROC开发Oracle库接口的编程特点通过向AUTHS
* 表输入作家代码查询作家姓名及工资运行前应建表插入数据并提交*/
#include #include #include /* 包含SQL通讯区它用于处理错误*/
#include void connect(); /* 连接到Oracle Server */
void disconnect(); /* 断开到Oracle Server的连接 */
void sql_error(char *); /* 处理错误句柄 */
void select(); /* 查询子程序 */
extern sqlglm(char *int *int *);
/* 主程序 */
void main()
{
/* 安装错误处理句柄 */
EXEC SQL WHENEVER SQLERROR DO sql_error(Oracle错误\n);
/* 连接到数据库 */
connect();
/* 执行查询 */
select();
/* 断开数据库连接 */
disconnect();
}
/* 子程序 */
/* 连接子程序 connect() */
void connect()
{
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR username[] password[] server[];
EXEC SQL END DECLARE SECTION;
/* 输入用户名口令以及服务器名 */
printf(\n输入用户名);
gets(usernamearr);
usernamelen=(unsigned short)strlen((char *)usernamearr);
printf(\n输入口令);
gets(passwordarr);
passwordlen=(unsigned short)strlen((char *)passwordarr);
printf(\n输入服务器名);
gets(serverarr);
serverlen=(unsigned short)strlen((char *)serverarr);
/* 连接到Oracle服务器上 */
EXEC SQL CONNECT :username IDENTIFIED BY :password USING :server;
printf(\n以用户%s成功地连接到了服务器%s上!\n usernamearr serverarr);
}
/* 断开连接子程序 disconnect() */
void disconnect()
{
char temp;
printf(\n是否在断开连接前提交所有事务? (Y/N));
scanf(%c &temp);
fflush(stdin);
if(temp !=Y && temp != y)
{
/* 回退事务断开连接 */
EXEC SQL ROLLBACK WORK RELEASE;
printf(\n回退事务断开连接退出程序!\n\n);
}
else
{
/* 提交事务断开连接 */
EXEC SQL COMMIT WORK RELEASE;
printf(\n提交事务断开连接退出程序!\n\n);
exit();
}
}
/* 查询子程序 select()
* 首先输入作家代码然后查询作家姓名和工资*/
void select()
{
EXEC SQL BEGIN DECLARE SECTION;
char author_code[] name[];
float salary;
short salary_ind;
EXEC SQL END DECLARE SECTION;
printf(\n输入作家代码: );
gets(author_code);
/* 查询作家姓名和工资 */
EXEC SQL SELECT name salary INTO :name :salary:salary_ind
FROM auths
WHERE author_code = :author_code;
/* 根据指示变量的值来确定该作家的工资是否为空*/
if (salary_ind ==)
{
printf(\n作家代码\t作家姓名\t作家工资\n);
printf(\t\t\n);
printf(%s\t%s\t%f\n author_code name salary);
}
else
{
printf(作家%s的工资未录入为空值!\n name);
}
}
/* 错误处理子程序 sql_error() */
void sql_error(char *msg)
{
char err_msg[];
size_t buf_len msg_len;
/* 出现SQL错误继续往下执行 */
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf(\n%s\n msg);
buf_len=sizeof(err_msg);
/* 调用函数sqlglm()获得错误消息 */
sqlglm(err_msg &buf_len &msg_len);
printf(%*s\n msg_len err_msg);
/* 回退事务断开连接退出程序 */
EXEC SQL ROLLBACK RELEASE;
exit(EXIT_FAILURE);
}
建表和插入数据记录
上述示例程序如要正确运行还需以Oracle库的合法用户登录并创建AUTHS表和插入一些数据记录建表文件建表命令和插入数据记录的示例命令如下所述这里叙述的工作完成后上节生成的可执行文件才能正确运行
REM 以下为建表文件authsSQL
DROP TABLE auths CASCADE CONSTRAINTS
/
CREATE TABLE auths(
AUTHOR_CODE VARCHAR() NOT NULL
NAME VARCHAR()
BIRTHDATE DATE
ENTRY_DATE_TIME DATE
SALARY NUMBER()
remark VARCHAR())
/
REM 下一行为在PL/SQL环境中运行建表文件的命令
REM @ E: \ PROCW \ Exam \ authssql
REM 下一行为在PL/SQL环境中向auths表插入数据的命令插入后应提交(COMMIT)!
REM INSERT INTO auths(author_codenamesalary) VALUES(A王达琳);