C语言实现Oracle9i数据库连接
在许多企业级应用程序中使用数据库是常见需求。其中Oracle数据库是非常常用的一种。本文将介绍如何用C语言实现连接Oracle9i数据库的方法。
1. 安装Oracle Client
需要安装Oracle Client软件。这可以从Oracle官方网站上下载。Oracle Client的安装包通常很大,因此需要一定时间下载和安装。
2. 包含头文件
在C程序中,需要包含头文件,该文件包含了连接Oracle9i数据库所需的函数和结构。
“`c
#include
3. 定义变量
在程序中需要定义一些变量来存储连接信息和数据库操作的结果信息。这些变量包括:
- OCIEnv *envhp:环境句柄变量,用于保存OCI环境信息。
- OCIError *errhp:错误句柄变量,用于保存OCI错误信息。
- OCISvcCtx *svchp:服务上下文句柄变量,用于保存连接的服务上下文信息。
- OCIStmt *stmthp:语句句柄变量,用于保存SQL语句的相关信息。
- OCIDefine *defnp:定义句柄变量,用于定义结果集中的数据类型。
- OCIBind *bindp:绑定句柄变量,用于绑定传入SQL语句的参数。
```c
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIDefine *defnp;
OCIBind *bindp;
另外,需要定义一些其它辅助变量,如用户名、密码、连接字符串等。在本例中,这些变量定义如下:
“`c
char *username = “test”;
char *password = “test123”;
char *conn_str = “localhost:1521/ORCL”;
char *sql = “select * from employees”;
4. 初始化OCI环境
在使用OCI连接Oracle数据库之前,需要先初始化OCI环境。这可以通过OCIEnvCreate函数来完成。
```c
OCIEnvCreate(&envhp, OCI_THREADED | OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL);
除envhp以外的参数分别表示:
– OCI_THREADED:多线程环境,使用线程安全的OCI库。
– OCI_OBJECT:使用OCI对象。
– NULL:分配器回调函数指针。
– NULL:分配器上下文指针。
– NULL:默认内存大小。
– NULL:客户端字符集。
– 0:默认字符集ID。
– NULL:指定日志函数的指针。
5. 创建连接
连接数据库需要使用OCILogon2函数。OCILogon2函数会打开Oracle Client连接到指定的Oracle服务器上。
“`c
OCILogon2(envhp, errhp, &svchp, (const OraText*)username, strlen(username), (const OraText*)password, strlen(password), (const OraText*)conn_str, strlen(conn_str), OCI_LOGON2_SYSPRIV);
其中envhp和errhp分别是环境句柄和错误句柄。&svchp是用来存储连接的服务上下文信息的指针。username、password和conn_str则分别为用户名、密码和连接字符串。OCI_LOGON2_SYSPRIV表示使用管理员权限连接。
6. 执行SQL语句
连接成功后,就可以使用OCIStmtPrepare函数和OCIStmtExecute函数来执行SQL语句。
```c
OCIStmtPrepare(stmthp, errhp, (const OraText *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
OCIStmtExecute(svchp, stmthp, errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
7. 获取结果集
使用OCIDefineByPos函数定义结果集中的数据类型。
“`c
OCIDefineByPos(stmthp, &defnp, errhp, 1, &emp_no, sizeof(emp_no), SQLT_INT, NULL, NULL, NULL, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defnp, errhp, 2, &emp_name, sizeof(emp_name), SQLT_STR, NULL, NULL, NULL, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defnp, errhp, 3, &emp_salary, sizeof(emp_salary), SQLT_FLT, NULL, NULL, NULL, OCI_DEFAULT);
在定义完结果集的数据类型后,使用OCIStmtFetch函数获取结果集数据。
```c
while (OCIStmtFetch2(stmthp, errhp, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT) != OCI_NO_DATA) {
printf("%d %s %f\n", emp_no, emp_name, emp_salary);
}
完整代码如下:
“`c
#include
#include
#include
#include
int mn()
{
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIDefine *defnp;
OCIBind *bindp;
char *username = “test”;
char *password = “test123”;
char *conn_str = “localhost:1521/ORCL”;
char *sql = “select * from employees”;
int emp_no;
char emp_name[20];
float emp_salary;
OCIEnvCreate(&envhp, OCI_THREADED | OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL);
OCIHandleAlloc(envhp, (void**)&errhp, OCI_HTYPE_ERROR, 0, NULL);
OCIHandleAlloc(envhp, (void**)&svchp, OCI_HTYPE_SVCCTX, 0, NULL);
OCILogon2(envhp, errhp, &svchp, (const OraText*)username, strlen(username), (const OraText*)password, strlen(password), (const OraText*)conn_str, strlen(conn_str), OCI_LOGON2_SYSPRIV);
OCIHandleAlloc(envhp, (void**)&stmthp, OCI_HTYPE_STMT, 0, NULL);
OCIStmtPrepare(stmthp, errhp, (const OraText *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defnp, errhp, 1, &emp_no, sizeof(emp_no), SQLT_INT, NULL, NULL, NULL, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defnp, errhp, 2, &emp_name, sizeof(emp_name), SQLT_STR, NULL, NULL, NULL, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defnp, errhp, 3, &emp_salary, sizeof(emp_salary), SQLT_FLT, NULL, NULL, NULL, OCI_DEFAULT);
OCIStmtExecute(svchp, stmthp, errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
while (OCIStmtFetch2(stmthp, errhp, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT) != OCI_NO_DATA) {
printf(“%d %s %f\n”, emp_no, emp_name, emp_salary);
}
OCIStmtFree(stmthp, OCI_DEFAULT);
OCIHandleFree(svchp, OCI_HTYPE_SVCCTX);
OCIHandleFree(errhp, OCI_HTYPE_ERROR);
OCIHandleFree(envhp, OCI_HTYPE_ENV);
return 0;
}
总结
通过上述步骤,就可以使用C语言连接到Oracle9i数据库,并执行SQL语句获取结果集。在实际项目中,需要根据具体需求,在此基础上进行更多的开发工作。