当前位置:首页 > 行业动态 > 正文

c oracle数据库连接

在C语言中,可通过安装OCI库,配置环境变量后用OCI函数实现与Oracle数据库的连接操作。

在C语言中连接Oracle数据库,主要有以下几种方法:

1、使用OCI(Oracle Call Interface)

安装和配置OCI:在使用OCI之前,需要先安装Oracle客户端并配置环境变量,如ORACLE_HOMELD_LIBRARY_PATH,在Linux系统中,可以在终端执行以下命令来设置环境变量:

 export ORACLE_HOME=/path/to/oracle/client
     export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

编写OCI程序

初始化OCI环境:在进行数据库操作之前,需要初始化OCI环境。

 OCIEnv *env;
       OCIError *err;
       if (OCIEnvCreate(&env, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL) != OCI_SUCCESS) {
           fprintf(stderr, "OCIEnvCreate failed
");
           return EXIT_FAILURE;
       }
       if (OCIHandleAlloc(env, (void *)&err, OCI_HTYPE_ERROR, 0, NULL) != OCI_SUCCESS) {
           fprintf(stderr, "OCIHandleAlloc for error handle failed
");
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }

连接数据库:使用OCILogon函数进行数据库连接。

 OCISvcCtx *svc;
       if (OCIHandleAlloc(env, (void *)&svc, OCI_HTYPE_SVCCTX, 0, NULL) != OCI_SUCCESS) {
           fprintf(stderr, "OCIHandleAlloc for service context failed
");
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }
       if (OCILogon(env, err, &svc, "username", strlen("username"), "password", strlen("password"), "dbname", strlen("dbname")) != OCI_SUCCESS) {
           fprintf(stderr, "OCILogon failed
");
           OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }
       printf("Connected to Oracle Database successfully!
");

执行SQL语句:首先创建语句句柄,然后使用OCIStmtPrepareOCIStmtExecute函数执行SQL语句。

c oracle数据库连接

 OCIStmt *stmt;
       if (OCIHandleAlloc(svc, (void *)&stmt, OCI_HTYPE_STMT, 0, NULL) != OCI_SUCCESS) {
           fprintf(stderr, "OCIHandleAlloc for statement handle failed
");
           OCILogoff(svc, err);
           OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }
       char *sql = "SELECT * FROM mytable";
       if (OCIStmtPrepare(stmt, err, (const text *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT) != OCI_SUCCESS) {
           fprintf(stderr, "OCIStmtPrepare failed
");
           OCIHandleFree((void *)stmt, OCI_HTYPE_STMT);
           OCILogoff(svc, err);
           OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }
       if (OCIStmtExecute(svc, stmt, err, 1, 0, NULL, NULL, OCI_DEFAULT) != OCI_SUCCESS) {
           fprintf(stderr, "OCIStmtExecute failed
");
           OCIHandleFree((void *)stmt, OCI_HTYPE_STMT);
           OCILogoff(svc, err);
           OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }

处理结果集:定义变量来存储查询结果,并使用OCIDefineByPosOCIStmtFetch函数处理结果集。

 OCIDefine *defn;
       char result[100];
       if (OCIHandleAlloc(env, (void *)&defn, OCI_HTYPE_DEFINE, 0, NULL) != OCI_SUCCESS) {
           fprintf(stderr, "OCIHandleAlloc for define handle failed
");
           OCIHandleFree((void *)stmt, OCI_HTYPE_STMT);
           OCILogoff(svc, err);
           OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }
       if (OCIDefineByPos(stmt, &defn, err, 1, (void *)result, sizeof(result), SQLT_STR, NULL, NULL, NULL, OCI_DEFAULT) != OCI_SUCCESS) {
           fprintf(stderr, "OCIDefineByPos failed
");
           OCIHandleFree((void *)defn, OCI_HTYPE_DEFINE);
           OCIHandleFree((void *)stmt, OCI_HTYPE_STMT);
           OCILogoff(svc, err);
           OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
           OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
           OCIEnvFree(env, OCI_DEFAULT);
           return EXIT_FAILURE;
       }
       while (OCIStmtFetch(stmt, err, 1, OCI_FETCH_NEXT, OCI_DEFAULT) == OCI_SUCCESS) {
           printf("Result: %s
", result);
       }

清理资源:在程序结束时,需要清理分配的资源。

 OCIHandleFree((void *)stmt, OCI_HTYPE_STMT);
       OCILogoff(svc, err);
       OCIHandleFree((void *)svc, OCI_HTYPE_SVCCTX);
       OCIHandleFree((void *)err, OCI_HTYPE_ERROR);
       OCIHandleFree((void *)env, OCI_HTYPE_ENV);

2、使用ODBC(Open Database Connectivity)

安装和配置ODBC:首先需要安装ODBC驱动程序,并配置数据源名称(DSN),可以使用命令行工具odbcinst和配置文件odbc.ini来进行配置,在Linux系统中,可以使用以下命令安装和配置ODBC:

 sudo apt-get install unixodbc unixodbc-dev
     odbcinst -i -d -f /path/to/odbcinst.ini
     odbcinst -i -s -l -f /path/to/odbc.ini

编写ODBC程序

c oracle数据库连接

初始化ODBC环境:使用SQLAllocHandle函数分配环境句柄,并设置ODBC版本。

 SQLHENV env;
       SQLHDBC dbc;
       SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
       SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);

连接数据库:使用SQLDriverConnect函数连接到数据库。

 SQLCHAR dsn[] = "DSN=mydsn;UID=username;PWD=password;";
       SQLHDBC dbc;
       if (SQLDriverConnect(dbc, NULL, dsn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE) != SQL_SUCCESS) {
           fprintf(stderr, "SQLDriverConnect failed
");
           SQLFreeHandle(SQL_HANDLE_DBC, dbc);
           SQLFreeHandle(SQL_HANDLE_ENV, env);
           return EXIT_FAILURE;
       }

执行SQL语句:使用SQLExecDirectSQLPrepareSQLExecute函数执行SQL语句。

 SQLHSTMT stmt;
       SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
       if (SQLExecDirect(stmt, (SQLCHAR *)"SELECT * FROM mytable", SQL_NTS) != SQL_SUCCESS) {
           fprintf(stderr, "SQLExecDirect failed
");
           SQLFreeHandle(SQL_HANDLE_STMT, stmt);
           SQLDisconnect(dbc);
           SQLFreeHandle(SQL_HANDLE_DBC, dbc);
           SQLFreeHandle(SQL_HANDLE_ENV, env);
           return EXIT_FAILURE;
       }

处理结果集:使用SQLBindColSQLFetch函数处理结果集。

 SQLCHAR result[100];
       if (SQLBindCol(stmt, 1, SQL_C_CHAR, result, sizeof(result), NULL) != SQL_SUCCESS) {
           fprintf(stderr, "SQLBindCol failed
");
           SQLFreeHandle(SQL_HANDLE_STMT, stmt);
           SQLDisconnect(dbc);
           SQLFreeHandle(SQL_HANDLE_DBC, dbc);
           SQLFreeHandle(SQL_HANDLE_ENV, env);
           return EXIT_FAILURE;
       }
       while (SQLFetch(stmt) == SQL_SUCCESS) {
           printf("Result: %s
", result);
       }

清理资源:在程序结束时,需要清理分配的资源。

c oracle数据库连接

 SQLFreeHandle(SQL_HANDLE_STMT, stmt);
       SQLDisconnect(dbc);
       SQLFreeHandle(SQL_HANDLE_DBC, dbc);
       SQLFreeHandle(SQL_HANDLE_ENV, env);

3、**使用Pro*C预编译器

**安装和配置Pro*C**:首先需要安装Oracle客户端,并配置Pro*C环境,在Linux系统中,可以设置以下环境变量:

 export ORACLE_HOME=/path/to/oracle/client
     export PATH=$ORACLE_HOME/bin:$PATH

**编写Pro*C程序**:在Pro*C程序中,可以直接嵌入SQL语句。

 #include <stdio.h>
     #include <stdlib.h>
     #include <sqlca.h>
     EXEC SQL INCLUDE SQLCA;
     int main() {
         EXEC SQL BEGIN DECLARE SECTION;
         VARCHAR user[20], pass[20], tnsname[20];
         char ename[20];
         int empno;
         EXEC SQL END DECLARE SECTION;
         strcpy(user.arr, "umail");
         user.len = (unsigned short)strlen((char *)user.arr);
         strcpy(pass.arr, "umail");
         pass.len = (unsigned short)strlen((char *)pass.arr);
         strcpy(tnsname.arr, "umail");
         tnsname.len = (unsigned short)strlen((char *)tnsname.arr);
         EXEC SQL CONNECT :user IDENTIFIED BY :pass USING :tnsname;
         EXEC SQL declare emp_cursor cursor for select id, ename from umail.tt1;
         EXEC SQL open emp_cursor;
         EXEC SQL WHENEVER NOT FOUND DO break;
         while (1) {
             EXEC SQL fetch emp_cursor into :empno, :ename;
             if (sqlca.sqlcode != 0) break;
             printf("the empno %d's name is %s/n", empno, ename);
         }
         printf("Yeah! We get %d records/n", empno);
         EXEC SQL close emp_cursor;
         EXEC SQL commit work release;
         return 0;
     }