深入理解C语言使用Oracle接口(c语言的oracle接口)

深入理解C语言使用Oracle接口

C语言是一种强大而广泛应用的编程语言,而Oracle数据库则是业界广泛使用的关系型数据库系统。将两者结合起来,我们可以在C语言中使用Oracle的服务,实现对Oracle数据库的访问与操作。

Oracle提供了一个C语言的应用程序接口(Application Programming Interface,API),被称为OCI(Oracle Call Interface)。OCI允许我们以面向对象的方式访问Oracle数据库,并进行各种操作,例如执行SQL语句、获取查询结果、调用存储过程等。下面我们就来一步步探索如何使用OCI。

我们需要安装并配置好Oracle客户端。OCI是Oracle客户端库中的一部分,因此我们需要先安装Oracle客户端。安装完成后,还需要将Oracle客户端库的路径添加到我们的系统环境变量中,这样我们就可以在C语言中链接到Oracle客户端库了。

接下来,我们来看一个OCI的基本使用实例。该实例展示了如何连接Oracle数据库、执行简单的查询操作、释放OCI环境等操作。详细代码如下:

#include 
#include
#include
void checkerr(OCIError *errhp, sword status)
{
text errbuf[512];
sb4 errcode = 0;
OCIErrorGet((void *)errhp, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
printf("ERROR CODE = %d\n%s\n", errcode, errbuf);
exit(1);
}
int mn()
{
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIServer *srvhp;
OCISession *usrhp;
OCIStmt *stmthp;
OCIParam *parmph;
text *stmt = (text *)"SELECT * FROM EMP";
ub4 buflenp, iter = 0;
ub2 rowcnt, field_count;
sword status, bind_status = 0;

/* Initialize OCI environment */
if (OCIEnvCreate(&envhp, OCI_DEFAULT, (void *)0, (void *(*)(void *, size_t))0, (void* (*)(void *, void *, size_t))0, (void (*)(void *, void *))0, (size_t)0, (void **)0))
checkerr(errhp, status);

/* Initialize OCI error handling */
if (OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0))
checkerr(errhp, status);

/* Initialize OCI server context */
if (OCIHandleAlloc((dvoid *)envhp, (dvoid **)&srvhp, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0))
checkerr(errhp, status);

/* Initialize OCI service context */
if (OCIHandleAlloc((dvoid *)envhp, (dvoid **)&svchp, OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0))
checkerr(errhp, status);

/* Attach to the Oracle database */
if (OCIServerAttach(srvhp, errhp, (text *)"ORCL", strlen("ORCL"), 0))
checkerr(errhp, status);

/* Set the server context in the service context */
if (OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4)0, OCI_ATTR_SERVER, errhp))
checkerr(errhp, status);

/* Log in to the Oracle database */
if (OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, OCI_HTYPE_SESSION, (size_t)0, (dvoid **)0))
checkerr(errhp, status);
if (OCIAttrSet((dvoid *)usrhp, OCI_HTYPE_SESSION, (dvoid *)"HR", (ub4)strlen("HR"), OCI_ATTR_USERNAME, errhp))
checkerr(errhp, status);
if (OCIAttrSet((dvoid *)usrhp, OCI_HTYPE_SESSION, (dvoid *)"hr", (ub4)strlen("hr"), OCI_ATTR_PASSWORD, errhp))
checkerr(errhp, status);
status = OCISessionBegin(svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT);
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
checkerr(errhp, status);
/* Set the user context in the service context */
if (OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, usrhp, (ub4)0, OCI_ATTR_SESSION, errhp))
checkerr(errhp, status);

/* Prepare SQL statement */
if (OCIHandleAlloc((dvoid *)envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0))
checkerr(errhp, status);
if (OCIStmtPrepare(stmthp, errhp, stmt, strlen((char *)stmt), OCI_NTV_SYNTAX, OCI_DEFAULT))
checkerr(errhp, status);

/* Execute SQL statement */
if (OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT))
checkerr(errhp, status);

/* Retrieve field count */
if (OCIStmtGetPieceInfo(stmthp, errhp, &buflenp, OCI_DESCRIBE_ONLY) != OCI_NO_DATA)
{
if (OCIStmtGetPieceInfo(stmthp, errhp, &buflenp, OCI_ATTR_PARAM_COUNT) != OCI_NO_DATA)
field_count = buflenp;
else
checkerr(errhp, OCI_ERROR);
}
else
checkerr(errhp, OCI_ERROR);
/* Display query results */
for (iter = 1; iter
printf("Column %d\t", iter);
printf("\n");
while (OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT) == OCI_SUCCESS)
{
for (iter = 1; iter
printf("%s\t", "");
printf("\n");
}
/* Release resources */
if (OCIHandleFree((dvoid *)stmthp, OCI_HTYPE_STMT))
checkerr(errhp, status);
if (OCISessionEnd(svchp, errhp, usrhp, OCI_DEFAULT))
checkerr(errhp, status);
if (OCIHandleFree((dvoid *)usrhp, OCI_HTYPE_SESSION))
checkerr(errhp, status);
if (OCIHandleFree((dvoid *)svchp, OCI_HTYPE_SVCCTX))
checkerr(errhp, status);
if (OCIServerDetach(srvhp, errhp, OCI_DEFAULT))
checkerr(errhp, status);
if (OCIHandleFree((dvoid *)srvhp, OCI_HTYPE_SERVER))
checkerr(errhp, status);
if (OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR))
checkerr(errhp, status);
if (OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV))
checkerr(errhp, status);

return 0;
}

在上述代码中,我们首先将OCI环境、OCI错误处理、OCI服务端环境、OCI会话、OCI语句句柄等资源逐一分配和初始化好,然后通过OCI API进行连接、SQL语句执行和查询结果的展示等操作,最后释放OCI资源。需要注意的是,OCI资源的释放顺序非常重要,不遵循资源释放的顺序可能会导致内存泄漏或其他问题。

由于OCI是面向对象的C API,这意味着我们可以使用结构体和函数来封装OCI API,从而实现更为友好的编程体验。以下是一个使用结构体封装OCI API的例子:

#include 
#include
#include
typedef struct OCIConnection {
OCIEnv *env;
OCIError *err;
OCISvcCtx *svc;
OCIServer *srv;
sword status;
} OCIConnection;

void checkerr(OCIError *errhp, sword status)
{
text errbuf[512];
sb4 errcode = 0;
OCIErrorGet((void *)errhp, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
printf("ERROR CODE = %d\n%s\n", errcode, errbuf);
exit(1);
}
OCIConnection *connect_db()
{
OCIConnection *conn = malloc(sizeof(OCIConnection));
if

数据运维技术 » 深入理解C语言使用Oracle接口(c语言的oracle接口)