目录
1简介... 1
2 准备... 1
2.1 环境说明... 1
3 安装... 2
4 配置... 2
5 使用... 2
5.1 验证实验... 2
5.2 问题分析... 4
6 延展... 5
7 总结... 5
Mysql迁移到Oracle方法
基于mysql select into outfile的方式导出文本文件并结合sqlldr导入数据到oracle里
1 mysql版本10.3.13-MariaDB,同理其它mysql版本效果类似。
-- 查看mysql版本
SELECT VERSION() AS mysql_Version;
mysql_Version |
10.3.13-MariaDB |
-- mysql 字符集
show variables like '%char%';
Variable_name |
Value |
character_set_client |
utf8 |
character_set_connection |
utf8 |
character_set_database |
utf8 |
character_set_filesystem |
binary |
character_set_results |
|
character_set_server |
utf8 |
character_set_system |
utf8 |
character_sets_dir |
E:\Program Files\MariaDB 10.3\share\charsets\ |
2 oracle版本为11gR2,同理其它版本效果类似。
--查看数据库版本
SELECT * FROM v$version;
BANNER |
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production |
PL/SQL Release 11.2.0.4.0 - Production |
"CORE 11.2.0.4.0 Production" |
TNS for Linux: Version 11.2.0.4.0 - Production |
NLSRTL Version 11.2.0.4.0 - Production |
--查看字符集
SELECT * FROM v$nls_parameters where parameter='NLS_CHARACTERSET';
PARAMETER |
VALUE |
NLS_CHARACTERSET |
AL32UTF8 |
无.
无
1) 通过mysql的 select into outfile的方式拼接SQL生成导出txt的语句。并将生成出来的sql语句拷贝出来并保存成export.sql
SELECT
CONCAT('SELECT ',
group_concat('IFNULL(',COLUMN_NAME,','''')'),
' into outfile "\/var\/lib\/mysql-files\/tmp\/data\/',
table_name,
'.txt','" fields terminated by "\\t" lines terminated by ''\\r\\n'' from test.',table_name,';')
from information_schema.`COLUMNS`
WHERE TABLE_schema = 'test'
GROUP BY TABLE_NAME
注:
2) 通过mysql <的方式执行外部的sql文件,这里可以将该命令封装在shell里
#! /bin/sh
mysql -uroot -ppasswd -Dtest<'/var/lib/mysql-files/tmp/export.sql' 1>/tmp/log.log
3) 如果oracle和mysql不在一台服务器上,那么需要通过命令将txt文件拷贝到oracle服务器里。如果在一台服务器上,则忽略这个操作。
scp -r /var/lib/mysql-files/tmp/data/*.txt [email protected]:/root/script/data/
4) 通过sql拼出sqlldr的ctl文件,拷贝执行出来的内容到imp.txt里
select concat('load data','\r','characterset utf8','\r','INFILE ''\/root\/script\/data\/',table_name,'.txt''','\r','Append into table ',table_name,'\r','fields terminated by '"'\\t'"'','\r','trailing nullcols','\r','(','\r',
group_concat(COLUMN_NAME),
');'
)
from information_schema.`COLUMNS`
WHERE table_schema in('test')
GROUP BY TABLE_NAME
5) 通过python代码按照“;”拆分成ctl文件。
import os
def splitFile(fileIn,dirOut):
file1 = open(fileIn, 'r', encoding='utf-8')
try:
str=""
for line in file1.readlines():
if line.find('.') >0:
fileName=line.split('/')[-1].replace('txt\'','ctl').strip("\n")
print(fileName)
file2 = open(dirOut + '\\' + fileName, 'w', encoding='utf-8')
str=str+" "+line
if line[-2]==";":
#line = line.strip("\n")
###print(str);
file2.write(str.replace(";",'').replace("GXSJC","GXSJC date \"yyyy-mm-dd hh24:mi:ss\""))
str = ""
file2.close()
finally:
file1.close()
if __name__ == '__main__':
splitFile(r'D:\temp\imp.txt',r'D:\temp\impCtls')
6) 生成sqlldr执行脚本,将SQL拼接里的内容拷贝出到Imp.sh内。
select concat('sqlldr userid=test/passwd@Instance rows=500000 bindsize=30720000 control=/root/script/ctl/' ,table_name )
from information_schema.tables where table_schema='test';
7) 运行Imp.sh并结合log文件对错误进行分析。
可能的时间格式 date 'yyyy-mm-dd hh24:mi:ss',此操作可以在ctl文件里修改,即对应的字段后面加上时间格式转换,如:
Col_name date 'yyyy-mm-dd hh24:mi:ss'
4. Field in data file exceeds maximum length;
这种错误可能是字段里含有中文字符,解决方法,在ctl里对有问题的字段,后面加char(4000)转换,如:
Col_name char(4000)
5. ORA-01722: invalid number;
这种错误可能是因为当前表的最后一个字段是数值型的且当前导出的数据行分隔符是\r\n,即回车换行。
解决方法,导出的txt的行分隔符换成\n
6.导入时出现字段和记录对不上的问题
可能的情况是字段里含有行分隔符\r\n,处理方法是换个行分隔符或者对出错的字段替换\r\n,即
REPLACE(REPLACE(char(13),''),CHAR(10),'')
无
暂无.有问题可以咨询如下: