蛋疼的数据库移植,艰难中进行。
??? 上周项目经理告诉我,客户想把数据库从oracle换成sqlsever 2005,然后要我搞定。说实话,我很讨厌这个差事,因为涉及到很多细节问题的解决,好在我比较闲,到现在为止,基本上解决问题,换了数据库后系统运行正常。以下是我解决问题的步骤,同时包括实现中的很多细节。因为对sql server 2005并不熟,一并把设计到的比较典型的sql 语句贴上来。
???? 首先是修改映射文件,增加SqlServerDriver映射oracle的格式:
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property><property name="myeclipse.connection.profile">oracle</property><property name="show_sql">true</property><property name="connection.url">jdbc:oracle:thin:@192.168.1.201:1521:orcl</property><property name="connection.username">wdrd</property><property name="connection.password">wdrd</property><property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
?
换成sql server后,将其映射文件修改成如下格式:
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property><property name="myeclipse.connection.profile">com.microsoft.sqlserver.jdbc.SQLServerDriver</property><property name="show_sql">true</property><property name="connection.url"> jdbc:sqlserver://192.168.1.201:1533;databaseName=wdrd</property><property name="connection.username">sa</property><property name="connection.password">ultratech</property><property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
?
映射文件修改完毕后,测试连接成功后,就要修改mapping文件了。连接oracle数据库时,如果我们的id是手动赋值的,那比较简单,也无需变化,采用“assigned”即可,但是对于自增的id,oracle要用到sequence,在oracle中,sequence是独立于table的,它们通常用来自增计数。废话 少说,我直接列出两张表的部分mapping文件为例。
表一:Fnd_Dept部门表,id是指定的
<class name="com.ultratech.omis.fnd.bo.FndDept" table="FND_DEPT"> <id name="deptId" type="java.lang.Long"> <column name="DEPT_ID" precision="10" scale="0" /> <generator > </generator> </id>
?
这种table的mapping不需要改变,Sql Server中直接copy就行。
?
表二:Fnd_Code系统字段表,id是自增的
<class name="com.ultratech.omis.fnd.bo.FndCode" table="FND_CODE"> <cache usage="read-write"/> <id name="codeId" type="java.lang.Long"> <column name="CODE_ID" precision="10" scale="0" /> <generator > <param name="sequence">FND_CODE_SEQ</param> </generator> </id>
?FND_CODE_SEQ是另外在oracle中建立的。
?
这种类型的表在sql server 2005的mapping文件如下所示:
<id name="codeId" type="java.lang.Long"> <column name="CODE_ID" precision="10" scale="0" /> <generator > </generator> </id>?需要注意的是,两个数据库建表的时候也有差异。
在sql server 指定Id自增时,需要采用以下模式:
? CODE_ID decimal(10,0)? identity(1,1)
oracle就很简单了,此处从略。
递归查询两者的递归查询差异比较大,下面是两个最典型的例子。
现有表dept,为方便理解,贴出建表语句
create table FND_DEPT( DEPT_ID NUMBER(10) not null, DEPT_PID NUMBER(10) not null, DEPT_NAME VARCHAR2(128) not null, BRANCH_ID VARCHAR2(3), SEQ NUMBER(4), CREATE_DATE DATE);alter table FND_DEPT add primary key (DEPT_ID);
oracle中的代码:
select dept.* from FND_DEPT dept start with dept.dept_id = 100 connect by prior dept.dept_id = dept.dept_pid order siblings by dept.SEQ asc;
?
sql server中的代码:
WITH deptCte (dept_id,dept_pid, dept_name,branch_id, seq,create_date)AS( SELECT * FROM fnd_dept AS e WHERE dept_id=100 /*定位点成员*/ UNION ALL SELECT e.* FROM fnd_dept AS e INNER JOIN deptCte AS l /*此处的l就是递归成员*/ ON e.dept_pid = l.dept_id)SELECT *FROM deptCte order by seq
????
?
???? 2.??? 查询某一部门的父部门(严格说是路径).
oracle中的代码为:
select dept.* from FND_DEPT dept start with dept.dept_id = 104 connect by prior dept.dept_pid = dept.dept_id order siblings by dept.SEQ asc;
?
sql server中的代码:
?
WITH deptCte (dept_id,dept_pid, dept_name,branch_id, seq,create_date,leavl)AS( SELECT *,0 as leavl /*此处添加leavl方便后面排序,oracle不一样,oracle中的leavl是关键字*/ FROM fnd_dept AS e WHERE dept_id=101 UNION ALL SELECT e.*,leavl+1 FROM fnd_dept AS e INNER JOIN deptCte AS l ON e.dept_id = l.dept_pid)SELECT dept_id,dept_pid, dept_name,branch_id, seq,create_dateFROM deptCte order by leavl desc?函数移植
oracle中的函数代码如下:
create or replace function WAIT_BEFORE(rep_id in number, rep_type in varchar2) return number is Result number;begin select COUNT(gr_w.report_id) into Result from gua_report gr_w, gua_report gr where gr.report_id = rep_id and gr_w.report_type = rep_type and gr_w.status = 'NO' and gr_w.report_date < gr.report_date; return(Result);end WAIT_BEFORE;
?
转换到sql server 2005中的代码为:
USE [wdrd]GO/****** Object: UserDefinedFunction [dbo].[WAIT_BEFORE] Script Date: 12/10/2010 15:02:09 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER FUNCTION [dbo].[WAIT_BEFORE](@rep_id decimal(10),@rep_type varchar(32))returns int--设置返回值,记住是returns 而不是returnASBEGIN DECLARE @result int set @result =(select count(*) from gua_report gr_w, gua_report gr where gr.report_id = @rep_id and gr_w.report_type = @rep_type and gr_w.status = 'NO' and gr_w.report_date < gr.report_date)return @result END
?
以上便是此次移植遇到的主要问题,当然还有其他细节问题,限于篇幅,此处从略。