背景
在公司的一个项目中,要使用达梦替换Oracle数据库。除了对数据库中对象的迁移外还需要对应用进行迁移,一般企业中数据库应用通常通过JDBC,OCI(如果是Oracle)/ODBC等方式链接数据库。JDBC不讲了,一般换上对应的Driver就可以搞定,问题不大,但C/C应用往往就未必那么容易。及时不考虑版权问题,目前国产数据库直接可以兼容OCI的并不多,一般MySQL系和PostgreSQL系的数据库会显得力不从心,但一些自研的国产数据库这方便往往兼容起来会相对容易些,目前我接触的国产数据库中达梦和OceanBase是可以做到兼容OCI接口的。其他的数据库就需要使用ODBC的方式进行迁移。今天以达梦为例,分别介绍如何使用OCI和ODBC进行C/C数据库应用的迁移。以及两者在迁移过程中的区别。
技术栈简介
- OTL
做过OCI/OCCI应用开发的小伙伴应该感触最深的就是接口太复杂,参数太多,生产效率低。(OCCI会少好一些),在企业中一般都会对OCI的接口进行二次封账(要不代码真的很难看)。之前很多项目都是基于公司自己封装的接口进行开发。当然如果你的公司没有这方面的积累也不用慌,有很多这样的开源框架可以选择(包括一些ORM框架),我个人比较倾向使用OTLv4,也是我们正在使用的integrated library
。它兼容大部分主流的数据,包括:Oracle,mysql,MSSQL,POSTGRESQL等; - OCI
Oracle Call Interface,提供了一组可对ORACLE数据库进行存取的接口子例程(函数); - ODBC
Open Database Connectivity,是为解决异构数据库间的数据共享的开放式数据库通用接口;
测试环境
软件 | 版本 |
---|---|
操作系统 | CentOS7 |
数据库 | 达梦DM8 |
DBI | OTLv4 |
获取otl 4.0 http://otl.sourceforge.net/otl3_compile.htm
代码准备
测试表
CREATE TABLE gchdb.company
(
id integer NOT NULL,
name character varying(20),
age integer NOT NULL,
address character(25),
salary numeric(18,2)
);
复制
ODBC环境搭建
OCI链接达梦
-CMakeLists.txt
cmake_minimum_required (VERSION 2.8) project (otloci) set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_DEBUG "-g3") set(CMAKE_CXX_FLAGS_RELEASE "-O2") set(CMAKE_BUILD_TYPE Debug) include_directories(./) include_directories(/usr/local/include) include_directories(/home/dmdba/dmoci/include) add_executable(otloci otloci.cpp) link_directories("/home/dmdba/dmoci") target_link_libraries(otloci /home/dmdba/dmoci/libdmoci.so)
复制
关键配置:
target_link_libraries(otloci /home/dmdba/dmoci/libdmoci.so)
dmoci的库文件;/home/dmdba/dmoci/include
接口所需头文件路径
核心源码
/// 主要宏定义
#define OTL_ORA12C // 适配Oracle 12C
#define OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE // 8i以上需要加这个
/// 保护otlv4头文件
#include "otlv4.h" // include the OTL 4.0 header file
/// 部分测试代码
try
{
otl_nocommit_stream o;
o.open(50, // buffer size
"merge INTO SYSDBA.COMPANY "
"using DUAL on (id = :id<int>) "
"when NOT MATCHED THEN "
"insert (id,name,age,address,salary) values (:id<int>,:name<char[21]>,:age<int>,:address<char[26]>,:salary<float>) "
"when matched then "
"update set name=:name<char[21]>, age=:age<int>, address=:address<char[26]>,salary=:salary<float>",
// SQL statement
db // connect object
);
o.set_flush(false);
o.set_commit(1);
char name[50] = {"小明"};
name[20] = '\0';
o << 103 << name << 18 << "dalian" << static_cast<float>(10000);
o.flush();
// db.commit();
}
catch(otl_exception& p)
{
cout<<"otl_exception:"<<endl;
cerr<<p.msg<<endl; // print out error message
cerr<<p.stm_text<<endl; // print out SQL that caused the error
cerr<<p.var_info<<endl; // print out the variable that caused the error
}
复制
测试
使用OCI的测试结果
id=103 age=18 name=小明 address=dalian
复制
使用ODBC的测试结果
otl_exception:
Incompatible data types in stream operation
merge INTO SYSDBA.COMPANY using DUAL on (id = ? ) when NOT MATCHED THEN insert (id,name,age,address,salary) values (? ,? ,? ,? ,? ) when matched then update set name=? , age=? , address=? ,salary=?
Variable: :id1<INT>, datatype in operator <</>>: CHAR
复制
看报错应该是类型不匹配,但实际上是绑定的参数个数错误
分析
首先在OTL官网找到一些线索
大概意思是:OCI可以按名字绑定,而ODBC是按位置进行绑定。
以这个线索进行分析,同名的变量例如:name<char[21]>在OCI中出现了两次,实际上只需要进行一次赋值。而ODBC中,首先不允许同名变量出现多次,且要对每一个:VAR进行赋值。因此绑定语句如下:
otl_nocommit_stream o;
o.open(50, // buffer size
"merge INTO SYSDBA.COMPANY "
"using DUAL on (id = :id<int>) "
"when NOT MATCHED THEN "
"insert (id,name,age,address,salary) values (:id1<int>,:name<char[21]>,:age<int>,:address<char[26]>,:salary<float>) "
"when matched then "
"update set name=:name1<char[21]>, age=:age1<int>, address=:address1<char[26]>,salary=:salary1<float>",
// SQL statement
db // connect object
);
复制
:name和:name1进行了区分
下面开始修改赋值,要与绑定字段的位置和数量匹配。
o << 106 << 106 << name << 16 << "dalian" << static_cast<float>(10000) << name << 16 << "dalian" << static_cast<float>(1000);
复制
验证
修改后重新编译,运行,结果如下:
id=106 age=16 name=小红 address=dalian
复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
文章被以下合辑收录
评论
相关阅读
达梦数据发布上市后首份财报:2024年营收10.4亿、净利3.6亿,销售平均薪酬 101 万、研发 36 万
通讯员
228次阅读
2025-04-15 12:09:47
国产数据库图谱又上新|82篇精选内容全览达梦数据库
墨天轮编辑部
218次阅读
2025-04-23 12:04:21
全国首部图数据库国家标准发布!达梦数据深度参与!
达梦数据
164次阅读
2025-04-02 09:34:13
达梦数据携手中国移动建成国内最大分布式数据库集群
通讯员
151次阅读
2025-04-02 15:10:38
达梦数据库快速上手指南
孙莹
143次阅读
2025-04-10 23:35:47
达梦中国数据库产业基地竣工,光谷崛起“数据之弧”
通讯员
140次阅读
2025-04-23 09:41:05
SQLark V3.4 更新 | 新增 PostgreSQL 数据库支持、SQL 常用代码段、表设计器体验升级,超多新功能等你来探索!
达梦产品与服务
122次阅读
2025-04-17 09:38:11
SQLark 数据生成 | 外键、自增列、check约束、虚拟列都能自动识别!
达梦产品与服务
99次阅读
2025-04-11 10:41:05
【喜报】您有一件邮件请查收!恭喜您通过达梦DCA/DCP考试~
云贝19941464235
75次阅读
2025-04-02 10:47:26
中国软件深度研究报告:打造操作系统、数据库央企龙头
通讯员
37次阅读
2025-04-21 12:20:29