随着数据库的普及,企业级应用越来越多地依赖于关系型数据库。Oracle数据库作为业内领先的数据库之一,其强大的功能和稳定可靠的性能被广泛使用。而C语言作为编程语言之一,则被众多开发者所喜爱。当C语言调用Oracle存储过程时,遵循以下步骤:
1. 引入Oracle库文件。
#include
2. 建立Oracle连接。
OCIEnv* pEnv;
OCISrvCtx* pSrvc;
OCIError* pErr;
OCIDbPool* pPool;
OCIDateTime* pDate;
3. 准备sql语句。
OCIStmt* pSt = NULL;
OCIBind* pBind1 = NULL;
OCIBind* pBind2 = NULL;
const char* pszSql = "begin test(:1,:2); end;";
4. 执行sql语句。
rc = OCIStmtPrepare(pSt, pErr, (OraText*)pszSql, strlen(pszSql),
OCI_NTV_SYNTAX, OCI_DEFAULT);
rc = OCIBindByName(pSt, &pBind1, pErr, (OraText*)":1",
strlen(":1"), (void *) &num1, sizeof(num1), SQLT_INT,
(void *)&ind1, 0, 0, 0, 0, OCI_DEFAULT);
rc = OCIBindByName(pSt, &pBind2, pErr, (OraText*)":2",
strlen(":2"), (void *)&num2, sizeof(num2), SQLT_INT,
(void *)&ind2, 0, 0, 0, 0, OCI_DEFAULT);
rc = OCIStmtExecute(pSvrconn, pSt, pErr, 1, 0, NULL, NULL, OCI_DEFAULT);
5. 关闭连接。
OCILogoff(pSvrconn, pErr);
下面以一个简单的例子来说明如何在C语言中调用Oracle存储过程。
//Oracle数据库测试.c
#include
#include
#include
void err_handler(void *errhp, const char *file, const int line)
{
text msgbuf[512];
sb4 errcode = 0;
OCIErrorGet(errhp, 1, NULL, &errcode, msgbuf, 511, OCI_HTYPE_ERROR);
printf("File %s, line %d:\n %.*s", file, line, 511, msgbuf);
exit(1);
}
int main(int argc, char **argv)
{
OCIEnv *envhp = NULL;
OCIError *errhp = NULL;
OCIServer *svrhp = NULL;
OCISvcCtx *svchp = NULL;
OCISession *usrhp = NULL;
OCIStmt *stmthp = NULL;
OCIBind* bindp1 = NULL;
OCIBind* bindp2 = NULL;
int num1, num2, answer;
sb2 ind1, ind2;
text sqlstmt[1024] = "";
if(OCIInitialize(OCI_THREADED, NULL, NULL, NULL, NULL) != OCI_SUCCESS)
return -1;
if(OCIEnvCreate(&envhp, OCI_THREADED | OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL) != OCI_SUCCESS)
return -1;
OCIHandleAlloc(envhp, (void **)&errhp, OCI_HTYPE_ERROR, 0, NULL);
OCIHandleAlloc(envhp, (void **)&svrhp, OCI_HTYPE_SERVER, 0, NULL);
if(OCIServerAttach(svrhp, errhp, (text *)"ORCL", strlen("ORCL"), OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
OCIHandleAlloc(envhp, (void **)&svchp, OCI_HTYPE_SVCCTX, 0, NULL);
OCISvcCtxSet(svchp, errhp, svrhp, 0);
if(OCIHandleAlloc(envhp, (void **)&usrhp, OCI_HTYPE_SESSION, 0, NULL) != OCI_SUCCESS)
return -1;
if(OCIAttrSet((void *)usrhp, OCI_HTYPE_SESSION, (void *)"test", strlen("test"), OCI_ATTR_USERNAME, errhp) != OCI_SUCCESS)
return -1;
if(OCIAttrSet((void *)usrhp, OCI_HTYPE_SESSION, (void *)"test", strlen("test"), OCI_ATTR_PASSWORD, errhp) != OCI_SUCCESS)
return -1;
if(OCISessionBegin(svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIHandleAlloc(envhp, (void **)&stmthp, OCI_HTYPE_STMT, 0, NULL) != OCI_SUCCESS)
return -1;
if(OCIStmtPrepare2(svchp, &stmthp, errhp, (const text *) "BEGIN test(:1, :2, :3); END;", strlen("BEGIN test(:1, :2, :3); END;"), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
num1 = 3;
ind1 = 0;
num2 = 4;
ind2 = 0;
if(OCIBindByName(stmthp, &bindp1, errhp, (text *) ":1", strlen(":1"), (dvoid *) &num1, sizeof(num1), SQLT_INT, &ind1, NULL, NULL, 0, NULL, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIBindByName(stmthp, &bindp2, errhp, (text *) ":2", strlen(":2"), (dvoid *) &num2, sizeof(num2), SQLT_INT, &ind2, NULL, NULL, 0, NULL, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIStmtExecute(svchp, stmthp, errhp, 1, 0, NULL, NULL, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIBindByName(stmthp, &bindp2, errhp, (text *) ":3", strlen(":3"), (dvoid *)&answer, sizeof(answer), SQLT_INT, NULL, NULL, NULL, 0, NULL, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
printf("The answer to the addition of %d and %d is %d.\n", num1, num2, answer);
if(OCISessionEnd(svchp, errhp, usrhp, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIHandleFree(stmthp, OCI_HTYPE_STMT) != OCI_SUCCESS)
return -1;
if(OCIHandleFree(usrhp, OCI_HTYPE_SESSION) != OCI_SUCCESS)
return -1;
if(OCIServerDetach(svrhp, errhp, OCI_DEFAULT) != OCI_SUCCESS)
err_handler(errhp, __FILE__, __LINE__);
if(OCIHandleFree(svchp, OCI_HTYPE_SVCCTX) != OCI_SUCCESS)
return -1;
if(OCIHandleFree(svrhp, OCI_HTYPE_SERVER) != OCI_SUCCESS)
return -1;
if(OCIHandleFree(errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS)
return -1;
OCIHandleFree(envhp, OCI_HTYPE_ENV);
return 0;
}
以上是一个简单的示例,当然实际情况可能要复杂得多。在实际开发中,我们在调用Oracle存储过程时还需要处理众多问题,比如输入参数和输出参数的处理、错误处理等。但只要掌握了基本的步骤,我们就可以愉快地使用C语言调用Oracle存储过程了。