写在前面
数据迁移并不是,只靠工具的,目前发现的问题是 oracle 的 date 类型是指 mysql 的 date 和 datetime 的综合,
而迁移过来,mysql都会变成 datetime 类型, 也就是会在日期后面补 “00:00:00”, 还有的表结构迁移不过来,应该是数据类型转换不了的问题,这个也要实际去观察,好在是执行完成的有标志,也有日志打印,可以根据日志,从断掉的重新开始。
注释,存储,视图,索引 目前没发现是否可以迁移。
注释迁移可以根据下面自己实现, 现实方法在最后。
配置环境
在 kettle 的 bin 目录下放入 mysql 和 oracle jdbc jar 包
oracle: ojdbc8
mysql: mysql-connector-java
1.迁移表结构与表数据
创建一个转换
新建 oracle 和 mysql 链接
oracle 链接
mysql 链接
表结构迁移
选择你要迁移的表
创建一个 job 名称,选择存放路径
得到
这个是创建表和倒入数据,如果我们需要数据的话,直接点击红框的执行按钮即可,如果只要到表结构的话,需要删除和链接节点,我们选中我们不需要的线然后,点击链接线,线会变成灰色。按着 shift 可以创建链接线,这样就可以只生成表结构了。
2.迁移 oracle 查询语句的数据到 mysql 已存在的表结构中
我们回到 转换1 的窗口,有个核心对象
在 输入 里面有个表输入,双击表输入
在 输出 里面有个表输出,双击表输出
双击表输入 -- 选择数据库,写你想到的 sql 语句,注意,不要加“;”, 可以点击预览看看是否是你想要的数据
双击表输出 -- 选择数据库,和你想倒入的表名
点击执行既可以看到数据迁移。
注释迁移
select * from user_tab_comments -- 查询表注释,(包括试图)
select * from user_col_comments -- 查询字段注释
我们在 mysql 里面建两个表,用 kettle 把这些数据迁移到 mysql 新建的两个表中。
然后写一个存储过程
CREATE DEFINER=`root`@`localhost` PROCEDURE `update_comments`(
v_schema VARCHAR(100),
v_type VARCHAR(100),
v_table_name VARCHAR(100)
)
BEGIN
if v_table_name is null THEN
if v_type = 'tab' or v_type is null THEN
BEGIN
DECLARE stmt VARCHAR(5000);
DECLARE done int DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR not found set done = true;
BEGIN
DECLARE my_cursor CURSOR for(
SELECT
CONCAT('ALTER TABLE ', v_schema, '.', table_name, ' COMMENT = "', comments, '"')
FROM
dba_tab_comments_table
WHERE
comments is not null
);
OPEN my_cursor;
team_loop:loop
FETCH my_cursor into stmt;
if done then leave team_loop;
end if;
if stmt is not null then
set @sql = stmt;
prepare v_statement from @sql;
EXECUTE v_statement;
DEALLOCATE PREPARE v_statement;
end if;
end loop team_loop;
CLOSE my_cursor;
END;
END;
end if;
if v_type = 'col' or v_type is null THEN
BEGIN
DECLARE stmt VARCHAR(5000);
DECLARE done int DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR not found set done = true;
BEGIN
DECLARE my_cursor CURSOR for(
SELECT
CONCAT('ALTER TABLE ', v_schema, '.', d.table_name, ' COMMENT COLUMN ', d.column_name, ' ', i.COLUMN_TYPE, ' COMMENT "', d.comments, '"')
FROM
dba_col_comments d
LEFT JOIN information_schema.`COLUMNS` i
ON d.table_name = i.COLUMN_NAME
WHERE
i.table_schema = v_schema
and i.column_type is not null
);
OPEN my_cursor;
team_loop:loop
FETCH my_cursor into stmt;
if done then leave team_loop;
end if;
if stmt is not null then
set @sql = stmt;
prepare v_statement from @sql;
EXECUTE v_statement;
DEALLOCATE PREPARE v_statement;
end if;
end loop team_loop;
CLOSE my_cursor;
END;
END;
end if;
ELSE
if v_type = 'tab' or v_type is null THEN
BEGIN
DECLARE stmt VARCHAR(5000);
DECLARE done int DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR not found set done = true;
BEGIN
DECLARE my_cursor CURSOR for(
SELECT
CONCAT('ALTER TABLE ', v_schema, '.', table_name, ' COMMENT = "', comments, '"')
FROM
dba_tab_comments_table
WHERE
comments is not null
and table_name = v_table_name
);
OPEN my_cursor;
team_loop:loop
FETCH my_cursor into stmt;
if done then leave team_loop;
end if;
if stmt is not null then
set @sql = stmt;
prepare v_statement from @sql;
EXECUTE v_statement;
DEALLOCATE PREPARE v_statement;
end if;
end loop team_loop;
CLOSE my_cursor;
END;
END;
end if;
if v_type = 'col' or v_type is null THEN
BEGIN
DECLARE stmt VARCHAR(5000);
DECLARE done int DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR not found set done = true;
BEGIN
DECLARE my_cursor CURSOR for(
SELECT
CONCAT('ALTER TABLE ', v_schema, '.', d.table_name, ' COMMENT COLUMN ', d.column_name, ' ', i.COLUMN_TYPE, ' COMMENT "', d.comments, '"')
FROM
dba_col_comments d
LEFT JOIN information_schema.`COLUMNS` i
ON d.table_name = i.COLUMN_NAME
WHERE
i.table_schema = v_schema
and i.column_type is not null
and d.table_name = v_table_name
);
OPEN my_cursor;
team_loop:loop
FETCH my_cursor into stmt;
if done then leave team_loop;
end if;
if stmt is not null then
set @sql = stmt;
prepare v_statement from @sql;
EXECUTE v_statement;
DEALLOCATE PREPARE v_statement;
end if;
end loop team_loop;
CLOSE my_cursor;
END;
END;
end if;
end if;
END;
根据自己的需求,执行存储过程即可。
迁移索引
oracle导出用户下所有索引sql
Select dbms_metadata.get_ddl('INDEX', INDEX_NAME)||';' from usr_indexes;
导出查询结果至CSV文件。
修改导出sql
将sql中多余部分全部注释
(
PCTFREE
STORAGE
PCTINCREASE
BUFFER_POOL
TABLESPACE
)
批量删除oracle 数据库前缀字段 如 (“DSM”.)
导入mysql
将修改后的sql 复制到 mysql访问工具中 执行。
备注:
Msyql 创建索引语句:
create index index_name on table_name(column_name);
Oracle创建索引语句
create index 索引名 on 表名(列名);