格式化SCHEMA文件
为了比较新旧数据库的SCHEMA,我们需要将两个SCHEMA文件转换成统一格式,包括:将所有大写替换成小写;删除所有行首的空格;将多个空格合并成1个空格。其中,空格包括制表符(Tab)和空格字符(Space)。
使用以下命令组合格式化SCHEMA文件:
sed -e "s/^[ ]*//" \ -e "s/[ ][ ]*/ /g" \ ${OLDDBSCHEMA} | tr [:upper:] [:lower:] > ${OLDDBSCHEMATMP} |
取得新旧数据库的table清单
定义如下函数,从数据库的SCHEMA文件中取得其中的table清单。这个函数适用于由db2look生成的、DB2数据库的DDL文件。
# 根据数据库的SCHEMA文件,取得其中的table清单# $1. 数据库的SCHMEA文件# $2. 输出的table清单文件gettbllist(){ grep -i "^[ ]*create[ ][ ]*table" $1 > $2.tmp sed -e "s/^[ ]*CREATE[ ][ ]*TABLE//" \ -e "s/(.*$//" \ $2.tmp | sort > $2 rm $2.tmp} |
找出仅在旧库或者仅在新库独有的表
定义如下函数,取出仅在指定数据库SCHEMA中存在的table的清单。这个函数适用于由db2look生成的、DB2数据库的DDL文件。
# 取出仅在第一个参数指定的数据库SCHEMA中存在的表的名称清单# $1: 待分析的数据库SCHEMA文件# $2: 用作参照的数据库SCHEMA文件# $3: 屏幕输出的提示信息gettableonlyinone(){ if [ $# -eq 3 ] then echo $3 fi TABLEINBOTH="" for tblname in `awk -F"." '{printf("%s\n", $2);}' $1 | awk -F"\"" '{printf("%s ", $2)}' | sort` do grep -i "\"$tblname\"" $2 1>/dev/null 2>&1 if [ ! $? -eq 0 ] then if [ $# -eq 3 ] then echo $tblname fi else TABLEINBOTH="${TABLEINBOTH} ${tblname}" fi done} |
对于仅在旧数据库中存在的表,需要从db2move.lst中删除该表对应的行。
对于仅在新数据库中存在的表,需要根据需要有选择的从新数据库中卸出数据并装入到新数据库中。
找出结构不同的表,并生成卸出数据的SQL脚本
通过以下步骤,找到在新旧数据库中都存在,并且结构发生了变化的table,并生成重新卸出数据的SQL语句。
# 根据数据库的SCHEMA文件,取得指定table的SCHEMA# $1: table名称# $2: 数据库的SCHEMA文件,需要先做格式化# $3: 输出的表的SCHEMA文件gettableschema(){ #echo "table name: " $1 #echo "dbschema name: " $2 #echo "outfile name: " $3 awk -v_tblname=$1 'BEGIN{isThisTable = 0;}{ if($1 == "create" && $2 == "table" && match($0, "\""_tblname"\"") > 0) { isThisTable = 1; printf("create table %s (\n", _tblname); #### ) } else if(isThisTable == 1) { if(match($0, ";") > 0) { isThisTable = 0; if($1 == "in") printf("; \n", $0); else printf("%s\n", $0); } else if(match($0, "timestamp not null with default ,") > 0) { printf("%s timestamp not null with default current timestamp , \n", $1); } else { printf("%s\n", $0); } } }' $2 > $3}# 生成卸出指定表的数据的SQL脚本# $1. 旧数据库的SCHEMA文件# $2. 新数据库的SCHEMA文件# $3. 输出的卸出指定表的数据的SQL脚本文件名# $4. 指定的表名# $5. db2move卸出文件时的清单文件genunloadsql(){ TMPSQLFILE=.tmpsql.sql.sql TMPNEWTBLFLD=.tmpfld.fld.fld rm -f ${TMPSQLFILE} # 1. 用新的表结构创建一个临时表 awk '{ if(NR > 1) { gsub("\"", "", $1); # remove character " printf("%s\n", $0); } else { printf("create table sihitranstmptbl (\n"); # ) } }' $2 > ${TMPSQLFILE} # 2. 生成insert into transtmptbl (...) select ... from <oldtbl>的SQL # 2.1. 生成新旧两个表的字段列表 awk '{ if(NR > 1 && $1 != ";") { gsub("\"", "", $1); # remove character " printf("%s\n", $1); } }' $2 > ${TMPNEWTBLFLD} isFirstFeild=1 Select="" Into="" for fldname in `cat ${TMPNEWTBLFLD}` do grep "\"${fldname}\"" $1 1>/dev/null 2>&1 if [ $? -eq 0 ] then # 2.2. 取出在新旧两表中都有的字段名,加入到select子句和into子句中 if [ ${isFirstFeild} -eq 0 ] then Select="${Select}," Into="${Into}," fi Select="${Select} ${fldname}" Into="${Into} ${fldname}" isFirstFeild=0 else # 2.3. 取出仅在新表中出现的字段,如果该字段不允许null, # 且没有设置default值,则按以下原则取默认值放到select子句中, # 并将字段名放到into子句中 grep "\"${fldname}\"" $2 | grep "not null" 1>/dev/null 2>&1 if [ $? -eq 0 ] then grep "\"${fldname}\"" $2 | grep "with default" 1>/dev/null 2>&1 if [ ! $? -eq 0 ] then if [ ${isFirstFeild} -eq 0 ] then Select="${Select}," Into="${Into}," fi # 计算默认值 # 对于新增的字符型字段,默认值为''; # 对于新增的数值型字段,默认值为0; # 对于新增的TIMESTAMP字段,默认值为''; # 对于新增的SERIAL开字段,默认值为0; # 对于新增的DATE字段,默认值为; # 对于新增的DATETIME字段,默认值为; Const=`grep "\"${fldname}\"" $2 | awk '{ if(match($2, "int") > 0) # integer, smallint, bigint printf("0"); else if(match($2, "numeric") > 0) printf("0.0"); else if(match($2, "decimal") > 0) printf("0.0"); else if(match($2, "double") > 0) printf("0.0"); else if(match($2, "float") > 0) printf("0.0"); else if(match($2, "real") > 0) printf("0.0"); else if(match($2, "char") > 0) # char, varchar printf("\" \""); else if($2 == "timestamp") printf("current timestamp"); else if($2 == "date") printf("current date"); else if($2 == "time") printf("current time"); else printf("\" \""); }'` Select="${Select} ${Const}" Into="${Into} ${fldname}" isFirstFeild=0 fi fi fi done tablefullname=`grep -i "\"$4\"" $5 | awk -F"!" '{printf("%s", $2);}'` echo "insert into sihitranstmptbl (${Into}) select ${Select} from ${tablefullname} ;" >> ${TMPSQLFILE} # 3. 将临时表中的数据导出到文件中 Unloadfile=`grep -i "\"$4\"" $5 | awk -F"!" '{printf("%s", $3);}'` echo "export to ${Unloadfile} of ixf select * from sihitranstmptbl ;" >> ${TMPSQLFILE} # 4. 删除临时表 echo "drop table sihitranstmptbl ;" >> ${TMPSQLFILE} cat ${TMPSQLFILE} >> $3 rm -f ${TMPSQLFILE} rm -f ${TMPNEWTBLFLD}}echo "table in both database:"TABLEINBOTH="`echo ${TABLEINBOTH} | tr [:upper:] [:lower:]`"echo > ${UNLOADSQLFILE}for tblname in ${TABLEINBOTH}do gettableschema ${tblname} ${OLDDBSCHEMATMP} ${OLDTBLSCHEMA} gettableschema ${tblname} ${NEWDBSCHEMATMP} ${NEWTBLSCHEMA} diff ${OLDTBLSCHEMA} ${NEWTBLSCHEMA} 1>/dev/null 2>&1 if [ ! $? -eq 0 ] then # 如果有不同,则生成卸出数据的SQL脚本 echo "different table:" ${tblname} genunloadsql ${OLDTBLSCHEMA} ${NEWTBLSCHEMA} ${UNLOADSQLFILE} ${tblname} ${DB2MOVELISTFILE} else echo "same table:" ${tblname} fidone |
其中,TABLEINBOTH是由上一步(找出仅在旧库或者新库中独有的表)的副产品。
注意,上述程序中,并没有处理新旧table中均有并且字段类型不同的字段,这种情况可以在卸出数据时按需要手工编辑生成的SQL脚本。
生成的SQL脚本名称叫"unload.sql"。在PC机上的DB2命令窗口中执行:
db2 -z result.txt -tvf unload.sql |
其中,"-z"选项将执行结果同时输出到屏幕及文件result.txt中。执行结束时,需要查看result.txt,如果其中有错误提示,请按需要修改unload.sql。修改之后,再重新执行上述命令,直到所有SQL命令均执行无错为止。
通过以下步骤,找出新数据库使用的表空间的名称,并给出创建数据库缓冲池及表空间的SQL的建议。
# 8. 根据新数据库SCHEMA文件取得tablespace的名称清单# 并给出创建缓冲池及tablespace的SQL建议echo "创建缓冲池的命令: "echo "create bufferpool BF81 size 10000 pagesize 8 K"echo "创建表空间的命令: "echo "--------------------------------------------------------------"for tblspace in ` grep -i "^[ ]*in[ ]" ${NEWDBSCHEMA} | grep ";" | awk '{ printf("%s\n", $2); if(NF > 3) { if($3 == "INDEX" && $4 == "IN") { printf("%s\n", $5); } } }' | sort | uniq `do echo "CREATE TABLESPACE ${tblspace} PAGESIZE 8K MANAGED BY DATABASE USING (FILE '<filename>' 50000) bufferpool bf81"doneecho "--------------------------------------------------------------" |
执行结果类似于:
创建缓冲池的命令:
create bufferpool BF81 size 10000 pagesize 8 K |
创建表空间的命令:
--------------------------------------------------------------CREATE TABLESPACE "DATATBS00_8K" PAGESIZE 8K MANAGED BY DATABASE USING (FILE'<filename>' 50000) bufferpool bf81CREATE TABLESPACE "DATATBS01_8K" PAGESIZE 8K MANAGED BY DATABASE USING (FILE'<filename>' 50000) bufferpool bf81CREATE TABLESPACE "DATATBS02_8K" PAGESIZE 8K MANAGED BY DATABASE USING (FILE'<filename>' 50000) bufferpool bf81CREATE TABLESPACE "IDXTBS00_8K" PAGESIZE 8K MANAGED BY DATABASE USING (FILE'<filename>' 50000) bufferpool bf81CREATE TABLESPACE "IDXTBS02_8K" PAGESIZE 8K MANAGED BY DATABASE USING (FILE'<filename>' 50000) bufferpool bf81CREATE TABLESPACE "STATICTBS00_8K" PAGESIZE 8K MANAGED BY DATABASE USING(FILE '<filename>' 50000) bufferpool bf81CREATE TABLESPACE "USERSPACE1" PAGESIZE 8K MANAGED BY DATABASE USING (FILE'<filename>' 50000) bufferpool bf81-------------------------------------------------------------- |
在实际创建表空间时,需要将其中的"<filename>"替换成Windows系统下的一个文件名称,每一个表空间使用不同的文件名。也可以根据对数据库中数据分布的估计,调整表空间的大小。
本文:http://www.qqread.com/db2/d307987.html相关专题
- DB2 (428篇文章)
- DB2中的数据处理 (474篇文章)
- 数据库专栏 (5163篇文章)
- 数据库处理专题 (8684篇文章)
- 城域网专题 (7833篇文章)
- 数据库安全技术专题 (13169篇文章)
- 数据库安装与卸载 (10543篇文章)
- Linux数据库宝典 (13157篇文章)
- SQL server 复制 (57篇文章)
- 数据库相关文章 (5163篇文章)
- 利用VS2005构建针对DB2的应用程序和Web站点 (0次浏览)
- 聚焦 DB2 的XML能力 (0次浏览)
- 教你提高商业智能环境中的DB2查询性能 (0次浏览)
- 用DB2 VS2005 .Net插件进行XML数据验证 (0次浏览)
- 针对VS2005 的IBM数据库插件概述 (0次浏览)
- DB2 “Viper 2”助力IT敏捷性 (0次浏览)
- DB2和Visual Studio .NET开发慨述 (0次浏览)
- 在WebLogic集群环境中使用DB2 Alphablox (0次浏览)
- Oracle与DB2、MySQL取前10条记录的对比 (0次浏览)



