最近一直为一件事情很是烦恼,老大让将sqlserver2005中的三个表数据全部都迁移到oracle中,当然,如果表结构都一样,迁移也是很容易的事情,首先建立同样的表机构,写两个数据库连接工具,一个是sqlserver的,一个是oracle的,紧接着,写迁移类,(忘了告诉到家,这三个表中都是有上百万条数据,如果不用批处理的话,时间可想而知了),这个类必须是可以批处理插入的。
首先写DBUtil数据连接工具。
package com.xqq.DBUtil;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class DBUtil {
private final static String DB_URL = "jdbc:oracle:thin:@192.168.40.37:1521:CSOA";
private final static String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private final static String DB_USERNAME = "CSOA";
private final static String DB_PASSWORD = "CSOA";
public static Connection getConnection(){
Connection conn = null;
try{
Class.forName(DB_DRIVER);//反射获得驱动
conn = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);//建立连接
System.out.println(2);
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
public void closeConnection(Connection conn){
try{
if(conn!=null){
if(conn!=null){
conn.close();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
//public static void main(String[] args) throws Exception{
Connection connection=DBUtil.getConnection();
//String sql="select * from CCAT_SOSHIKI";
//PreparedStatement smt=(PreparedStatement)connection.prepareStatement(sql);
//ResultSet rs=smt.executeQuery();
//ResultSetMetaData me=rs.getMetaData();
//System.out.println(me.getColumnCount());
//for(int i=1;i<=me.getColumnCount();i++)
//System.out.print(me.getColumnName(i)+" ");
//while(rs.next()){
//for(int i=1;i<=me.getColumnCount();i++)
//System.out.print(rs.getString(i)+" ");
//System.out.println();
//System.out.println();
//}
//System.out.println(DBUtil.getConnection());
//}
}
main方法中是测试代码,这里就不多详细介绍了,sqlserver连接工具DBUtil就不多介绍了,因为只需要改一下上面的字段就OK啦。
紧接着,是要写从原数据库中迁移的数据,也即sqlserver SQL语句。
public void convert(String strYMD,String endYMD) {
Hashtable compare = new Hashtable();//建立一个hashtable
String startYMD,enddYMD;
try{
startYMD = new SimpleDateFormat("yyyy-mm-dd").format(new SimpleDateFormat("yyyymmdd").parse(strYMD));
enddYMD = new SimpleDateFormat("yyyy-mm-dd").format(new SimpleDateFormat("yyyymmdd").parse(endYMD));
String sql = "select " +
"FT_EMP_ID," +
"FT_YMD,"+
"FT_TIMEM_No," +
"FT_TYPE,"+
"FT_START_TIME," +
"FT_END_TIME," +
"FT_NOTE," +
"FT_APPROVL_TIME " +
"from T_FINANCE_TIME" +
" where FT_YMD between ? and ?";//取出原表中要用到的字段
System.out.println(sql);
Connection conn1s = DBUtil2.getConnection();//连接sqlserver数据库
PreparedStatement pstmt = conn1s.prepareStatement(sql);//执行查询语句
pstmt.setString(1, startYMD);//(下面的所有语句是对新表中要用到数据编辑)
pstmt.setString(2, enddYMD);
ResultSet rs = pstmt.executeQuery();
System.out.println(sql);
SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
Calendar c = Calendar.getInstance();
while(rs.next()){
//System.out.println(j++);
T_FINACE_TIME time = new T_FINACE_TIME();
if(rs.getString(1).charAt(0) == 'A'){
time.setCMP_CD("02");
}else
{
time.setCMP_CD("01");
}
time.setFT_EMP_ID(rs.getString(1));
Date date = new SimpleDateFormat("yyyy-mm-dd").parse(rs.getString(2));
if (compare.containsKey(rs.getString(1)+new SimpleDateFormat("yyyymmdd").format(date)+rs.getInt(3))){
System.out.println("comparewain:"+rs.getString(1)+new SimpleDateFormat("yyyymmdd").format(date)+rs.getInt(3));
continue;
}//这段代码很重要,如果有重复的字段,忽略,执行下一条数据。
time.setFT_YMD(new SimpleDateFormat("yyyymmdd").format(date));
//System.out.println(time.getFT_YMD());
time.setFT_TIMEM_No(rs.getInt(3));
//
//if(String.valueOf(Integer.parseInt(rs.getString(4))-131000).charAt(0) != '0'){
//time.setFT_TYPE(String.valueOf((String.valueOf(Integer.parseInt(rs.getString(4))-131000)).charAt(1)));
//}else{
if(rs.getString(4)==null ||rs.getString(4).equals("")){
time.setFT_TYPE("");
}else{
time.setFT_TYPE(String.valueOf(Integer.parseInt(rs.getString(4))-131000));
}
//}
//System.out.println(time.getFT_TYPE());
time.setFT_START_TIME(rs.getString(5));
time.setFT_END_TIME(rs.getString(6));
if (rs.getString(5) == null || rs.getString(5).equals("")
|| rs.getString(6) == null
|| rs.getString(6).equals("")) {
time.setTIME_WK(0);
} else {
time.setTIME_WK((Float.parseFloat(rs.getString(6)) - Float
.parseFloat(rs.getString(5))) / 2);
}
if(rs.getString(7)== null|| rs.getString(7).equals("")){
time.setFT_NOTE("");
}else{
time.setFT_NOTE(rs.getString(7));
}
if(rs.getString(8) == null || rs.getString(7).equals("")){
time.setFT_APPROVL_TIME("");
}else{
Date date1 = new SimpleDateFormat("yyyy-mm-dd").parse(rs.getString(8));
time.setFT_APPROVL_TIME(new SimpleDateFormat("yyyymmdd").format(date1));
}
//System.out.println(time.getFT_APPROVL_TIME());
String s = formatDate.format(c.getTime());
//System.out.println(s);
time.setINS_DATE(formatDate.parse(s));
time.setAPPROVL_KBN("1");
compare.put(rs.getString(1)+new SimpleDateFormat("yyyymmdd").format(date)+rs.getInt(3), "1");//这一步很是关键!
System.out.println(compare.size());
list.add(time);
}
conn1s.close();
System.out.println(list.size());
}catch(Exception e){
e.printStackTrace();
}
}
其中里面很多不同的字段需要转换編輯的,这就不多说了。
下面一步执行转换:
public void execute(Connection conn) {
try {
conn.setAutoCommit(false);
InsertStatement =
"INSERT INTO PQX_EXP" +
"(CMP_CD," +
"USR_ID," +
"REC_YMD," +
"ZHINO," +
"KBN_FINA,"+
"REC_ST_KBN," +
"REC_ET_KBN," +
"TIME_WK,"+
"BIKO," +
"APPROVL_USR,"+
"APPROVL_KBN,"+
"APPROVL_YMD," +
"INS_USERID,"+
"INS_DATE," +
"UP_USERID," +
"UP_DATE)" +
"VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement pst = conn.prepareStatement(InsertStatement);
int count = 0;
for (T_FINACE_TIME t_finace_time : list) {
pst.setString(1, t_finace_time.getCMP_CD());
pst.setString(2, t_finace_time.getCMP_CD() + 0
+ t_finace_time.getFT_EMP_ID());
//SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//String sdate = sdf.format(t_finace_time.getFT_YMD());
pst.setString(3, t_finace_time.getFT_YMD());
pst.setInt(4, t_finace_time.getFT_TIMEM_No());
pst.setString(5, t_finace_time.getFT_TYPE());
pst.setString(6, t_finace_time.getFT_START_TIME());
pst.setString(7, t_finace_time.getFT_END_TIME());
pst.setFloat(8, t_finace_time.getTIME_WK());
pst.setString(9, t_finace_time.getFT_NOTE());
pst.setString(10, t_finace_time.getCMP_CD() + 0
+ t_finace_time.getFT_EMP_ID());
pst.setString(11, t_finace_time.getAPPROVL_KBN());
pst.setString(12, t_finace_time.getFT_APPROVL_TIME());
pst.setString(13, t_finace_time.getCMP_CD() + 0
+ t_finace_time.getFT_EMP_ID());
pst.setDate(14, new java.sql.Date(t_finace_time.getINS_DATE()
.getTime()));
pst.setString(15, t_finace_time.getCMP_CD() + 0
+ t_finace_time.getFT_EMP_ID());
pst.setDate(16, new java.sql.Date(t_finace_time.getINS_DATE()
.getTime()));
pst.addBatch();//执行批处理,如果到了一千条就执行一次,当然效率也是相当快的。
if (++count % bachSize == 0 || count == (list.size()) - 1) {
pst.executeBatch();
conn.commit();
pst.clearBatch();
}
System.out.println(count);
}
pst.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
两个方法执行完毕!
这里,主要要强调两个问题,第一,如果,原来数据库中有重复的数据,但现在oracle中不允许有联合关键字重复如何办?我用一个Hashtable保留了数据唯一性(这个问题纠结了几天,老大后来告诉我的)。这样就可以顺利执行啦!
第一次,写这样的博客,写的不好,请多多包含。
转载于:https://blog.51cto.com/6049752/1236009