今天工作中遇到个数据迁移的问题,几经周折啊,说说过程,db2导入mysql
1,开始的策略:直接用export从DB2导出数据,用import导入数据到mysql
================================DB2之间迁移==========================================
具体步骤:
为了执行存储过程还建立了一张中间表:
LIXL_MAXID,专门用来存放表名和对应的最大的maxID
1,完整备份
a.备份建表语句
-----(用quest central工具生成脚本)createTable.txt
b.备份表数据
------(用quest central工具生成脚本)export.txt 记得修改文本添加modified by codepage=1208
执行这个脚本生成del文件
2.开始导入 执行脚本import.txt
知识点:
export语句:
EXPORT TO 'D:\data\allExport\UI_DEPARTMENT.del' OF del modified by codepage=1208 //这里是设置编码格式
SELECT * FROM "APPUSER"."UI_DEPARTMENT";
import语句:
ALTER TABLE LIXL_UI_DEPARTMENT ALTER COLUMN ID DROP IDENTITY;//先把表中的主键去掉
load client from 'D:\data\allExport\UI_DEPARTMENT.del' OF del modified by delprioritychar codepage=1208
replace into "APPUSER"."LIXL_UI_DEPARTMENT"(ID, NAME,SHOW_ENABLE,SORT,PARENT_ID,IF_LEAF);
SET INTEGRITY FOR LIXL_UI_DEPARTMENT ALL IMMEDIATE UNCHECKED; //为了防止DB2立即检查
call UP_SET_AUTOID('LIXL_UI_DEPARTMENT');//调用存储过程,把他设置为自增,并且起始值为当前最大
#SYNC 10;
下面是存储过程的内容
drop procedure UP_SET_AUTOID;
CREATE PROCEDURE UP_SET_AUTOID
(IN IN_TABLE VARCHAR(500)
)
SPECIFIC UP_SET_AUTOID
LANGUAGE SQL
begin
Declare strSQL VarChar(2000);
Declare senten2 VarChar(2000);
Declare intId Integer;
Declare strID VarChar(200);
Declare strTableName VarChar(500);
set strTableName = In_TABLE;
delete from LIXL_MAXID where table_name=In_TABLE;
set strSQL = 'insert into LIXL_MAXID
select '''||strTableName||''',char(Coalesce(max(ID),0)) as id
from '||strTableName;
prepare s2 From strSQL;
execute s2;
select char(Integer(MAXID)+1) into strID from LIXL_MAXID Where table_name=In_TABLE;
Set strSQL = ' Alter table '||strTableName||' alter column ID set generated always as identity(START WITH '||Rtrim(strID)||', INCREMENT BY 1 )';
prepare s2 From strSQL;
execute s2;
end;
==================================DB2迁移mysql====================================================
1.如果数据中没有int类型字段没有null的情况
直接load就可以
load data local infile 'D://data//db2导入db2//完整备份//allExport/UI_DEPARTMENT.del'
replace into table UI_DEPARTMENT ;
2.数据库中int类型字段有null值,如果用上面的方法则,会把null直接导入为0,这是mysql数据库本事的设计,没法改变
解决办法:导出为insert语句插入
自己写了一个java类,来执行insert加入,里面配置两个数据源
package lixl.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Types;
import java.util.Date;
import java.util.Properties;
public class ExportInsert {
/**
* @param args
*/
@SuppressWarnings("null")
public static void main(String[] args) {
InputStream in = ClassLoader.getSystemResourceAsStream("db-cfg.properties");
Properties p = new Properties();
String url ;
String user ;
String password ;
String driverManager;
String basePath;
String tableNames;
String url_destination ;
String user_destination ;
String password_destination ;
String driverManager_destination;
try {
p.load(in);
} catch (IOException e1) {
e1.printStackTrace();
}
url_destination = p.getProperty("destination.url");
user_destination = p.getProperty("destination.userName");
user_destination = user_destination.trim();
password_destination = p.getProperty("destination.pwd");
driverManager_destination = p.getProperty("destination.driverManager");
url = p.getProperty("DB2DB.url");
user = p.getProperty("DB2DB.userName");
password = p.getProperty("DB2DB.pwd");
driverManager = p.getProperty("DB2DB.driverManager");
basePath = p.getProperty("DB2DB.baseDir");
tableNames = p.getProperty("DB2DB.tables");
Connection conn = null;
PreparedStatement pstmt = null;
Connection conn_destination = null;
Statement pstmt_destination = null;
String[] tables = tableNames.split(",");
try {
Class.forName(driverManager);
conn = DriverManager.getConnection(url, user, password);//获取db2连接
System.out.println("开始准备数据,请等待...");
Date start = new Date();
for (int i = 0; i < tables.length; i++) {
String tableNameParm = tables[i];
String selectAll = "select * from "+tableNameParm;
pstmt = conn.prepareStatement(selectAll);
ResultSet resultSet = pstmt.executeQuery();//获得查询的结果集
int number = resultSet.getMetaData().getColumnCount();//获得表中列数目 共9列
Class.forName(driverManager_destination);
conn_destination = DriverManager.getConnection(url_destination, user_destination, password_destination);
String deleteSql = "delete from "+tableNameParm;
PreparedStatement preparedStatement = conn_destination.prepareStatement(deleteSql);
preparedStatement.execute();//插入值之前,先删除旧值
int counterNumber=0;//表中数据的记录总数计数器
pstmt_destination = conn_destination.createStatement();
while(resultSet.next()){//表中数据的每一行
counterNumber++;
StringBuffer oneTableStringBuffer = new StringBuffer();
oneTableStringBuffer.append("insert into "+tableNameParm+" values(");
for (int j = 1; j <= number; j++) {
int type = resultSet.getMetaData().getColumnType(j);//列数据类型,是个枚举
Object colVal = resultSet.getObject(j);//用getObject能获得的原本的值
if(type==Types.INTEGER){
if(colVal==null){
colVal= "null";
}
}
if(type==Types.CHAR||type ==Types.VARCHAR||type==Types.TIME||type==Types.TIMESTAMP||type==Types.DATE){
if(colVal!=null){
colVal = "\""+colVal+"\"";
}
}
if(j!=number){
oneTableStringBuffer.append(colVal+",");
}else if(j==number){
oneTableStringBuffer.append(colVal);
}
}
oneTableStringBuffer.append(");");
pstmt_destination.addBatch(oneTableStringBuffer.toString());//添加批量导入的sql(里面是一条insert语句)
}
try {
Date d1 = new Date();
pstmt_destination.executeBatch();//执行批量插入
Date d2 = new Date();
System.out.println("批量导入表"+tableNameParm+"成功=======共条"+counterNumber+"数据,耗时"+(d2.getTime()-d1.getTime())+"毫秒");
} catch (Exception e) {
System.out.println("批量导入表"+tableNameParm+"失败");
e.printStackTrace();
}
pstmt.close();
}
Date end = new Date();
System.out.println("==================数据已经全部导入新库中"+"共导出"+tables.length+"张表的数据,耗时"+(end.getTime()-start.getTime())+"毫秒"+"==========================");
//==========================下面是写文件方法把一个字符串写到一个文本中==============================
// try {
// File file = new File(basePath);
// if(!file.exists()){
// System.out.println("开始创建文件夹"+basePath);
// new File(basePath).mkdirs();
// System.out.println("创建文件夹结束");
// }
// String filePath = basePath + "\\insert.txt";
// BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(
// new File(filePath)));
// System.out.println("开始写文件"+filePath);
// bufferedWriter.write(stringBuffer.toString());
// System.out.println("文件写入成功"+filePath);
// bufferedWriter.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
================================================================================
因为该程序要在服务器上执行,而且服务器没有eclipse,不用直接运行来执行程序,需要打jar包为可执行文件xxx.jar
用eclipse直接打包
把该jar包ftp到服务器
执行下列命令:
java -jar xxxx/xxx.jar//这里是jar文件路径