java项目,从Oracle迁移到达梦数据库笔记

达梦数据库迁移挑战
本文记录了从Oracle11g迁移到达梦6.0数据库过程中遇到的问题及解决方案,包括字段名大小写处理、数据类型差异、语法关键字冲突及dual表访问等问题。

达梦数据库是个国产数据库,据说对Oracle有很好的兼容,本人亲自从Oracle11g迁移到达梦6.0的数据库上来,遇到一些问题,以下是问题记录:

 

1。字段名错误
虽然达梦SQL可以兼容字段大小写,但是JDVC实际上执行与Oracle会有差别,

达梦的SQL可以执行,但是返回的字段的列名仍然按SQL的大小写返回,而Oracle会变成全部的大写返回,

select typeid, typename from T_PUB_PRODUCT_TYPE

在用oracle执行后返回的列名叫TYPEID,TYPENAME

达梦返回值则为typeid,typename

比较好的做法是在数据库执行语句之前,强制所有语句转大写:

 

rs = stmt.executeQuery(strSql.toUpperCase());    //达梦数据库对列名区分大小写,Oracle会自动全转大写

 

==============================================
cuont(*)数据类型错误
语句:
select count(*) counts  from t_cus_product left join t_pub_product_type on p_type=typeid where p_createrid=200

oracle的count(*)可以兼容BigDecimal,达梦的count(*)是Long型
        //count = ((BigDecimal)mapCount.get("counts")).intValue();//Orcale 为 BigDecimal
        count = ((Long)mapCount.get("counts")).intValue();   //达梦数据库为Long


=====================================================
2。达梦数据库语法关键字错误

以下语句oracle 可以执行,达梦却报错误
select c.contractid,CONTRACTNO, c.contractname, c.type, sum,begin,end
state, userid, serviceid,P_NAME
from t_contract c
left join T_CUS_PRODUCT
 on c.PRODUCTID=P_ID
  where userid=200 order by contractid
 
原因:begin,end为达梦的保留关键字,语句修改为双引号的形式,可以通过:
select c.contractid,CONTRACTNO, c.contractname, c.type, sum,"begin","end"
state, userid, serviceid,P_NAME
from t_contract c
left join T_CUS_PRODUCT
 on c.PRODUCTID=P_ID
   where userid=200 order by contractid
=============================================
3。查询dual表报错,
语句:select seq_c006_message_content.nextval from dual

java报错:
java.sql.SQLException: 无效的表或视图名 'dual'
    at dm.jdbc.dbaccess.DBError.throwSQLException(Unknown Source)
    at dm.jdbc.driver.DmdbCSI.prepareSQL(Unknown Source)
    at dm.jdbc.driver.DmdbStatement.directExec(Unknown Source)
    at dm.jdbc.driver.DmdbStatement.executeQuery(Unknown Source)
    at cn.org.hz.common.dao.DBAccess.queryOneRow(DBAccess.java:110)
    at cn.org.hz.blh.i007.I007Blh.I007MessageAdd(I007Blh.java:136)
    at cn.org.hz.blh.i007.I007Blh$$FastClassByCGLIB$$f90d5dcf.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at cn.org.hz.common.aop.AroundInterceptor.invoke(AroundInterceptor.java:13)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
    at cn.org.hz.blh.i007.I007Blh$$EnhancerByCGLIB$$67fbf5f5.I007MessageAdd(<generated>)
    at cn.org.hz.ctrl.i007.I007Ctrl.I007MessageAdd(I007Ctrl.java:113)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:473)
    at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:410)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at cn.org.hz.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:23)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
    at java.lang.Thread.run(Thread.java:619)

解决在本用户下建立一个dual同义词
如果需要直接访问,可以用SYSDBA创建一个PUBLIC同义词:
CREATE PUBLIC SYNONYM dual for SYSTEM.SYSDBA.SYSDUAL;

 

达梦虽然在sysdba下造了一个dual表来兼容oracle但是却没有在每个新用户下建立同义词,所有一般对dual表的查询都会报错。

 

=================================================

 

迁移使用 Oracle 数据库Java 项目到达数据库是一个涉及多个步骤的过程,主要包括数据库结构迁移、数据迁移以及 Java 应用程序配置调整。以下是详细的迁移过程和注意事项。 ### ### 1. 数据库结构迁移迁移之前,需要将 Oracle 中的表结构转换达梦数据库支持的格式。由于 Oracle达梦在数据类型、函数、语法等方面存在差异,建议使用达梦提供的 **迁移工具(DM Data Migration Tool)** 进行结构迁移。 - 使用 DM 数据迁移工具连接源数据库Oracle)和目标数据库达梦),选择相应的模式或表进行迁移。 - 工具会自动识别并转换数据类型,例如 `VARCHAR2` 转换为 `VARCHAR`,`NUMBER` 转换为 `DECIMAL` 等[^1]。 - 需要检查索引、视图、存储过程等对象是否被正确转换,某些复杂的 PL/SQL 可能需要手动调整以适应达梦的 DMSQL 语法。 ### ### 2. 数据迁移 数据迁移可以采用以下几种方式: #### a. 使用达梦迁移工具 达梦数据库提供图形化迁移工具,支持从 Oracle 到达的数据迁移。只需填写 Oracle 的连接信息(如主机名、端口、用户名、密码等),然后选择需要迁移的表即可完成数据迁移[^2]。 #### b. 导出导入 SQL 文件 通过 PL/SQL Developer 或其他工具导出 Oracle 表结构和数据为 `.dmp` 或 `.sql` 文件,再将其导入到达数据库中。需要注意: - 导出时应选择“PL/SQL Developer”导出模式,避免使用“Oracle Export”,因为后者可能无法正确导入到达数据库[^3]。 - 导入时需根据达梦数据库语法调整 SQL 文件中的关键字、函数和语句。 #### c. 使用 ETL 工具 可借助 Kettle、DataX 等 ETL 工具进行数据抽取、转换和加载,适用于大规模数据迁移场景。 ### ### 3. Java 项目适配达梦数据库 Java 项目通常通过 JDBC 连接数据库,因此迁移过程中主要调整如下内容: #### a. 替换 JDBC 驱动 将原有的 Oracle JDBC 驱动(`ojdbc8.jar` 等)替换为达梦数据库提供的 JDBC 驱动(`dm8.jar`)。可以在 Maven 项目中修改 `pom.xml` 文件,示例如下: ```xml <dependency> <groupId>com.dm</groupId> <artifactId>DmJdbcDriver16</artifactId> <version>22.1</version> <scope>system</scope> <systemPath>${project.basedir}/lib/dm8.jar</systemPath> </dependency> ``` #### b. 修改数据库连接字符串 Oracle 的 JDBC URL 格式通常是: ```java jdbc:oracle:thin:@//host:port/service_name ``` 而达梦数据库的 JDBC URL 格式为: ```java jdbc:dm://host:port ``` 同时,驱动类名也需更改: - Oracle:`oracle.jdbc.driver.OracleDriver` - 达梦:`dm.jdbc.driver.Driver` #### c. 处理 SQL 兼容性问题 由于 Oracle达梦SQL 方面存在差异,建议: - 检查所有 SQL 语句,尤其是分页查询、序列、函数调用等部分。 - 替换 Oracle 特有的函数,例如 `NVL()` 替换为 `COALESCE()`,`ROWNUM` 替换为 `LIMIT`。 - 对于自增主键,达梦使用 `IDENTITY` 或者 `SEQUENCE` 实现,需调整相应的插入逻辑。 #### d. 测试与调试 完成上述修改后,应进行全面测试,包括: - 单元测试验证数据库操作是否正常执行。 - 性能测试确保系统在达梦数据库下的响应时间和吞吐量满足要求。 - 异常处理测试确保事务一致性。 ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值