达梦8——接口DCI——基本概念;基本使用;

 


 一、基本概念

OCI(Oracle Call Interface)是 ORACLE 公司开发的一个接口,C语言、C++通过这个接口,可以访问 Oracle 数据库;

DM DCI 是参照 OCI 的接口标准,结合自身的特点,为C或C++开发人员提供访问达梦数据库的一款接口产品。

 

二、基本使用

1、下载Visual Studio等C可用IDE;

2、新建空的C项目,新建C文件,把以下源码复制到C文件中;

/************************************************************************/
/* DCI编程实例 */
/************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "DCI.h"
/* 声明句柄 */
OCIEnv* envhp; /* 环境句柄 */
OCISvcCtx* svchp; /* 服务环境句柄 */
OCIServer* srvhp; /* 服务器句柄 */
OCISession* authp; /* 会话句柄 */
OCIStmt* stmthp; /* 语句句柄 */
OCIDescribe* dschp; /* 描述句柄 */
OCIError* errhp; /* 错误句柄 */
OCIDefine* defhp[3]; /* 定义句柄 */
OCIBind* bidhp[4]; /* 绑定句柄 */
sb2 ind[3]; /* 指示符变量 */
/* 绑定select结果集的参数 */
text szpersonid[11]; /* 存储personid列 */
text szsex[2]; /* 存储sex列 */
text szname[51]; /* 存储name列 */
text szemail[51]; /* 存储mail列 */
text szphone[26]; /* 存储phone列 */
char sql[256]; /* 存储执行的sql语句*/
int main(int argc, char* argv[])
{
    char strServerName[50];
    char strUserName[50];
    char strPassword[50];
    int ret;
    text errbuf[100];
    /* 设置服务器,用户名和密码 */
    strcpy(strServerName, "localhost");
    strcpy(strUserName, "SYSDBA");
    strcpy(strPassword, "SYSDBA");
    /* 初始化OCI应用环境*/
    OCIInitialize(OCI_DEFAULT, NULL, NULL, NULL, NULL);
    /* 初始化环境句柄 */
    OCIEnvInit(&envhp, OCI_DEFAULT, 0, 0);
    /* 分配句柄 */
    OCIHandleAlloc(envhp, (dvoid**)&svchp, OCI_HTYPE_SVCCTX, 0, 0); /*服务器环境句柄*/
    OCIHandleAlloc(envhp, (dvoid**)&srvhp, OCI_HTYPE_SERVER, 0, 0); /* 服务器句柄*/
    OCIHandleAlloc(envhp, (dvoid**)&authp, OCI_HTYPE_SESSION, 0, 0); /* 会话句柄 */
    OCIHandleAlloc(envhp, (dvoid**)&errhp, OCI_HTYPE_ERROR, 0, 0); /* 错误句柄 */
    OCIHandleAlloc(envhp, (dvoid**)&dschp, OCI_HTYPE_DESCRIBE, 0, 0); /*描述符句柄*/
    /* 连接服务器 */
    OCIServerAttach(srvhp, errhp, (text*)strServerName,(sb4)strlen(strServerName), OCI_DEFAULT);
    /* 设置用户名和密码 */
    OCIAttrSet(authp, OCI_HTYPE_SESSION, (text*)strUserName,(ub4)strlen(strUserName), OCI_ATTR_USERNAME, errhp);
    OCIAttrSet(authp, OCI_HTYPE_SESSION, (text*)strPassword,(ub4)strlen(strPassword), OCI_ATTR_PASSWORD, errhp);
    /* 设置服务器环境句柄属性 */
    OCIAttrSet((dvoid*)svchp, (ub4)OCI_HTYPE_SVCCTX,
        (dvoid*)srvhp, (ub4)0, OCI_ATTR_SERVER, errhp);
    OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, (dvoid*)authp,
        0, OCI_ATTR_SESSION, errhp);




    /* 创建并开始一个用户会话 */
    OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, OCI_DEFAULT);
    OCIHandleAlloc(envhp, (dvoid**)&stmthp, OCI_HTYPE_STMT, 0, 0); /* 语句句柄 */
            ///************************************************************************/
            ///* 查询person表 */
            ///************************************************************************/
            strcpy(sql, "select personid, name, phone from sysdba.person");
            /* 准备SQL语句 */
            OCIStmtPrepare(stmthp, errhp, (text*)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
            /* 绑定输出列 */
            OCIDefineByPos(stmthp, &defhp[0], errhp, 1, (ub1*)szpersonid,
                sizeof(szpersonid), SQLT_STR, &ind[0], 0, 0, OCI_DEFAULT);
            OCIDefineByPos(stmthp, &defhp[1], errhp, 2, (ub1*)szname,
                sizeof(szname), SQLT_STR, &ind[1], 0, 0, OCI_DEFAULT);
            OCIDefineByPos(stmthp, &defhp[2], errhp, 3, (ub1*)szphone,
                sizeof(szphone), SQLT_STR, &ind[2], 0, 0, OCI_DEFAULT);
            /* 执行SQL语句 */
            ret = OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, 0, NULL, NULL, OCI_DEFAULT);
            if (ret != 0)
            {
                OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);
                printf("%s\n", errbuf);
            }
            printf("%-10s%-10s%-10s\n", "PERSONID", "NAME", "PHONE");
            while ((OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)) != OCI_NO_DATA)
            {
                printf("%-10s", szpersonid);
                printf("%-10s", szname);
                printf("%-10s\n", szphone);
            }
            /************************************************************************/
            /* 向person表插入一条数据 */
            /************************************************************************/
            memset(sql, 0, sizeof(sql));
            strcpy(sql, "insert into sysdba.person(sex, name, email, phone) values(:sex,:name,:email,:phone)");
            /* 准备SQL语句 */
            OCIStmtPrepare(stmthp, errhp, (text*)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
            /* 设置输入参数 */
            memset(szsex, 0, sizeof(szsex));
            strcpy(szsex, "FM");
            memset(szname, 0, sizeof(szname));
            strcpy(szname, "张三");
            memset(szemail, 0, sizeof(szemail));
            strcpy(szemail, "z@g.com");
            memset(szphone, 0, sizeof(szphone));
            strcpy(szphone, "027-00");
            /* 绑定输入列 */
            OCIBindByName(stmthp, &bidhp[0], errhp, ":sex", 4, szsex, strlen((char*)szsex),
                SQLT_AFC, NULL, NULL, NULL, 0, NULL, 0);
            OCIBindByName(stmthp, &bidhp[1], errhp, ":name", 5, szname, strlen((char*)szname),
                SQLT_AFC, NULL, NULL, NULL, 0, NULL, 0);
            OCIBindByName(stmthp, &bidhp[2], errhp, ":email", 6, szemail, strlen((char*)szemail),
                SQLT_AFC, NULL, NULL, NULL, 0, NULL, 0);
            OCIBindByName(stmthp, &bidhp[3], errhp, ":phone", 6, szphone, strlen((char*)szphone),
                SQLT_AFC, NULL, NULL, NULL, 0, NULL, 0);
            /* 执行SQL语句 */
            ret = OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, (CONST OCISnapshot*) 0, (OCISnapshot*)0,
                (ub4)OCI_DEFAULT);
            if (ret != 0)
            {
                OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);
                printf("%s\n", errbuf);
            }
            /* 提交到数据库 */
            OCITransCommit(svchp, errhp, OCI_DEFAULT);
         
    //结束会话
    OCISessionEnd(svchp, errhp, authp, (ub4)0);
    //断开与数据库的连接
    OCIServerDetach(srvhp, errhp, OCI_DEFAULT);
    //释放OCI句柄
    OCIHandleFree((dvoid*)dschp, OCI_HTYPE_DESCRIBE);
    OCIHandleFree((dvoid*)stmthp, OCI_HTYPE_STMT);
    OCIHandleFree((dvoid*)errhp, OCI_HTYPE_ERROR);
    OCIHandleFree((dvoid*)authp, OCI_HTYPE_SESSION);
    OCIHandleFree((dvoid*)svchp, OCI_HTYPE_SVCCTX);
    OCIHandleFree((dvoid*)srvhp, OCI_HTYPE_SERVER);
    return 0;
}

 

3、添加依赖

由于在编译的过程中需要用到 DM 的头文件 dci.h,
在连接阶段需要用到 dmoci.lib 这个库文件,
在执行阶段需要用到动态库 dmoci.dll、dmcalc.dll、dmelog.dll、dmmen.dll、dmos.dll、dmutl.dll、
dmclientlex.dll、dmfldr_dll.dll、dmbcast.dll、dmdta.dll、dmcfg.dll、dmstrt.dll、dmcpr.dll、dmcyt.dll、dmcvt.dll、dmmout.dll、dmdpi.dll、dmcomm.dll。

所以,我们需要添加这些依赖项;

具体步骤:

  • 右击项目,打开属性,
  • C/C++ -> 常规 -> 附加包含目录 -> c:\dmdbms\include
  • 链接器 -> 附加库目录 -> c:\dmdbms\include
  • 链接器 -> 附加依赖项 -> dmoci.lib

 当我们添加好依赖后,main.c文件里的“以来未找到”就会消失了;

 

 

4、建表

由于main.c文件里需要查询和插入sysdba模式下的person表,所以打开DM管理工具,去sysdba模式下新建一个person表;

这里要注意,到底是去新建一个person表,还是PERSON表,如果dm初始化实例时选择的是大小写不敏感,则无所谓;

但如果dm选择的大小写敏感,那就有所谓了,否则会找不到表;
首先大小写敏感下的person表和PERSON表不一样,
其次是dm的sql解释器自动把所有字母转换为大写字母,如果大小写敏感的话,我们小写的表名和列名就找不到了;
如果不想要dm解释器自动转换我们输入的sql,就要在对象名上加双引号,这样dm解释器就回去找小写的表明和列名了;;

 

 

5、执行

点击‘调式’, 点击‘开始执行(不调试)’

注意:如果报strcpy不全的错误,可以右击项目属性->C/C++->预处理器->预处理器定义中添加:_CRT_SECURE_NO_WARNINGS
     参考:https://blog.csdn.net/qq_33757398/article/details/81204372

 

 

 

posted @ 2020-09-09 14:41  Eric-Shen  阅读(3155)  评论(0编辑  收藏  举报