VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1525|回复: 5

看了好些提问linux c连接oracle的帖子,我以前写了个简单的封装,不只对大家有没有帮助!

[复制链接]

1

主题

5

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
发表于 2020-1-29 21:40:02 | 显示全部楼层 |阅读模式
oracle的使用比较复杂,我将它的应用封装成类似mysql的那种方法。有两个文件:oracle.h, oracle.c, 最后是用法举例(没有编译认证),希望对大家有所帮助,有错误也希望大家指出并改正阿,不支持blob, clob,有空再更新吧。
by the way, 需要oracle环境,可以安装oracle客户端(我这个好像是9i的吧),也可以用oracle_instance, 很好用的,大家可以到网上查查。
文件1:oracle.h

#ifndef        _ORACLE_H__
#define _ORACLE_H__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <oci.h>

typedef        struct st_oci
{
        char        ip[32];
        int        port;
        char        user[32];
        char        pass[32];
        char        sid[32];

        OCIEnv          *envhp;
        OCIError        *errhp;
        OCIServer       *srvhp;
        OCISvcCtx       *svchp;
        OCISession      *authp;
        OCIStmt         *stmthp;
        OCIBind         *bindhp;
        OCIParam        *colhp;
        OCIDefine       **defhp;

}OCI_ENV;

typedef        struct        st_getdata
{
        int        tag;
        int        num_column;
        int        num_row;

        char        **buf;
        int        *buf_len;
}OCI_DATA;

#define        NOT_BIND 0
#define        ALREADY_BIND 1

int        oci_init_env(OCI_ENV *env, char *ip, int port, char *user, char *pass, char *sid);

int        oci_query(OCI_ENV *env, char *query);

int        oci_insert(OCI_ENV *env, char *query);

int        oci_fetch_data(OCI_ENV *env, char *query, OCI_DATA *data);

int     oci_free_result(OCI_DATA *data);

int        oci_end(OCI_ENV *env);

#endif //_ORACLE_H__

回复

使用道具 举报

1

主题

5

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
 楼主| 发表于 2020-3-3 20:30:01 | 显示全部楼层
文件2:oracle.c
#include "oracle.h"

/*        1, if error
        0, if succes
*/
int        oci_init_env(OCI_ENV *env, char *ip, int port, char *user, char *pass, char *sid)
{

        OCIEnv     *envhp;
        OCIError   *errhp;
        OCISvcCtx  *svchp;
        OCIStmt    *stmthp;

        if(env==NULL || env->user==NULL || env->pass==NULL || env->sid==NULL || env->ip==NULL){
                return 1;
        }       
       
        snprintf(env->ip, 32, "%s",  ip);
        snprintf(env->user, 32, "%s", user);
        snprintf(env->pass, 32, "%s", pass);
        snprintf(env->sid, 32, "%s", sid);
        env->port = port;

        if(OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0,
                (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0)){
                return 1;
        }
        if(OCIEnvInit((OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0, (dvoid **) 0)){
                return 1;
        }
        if(OCIHandleAlloc((dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,(size_t) 0,(dvoid **) 0)){
                return 1;
        }
        if(OCIHandleAlloc((dvoid *) envhp, (dvoid **)&svchp, OCI_HTYPE_SVCCTX,(size_t)NULL, (dvoid **)NULL)){
                OCIHandleFree((dvoid *) errhp, OCI_HTYPE_ERROR);
                OCIHandleFree((dvoid *) envhp, OCI_HTYPE_ENV);
                return 1;
        }
            if(OCILogon(envhp, errhp, &svchp, env->user, strlen(env->user), env->pass, strlen(env->pass),
                env->sid, strlen(env->sid))){
                OCIHandleFree((dvoid *) svchp, OCI_HTYPE_SVCCTX);
                OCIHandleFree((dvoid *) errhp, OCI_HTYPE_ERROR);
                OCIHandleFree((dvoid *) envhp, OCI_HTYPE_ENV);
                return 1;
        }   
            if(OCIHandleAlloc((dvoid *)envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT,(size_t)NULL, (dvoid **)NULL)){
                OCILogoff(svchp, errhp);
                OCIHandleFree((dvoid *) svchp, OCI_HTYPE_SVCCTX);
                OCIHandleFree((dvoid *) errhp, OCI_HTYPE_ERROR);
                OCIHandleFree((dvoid *) envhp, OCI_HTYPE_ENV);
                return 1;
        }

        env->envhp = envhp;
        env->errhp = errhp;
        env->svchp = svchp;
        env->stmthp = stmthp;
        env->defhp = NULL;
        env->bindhp = NULL;

        return 0;

}

/*        1, if error
        0, if success
*/
int     oci_insert(OCI_ENV *env, char *query)
{
        if(OCIStmtPrepare(env->stmthp, env->errhp, query, (ub4)strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT)){
                return 1;
        }

        if(OCIStmtExecute(env->svchp, env->stmthp, env->errhp, (ub4) 1, (ub4) 0,
                (CONST OCISnapshot *) NULL,(OCISnapshot *) NULL, OCI_DEFAULT | OCI_COMMIT_ON_SUCCESS)){
                return 1;
        }

        return 0;
}

/*      1, if error
        0, if success
*/
int     oci_query(OCI_ENV *env, char *query)
{      
        if(OCIStmtPrepare(env->stmthp, env->errhp, query, (ub4)strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT)){
                return 1;
        }
        
        if(OCIStmtExecute(env->svchp, env->stmthp, env->errhp, (ub4) 1, (ub4) 0,
                (CONST OCISnapshot *) NULL,(OCISnapshot *) NULL, OCI_DEFAULT | OCI_COMMIT_ON_SUCCESS)){
                return 1;
        }

        return 0;
}

                                                                                                               
/*        1, if has more data
        0, if has no data any more
*/
int        oci_fetch_data(OCI_ENV *env, char *query, OCI_DATA *data)
{
        int        num_col;
        char        **buf_col;
        int        *len_col;
        int        i;

        OCIParam        *colhp;
        OCIDefine        **defhp;
       
        char        tmpbuf[7][50];
        memset(tmpbuf, 0, 350);

        if(env == NULL || query == NULL || data == NULL){
                return 0;
        }
        if(data->tag == NOT_BIND){       
                num_col = 0;

                if(OCIStmtPrepare(env->stmthp, env->errhp, query, (ub4)strlen(query), OCI_NTV_SYNTAX,
                        OCI_DEFAULT) > 0){
                        return 0;
                }

                if(OCIStmtExecute(env->svchp, env->stmthp, env->errhp, (ub4) 0, (ub4) 0,
                        (CONST OCISnapshot *) NULL,(OCISnapshot *) NULL, OCI_DESCRIBE_ONLY) > 0){
                        return 0;
                }
       
                if(OCIAttrGet(env->stmthp, OCI_HTYPE_STMT, &num_col, 0, OCI_ATTR_PARAM_COUNT, env->errhp)){
                        return 0;
                }       
               
                if(num_col == 0){
                        return 0;
                }
                len_col = (int *)malloc(sizeof(int) * num_col);
                if(len_col == NULL){
                        return 0;
                }
                buf_col = (char **)malloc(sizeof(char *) * num_col);
                if(buf_col == NULL){
                        return 0;
                }
                defhp = (OCIDefine **)malloc(sizeof(OCIDefine *) * num_col);
                if(defhp == NULL){
                        return 0;
                }
                data->num_column = num_col;
                data->num_row = 0;
                data->buf = buf_col;
                data->buf_len = len_col;

                memset(len_col, 0, sizeof(int) * num_col);
                memset(buf_col, 0, sizeof(char *) * num_col);
                for(i=1; i<=num_col; i++){
                        OCIParamGet(env->stmthp, OCI_HTYPE_STMT, env->errhp, (void **)&colhp, i);
                        OCIAttrGet(colhp, OCI_DTYPE_PARAM, (len_col+i-1), 0, OCI_ATTR_DATA_SIZE, env->errhp);
                        *(len_col+i-1) = *(len_col+i-1)+1;
                        *(buf_col+i-1) = (char *)malloc((int)(*(len_col+i-1)));
                        if(*(buf_col+i-1) == NULL){
                                return 0;
                        }
                        memset(*(buf_col+i-1), 0, (int)(*(len_col+i-1)));
                        if(OCIDefineByPos(env->stmthp, (defhp+i-1), env->errhp, i, (ub1 *)(*(buf_col+i-1)),
                                *(len_col+i-1), SQLT_STR, NULL, (dvoid *)0, (ub2 *)0, OCI_DEFAULT)){
                                return 0;
                        }
                }
                if(OCIStmtExecute(env->svchp, env->stmthp, env->errhp, (ub4) 0, (ub4) 0,
                        (CONST OCISnapshot *) NULL,(OCISnapshot *) NULL, OCI_DEFAULT) > 0){
                        return 0;
                }
                data->tag = ALREADY_BIND;
        }
        for(i=0; i<data->num_column; i++){
                memset(data->buf[i], 0, data->buf_len[i]);
        }
        if (OCI_NO_DATA != OCIStmtFetch(env->stmthp, env->errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)){
                data->num_row++;
                return 1;
        }
        else{
                data->tag = NOT_BIND;
                return 0;
        }
}

/*        1, if error
        0, if success
*/
int        oci_free_result(OCI_DATA *data)
{
        int        i;

        if(data == NULL){
                return 1;
        }
        if(data->buf_len)
                free(data->buf_len);
        if(data->buf){
                for(i=0; i<data->num_column; i++){
                        if(*(data->buf+i)){
                                free(*(data->buf+i));
                        }
                }
                free(data->buf);
        }
        return 0;
}


int     oci_end(OCI_ENV *env)
{
        OCILogoff(env->svchp, env->errhp);
        OCIHandleFree((dvoid *) env->svchp, OCI_HTYPE_SVCCTX);
               OCIHandleFree((dvoid *) env->errhp, OCI_HTYPE_ERROR);
        OCIHandleFree((dvoid *) env->envhp, OCI_HTYPE_ENV);
                                                                                                               
        return 0;
}
回复

使用道具 举报

1

主题

5

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
 楼主| 发表于 2020-3-3 22:15:01 | 显示全部楼层
程序举例:
#include "oracle.h"

int main()
{
        OCI_ENV *simple_env;
        simple_env = (OCI_ENV *)malloc(sizeof(OCI_ENV));
        memset(simple_env, 0, sizeof(OCI_ENV));
        /* 初始化环境 */
        if(oci_init_env(simple_env, oracle_ip, oracle_port, oracle_user, oracle_pass, oracle_sid)){
                return 1;
        }

        /* 插入 */
        if(oci_insert(simple_env, "insert into tmp('a', 'b') values('value_a', 'value_b')")){
                _error();
        }
        /* 更新 */
        if(oci_query(simple_env, "update tmp set 'a' = 'value_new_a'")){
                _error();
        }
        
        /* 取数据 */
        OCI_DATA *data = (OCI_DATA *)malloc(sizeof(OCI_DATA));
        memset(data, 0, sizeof(OCI_DATA));
        while(oci_fetch_data(simple_env, "select 'a', 'b' from tmp", data) == 1){
                printf("a: %s\tb: %s\n", data->buf[0], data->buf[1]);
        }
        
        /* 注销 */
        oci_end(simple_env);
        
        return 0;
}
回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-3-12 20:00:02 | 显示全部楼层
mark 学习
回复

使用道具 举报

0

主题

2

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-4-26 10:45:01 | 显示全部楼层
OCCI (OCI/C++) 两个语句就可以连至数据库。你的OCI是C语言版吗?不明白你为什么那么写。

Environment *env = Environment::createEnvironment (Environment::DEFAULT);
Connection *conn = env->createConnection (user, passwd, db);

回复

使用道具 举报

1

主题

5

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
 楼主| 发表于 2020-5-4 20:30:01 | 显示全部楼层
是c语言版
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表