cOracle ProC 程序设计技术指南(oracle pro)
COracle ProC 程序设计技术指南
COracle ProC 是一个嵌入 SQL 的 C 语言预编译器,它允许 C 程序员编写在 Oracle 数据库上运行的程序。它提供了对 SQL 数据库的强大支持,并提供了一些 C 函数,方便程序员直接访问底层数据库。
1. 简介
COracle ProC 由 Oracle 公司开发,它支持所有的数据库对象和功能,包括存储过程、触发器和游标等。ProC 在编译阶段将 SQL 语句预编译成 C 语言代码,这样程序在运行时直接执行 C 代码,避免了 SQL 语句解释的过程,提高了程序的执行效率。
2. 环境搭建
使用 COracle ProC 开发程序需要满足以下条件:
– Oracle 数据库服务
– COracle ProC 编译器
– C 语言编译器
在安装 COracle ProC 之前,需要确保已安装 Oracle 数据库服务,可以使用以下命令查看数据库版本号:
“`sql
select * from v$version;
然后,在 Oracle 官网下载和安装 COracle ProC 编译器和 Oracle Instant Client。COracle ProC 编译器是一个单独的安装包,安装后会自动注册到环境变量中。Oracle Instant Client 是一个轻量级的客户端组件,它可以作为 COracle ProC 程序的运行时环境。
3. 程序编写
使用 COracle ProC 编写程序的一般流程如下:
- 编写 SQL 命令
- 使用 COracle ProC 编译器将 SQL 命令预编译为 C 语言代码
- 编写 C 语言代码
- 使用 C 语言编译器将 C 语言代码编译为可执行程序
下面是一个查询员工信息的例子。我们需要创建一个名为 emp 的表:
```sqlcreate table emp(
empno number(4) primary key, ename varchar2(10),
job varchar2(9), mgr number(4),
hiredate date, sal number(7,2),
comm number(7,2), deptno number(2)
);
然后,我们使用 COracle ProC 编译器编写以下代码:
“`c
#include
#include
#include
#include
#define USERNAME “test”
#define PASSWORD “test”
#define DATABASE “localhost:1521/orcl”
void check_error(OCIError *err, sword status)
{
text errbuf[512];
sb4 errcode;
OCIErrorGet((dvoid *)err, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
printf(“Error(%d): %s\n”, errcode, errbuf);
}
int mn(int argc, char *argv[])
{
OCIEnv *envhp; // 环境句柄
OCIServer *srvhp; // 服务器句柄
OCIError *errhp; // 错误句柄
OCISession *sesshp; // 会话句柄
OCIStmt *stmthp; // 语句句柄
OCIDefine *defhp1, *defhp2, *defhp3, *defhp4; // 定义句柄
sword status;
char *sql = “SELECT EMPNO, ENAME, JOB, MGR FROM EMP”;
ub4 empno, mgr;
text ename[11], job[10];
// 初始化环境句柄
status = OCIEnvCreate(&envhp, OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **)0);
check_error((OCIError *)0, status);
// 分配错误句柄
status = OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **)0);
check_error(errhp, status);
// 分配服务器句柄
status = OCIHandleAlloc((dvoid *)envhp, (dvoid **)&srvhp, OCI_HTYPE_SERVER, (size_t) 0, (dvoid **)0);
check_error(errhp, status);
// 分配会话句柄
status = OCIHandleAlloc((dvoid *)envhp, (dvoid **)&sesshp, OCI_HTYPE_SESSION, (size_t) 0, (dvoid **)0);
check_error(errhp, status);
// 连接数据库
status = OCILogon(envhp, errhp, &sesshp, (text *)USERNAME, strlen(USERNAME), (text *)PASSWORD, strlen(PASSWORD), (text *)DATABASE, strlen(DATABASE));
check_error(errhp, status);
// 分配语句句柄
status = OCIHandleAlloc((dvoid *)envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, (size_t) 0, (dvoid **)0);
check_error(errhp, status);
// 准备 SQL 语句
status = OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
check_error(errhp, status);
// 定义查询结果
status = OCIDefineByPos(stmthp, &defhp1, errhp, 1, (dvoid *)&empno, sizeof(empno), SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT);
check_error(errhp, status);
status = OCIDefineByPos(stmthp, &defhp2, errhp, 2, (dvoid *)ename, sizeof(ename), SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT);
check_error(errhp, status);
status = OCIDefineByPos(stmthp, &defhp3, errhp, 3, (dvoid *)job, sizeof(job), SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT);
check_error(errhp, status);
status = OCIDefineByPos(stmthp, &defhp4, errhp, 4, (dvoid *)&mgr, sizeof(mgr), SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT);
check_error(errhp, status);
// 执行查询
status = OCIStmtExecute(sesshp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT);
check_error(errhp, status);
// 输出查询结果
printf(“%-10s %-10s %-9s %s\n”, “EMPNO”, “ENAME”, “JOB”, “MGR”);
while ((status = OCIStmtFetch(stmthp, errhp, (ub4)1, OCI_FETCH_NEXT, OCI_DEFAULT)) == OCI_SUCCESS)
printf(“%-10d %-10s %-9s %d\n”, empno, ename, job, mgr);
if (status != OCI_NO_DATA)
check_error(errhp, status);
// 释放资源
OCIHandleFree((dvoid *)stmthp, OCI_HTYPE_STMT);
OCIHandleFree((dvoid *)sesshp, OCI_HTYPE_SESSION);
OCIHandleFree((dvoid *)srvhp, OCI_HTYPE_SERVER);
OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR);
OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);
return 0;
}
程序首先初始化环境句柄、分配错误句柄、服务器句柄、会话句柄和语句句柄,然后连接数据库、准备 SQL 语句、定义查询结果、执行查询、输出查询结果,最后释放资源。在输出查询结果时,我们使用了 C 语言中的格式控制符,保证了结果的对齐。
4. 总结
COracle ProC 程序设计技术指南