1.背景知识
有些情况下我们需要跨字符集进行表的迁移
。
比如 ZHS16GBK->AL32UTF8
在存储中文时两个字符集有如下差异
字符集 | 中文字符占用字节 | 以汉字存储性别 |
---|---|---|
ZHS16GBK | 2 | char(2) |
AL32UTF8 | 3 | char(3) |
那么当把一个包含字段 char(2),varchar2(10) 的表从ZHS16GBK 迁移到 AL32UTF8 时,可能就会遇到字段长度不足的报错。
这时就要用到 csscan
工具,该工具oracle 自带,位于$ORACLE_HOME/bin
目录
csscan 用法示例:
基于用户:
csscan userid=cym/cym user=cym tochar=AL32UTF8 ARRAY=20480000 process=4 SUPPRESS=0基于表:
csscan userid=cym/cym table=cym.cym1,cym.cym2 tochar=AL32UTF8 ARRAY=20480000 process=4 SUPPRESS=0
- process 并行数
- suppress 不记录迁移失败的数据行
扫描结果包含3个文件:
scan.err scan.out scan.txt
scan.err
包含了要处理的表字段及变更放法,如果要变更的字段很多,这个文件会很大,人工处理耗时耗力且可能遗漏。于是就想要写个脚本实现对 scan.err
文件的处理。
csprocess.sh
#!/bin/bash
############################################
# csprocess.sh
# 用途说明:
# 用来处理 csscan 得到的 .err 文件
# 用法示例:
# sh csprocess.sh scan.err
#
if [ ! $1 ];then
file=scan.err
else
file=$1
fi
i=1
grep ':' $file | grep -E '^User|^Table|^Column|^Type|^Max' | awk -F ':' '{print $2}' | while read line
do
if [ $i -eq 1 ];then
v1='ALTER TABLE '$line
elif [ $i -eq 2 ];then
v2='.'$line
elif [ $i -eq 3 ];then
v3=' MODIFY '$line' '
elif [ $i -eq 4 ];then
v4=`echo $line|awk -F '(' '{print $1}'`
elif [ $i -eq 5 ];then
echo $v1$v2$v3$v4'('$line');' >> cs.sql
i=0
fi
((i++))
done
2.测试演示
- 建表
create table cym1(id number,gender char(2),mark varchar2(10));
create table cym2(id number,gender char(6),mark varchar2(10));
create table cym3(id number,gender char(2),mark varchar2(16));
insert into cym1 values(1111,'男','我爱你中国');
insert into cym2 values(1111,'male','IloveChina');
insert into cym3 values(1111,'男','我爱你中国');
commit;
- csscan 扫描
[oracle@BServer007 test]$ csscan userid=cym/cym table=cym.cym1,cym.cym2,cym.cym3 tochar=AL32UTF8 ARRAY=20480000 process=4 SUPPRESS=0
[oracle@BServer007 test]$ ls
csprocess.sh scan.err scan.out scan.txt
- 获取变更SQL
[oracle@BServer007 test]$ sh csprocess.sh
[oracle@BServer007 test]$ ls
csprocess.sh cs.sql scan.err scan.out scan.txt
[oracle@BServer007 test]$ cat cs.sql
ALTER TABLE CYM.CYM1 MODIFY MARK VARCHAR2(15);
ALTER TABLE CYM.CYM3 MODIFY GENDER CHAR(3);
ALTER TABLE CYM.CYM1 MODIFY GENDER CHAR(3);
数据迁移方案推荐
- 调整原库的表字段长度。(不推荐)
- 先迁移元数据,目标端根据获得的脚本调整完字段后再单独迁移数据。(推荐)
补充:case 写法
经测试,效率上两种写法基本无差异
#!/bin/bash
############################################
# csprocess.sh
# 说明:
# 用来处理 csscan 得到的.err 文件
# 用法示例:
# sh csprocess.sh scan.err
#
if [ ! $1 ];then
file=scan.err
else
file=$1
fi
i=1
grep ':' $file | grep -E '^User|^Table|^Column|^Type|^Max' | awk -F ':' '{print $2}' | while read line
do
case $i in
1) v1='ALTER TABLE '$line ;;
2) v2='.'$line ;;
3) v3=' MODIFY '$line' ' ;;
4) v4=`echo $line|awk -F '(' '{print $1}'` ;;
5) echo $v1$v2$v3$v4'('$line');' >> cs.sql;
i=0 ;;
esac
((i++))
done