db2look -d cusgadev -i db2admin -w
db2admin -e -a -o cusnew.sql
該命令用于從SIT環境中抽取最新的DDL語句。其中各選項的涵義如下: -d :指定被抽取DDL的數據庫名稱。 -e:抽取數據庫的DDL語句,包括表、視圖、自動摘要表、別名、索引、觸發器、Sequences、User defined Distinct Types、PRimary Key/RI/CHECK約束、用戶定義的結構化類型、用戶定義的函數、用戶定義的方法、用戶定義的轉換。 -i :連接遠程數據庫時,需要用這個選項指定登錄用戶名。 -w :連接遠程數據庫時,需要用這個選項指定登錄用戶的密碼。 -a:輸出所有用戶創建的對象,而不僅僅是當前登錄用戶創建的對象。 -o :將DDL輸出到指定的文件中。假如不指定該選項,則將輸出到標準輸出。 從單元測試環境取得舊數據庫的SCHEMA。在單元測試環境中,執行以下命令: db2look -d cusgadev -e -a -o cusnew.sql 該命令用于從單元測試環境中抽取最新的DDL語句。各選項的涵義見上文。 在單元單元測試環境,卸出舊數據庫的數據。在單元測試環境中,執行以下命令: db2move cusgadev export 該命令用于將單元測試環境中已有的數據輸出到當前目錄下。該命令為每一個表生成獨立的PC/IXF格式的數據文件,這些文件可以傳輸到任何其他的機器上并通過load或者import命令裝入到那臺機器上的DB2數據庫中。 該命令同時生成一個名為"db2move.lst"的文件,這個文件是卸出表的清單,指明哪一個表對應到哪一個數據文件。該文件將用于之后的步驟,以便用最新的SCHEMA卸出原有表的數據。 分析新舊數據庫SCHEMA 以下,我們使用cygwin環境下的SHELL程序來分析新舊數據庫的SCHEMA。 上一頁12345678下一頁 格式化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
", $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
}
上一頁123456789下一頁 對于僅在舊數據庫中存在的表,需要從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 (
", _tblname); #### )}
else if(isThisTable == 1)
{
if(match($0, ";") > 0)
{
isThisTable = 0;
if($1 == "in")
printf(";
", $0);
else
printf("%s
", $0);
}
else if(match($0,
"timestamp not null with default ,") > 0)
{
printf("%s timestamp not null
with default current timestamp ,
", $1);
}
else
{
printf("%s
", $0);
}
}
}' $2 > $3
}
上一頁12345678910下一頁 # 生成卸出指定表的數據的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
", $0);
}
else
{
printf("create table sihitranstmptbl (
"); # )
}
}' $2 > ${TMPSQLFILE}
# 2. 生成insert into transtmptbl (...) select ... from <oldtbl>的SQL
# 2.1. 生成新舊兩個表的字段列表
awk '{
if(NR > 1 && $1 != ";")
{
gsub(""", "", $1); # remove character "
printf("%s
", $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}
fi
done
上一頁234567891011下一頁 其中,TABLEINBOTH是由上一步(找出僅在舊庫或者新庫中獨有的表)的副產品。 注重,上述程序中,并沒有處理新舊table中均有并且字段類型不同的字段,這種情況可以在卸出數據時按需要手工編輯生成的SQL腳本。 生成的SQL腳本名稱叫"unload.sql"。在PC機上的DB2命令窗口中執行:db2 -z result.txt -tvf unload.sql
其中,"-z"選項將執行結果同時輸出到屏幕及文件result.txt中。執行結束時,需要查看result.txt,假如其中有錯誤提示,請按需要修改unload.sql。修改之后,再重新執行上述命令,直到所有SQL命令均執行無錯為止。 取得新SCHEMA的表空間名稱 通過以下步驟,找出新數據庫使用的表空間的名稱,并給出創建數據庫緩沖池及表空間的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
", $2);
if(NF > 3)
{
if($3 == "INDEX" && $4 == "IN")
{
printf("%s
", $5);
}}
}' | sort | uniq `
do
echo "CREATE TABLESPACE ${tblspace} PAGESIZE 8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81"
done
echo "-----------------------------------
---------------------------"
上一頁34567891011下一頁 執行結果類似于: 創建緩沖池的命令:create bufferpool BF81 size 10000 pagesize 8 KB。 創建表空間的命令:--------------------------------------
------------------------
CREATE TABLESPACE "DATATBS00_8K" PAGESIZE
8K MANAGED BY DATABASE USING (FILE
'<filename>' 50000) bufferpool bf81
CREATE TABLESPACE "DATATBS01_8K" PAGESIZE
8K MANAGED BY DATABASE USING (FILE
'<filename>' 50000) bufferpool bf81
CREATE TABLESPACE "DATATBS02_8K" PAGESIZE
8K MANAGED BY DATABASE USING (FILE
'<filename>' 50000) bufferpool bf81
CREATE TABLESPACE "IDXTBS00_8K" PAGESIZE
8K MANAGED BY DATABASE USING (FILE
'<filename>' 50000) bufferpool bf81
CREATE TABLESPACE "IDXTBS02_8K" PAGESIZE
8K MANAGED BY DATABASE USING (FILE
'<filename>' 50000) bufferpool bf81
CREATE TABLESPACE "STATICTBS00_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
CREATE TABLESPACE "USERSPACE1" PAGESIZE
8K MANAGED BY DATABASE USING (FILE
'<filename>' 50000) bufferpool bf81
------------------------------------
--------------------------
在實際創建表空間時,需要將其中的""替換成Windows系統下的一個文件名稱,每一個表空間使用不同的文件名。也可以根據對數據庫中數據分布的估計,調整表空間的大小。 上一頁4567891011下一頁 重建數據庫 按以下步驟重建數據庫: 1、編輯db2move.lst,刪除在新庫中已不使用的表。 根據上述步驟中得到的僅在舊數據庫中存在的表,編輯db2move.lst,刪除該表所在的行。 2、刪除舊數據庫。 執行以下命令,刪除舊數據庫:db2 drop database cusgadev 3、創建數據庫,執行以下命令,創建新數據庫: db2 create database cusgadev using codeset iso8859-1 territory cn 其中,"iso8859-1"表示數據庫使用的字符集,"cn"表示數據庫使用的地域。 4、連接數據庫:執行以下命令,連接新數據庫:db2 connect to cusgadev 5、修改物理日志參數,執行以下命令,修改數據庫的日志參數: db2 update database configuration using logfilsiz 25000 deferred 創建數據時,默認的日志空間比較小,對于大事務的處理有影響,所以,需要根據應用的需要及PC機的配置適當調整日志空間的值。 可以使用"GET DATABASE CONFIGURATION"命令查看數據庫的當前配置。 6、創建緩沖池,執行以下命令,為數據庫創建緩沖池:db2 create bufferpool BF81 size 10000 pagesize 8 K。 7、創建表空間,執行以下命令,為數據庫創建表空間:db2 CREATE TABLESPACE "DATATBS00_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
db2 CREATE TABLESPACE "DATATBS01_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
db2 CREATE TABLESPACE "DATATBS02_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
db2 CREATE TABLESPACE "IDXTBS00_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
db2 CREATE TABLESPACE "IDXTBS02_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
db2 CREATE TABLESPACE "STATICTBS00_8K" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
db2 CREATE TABLESPACE "USERSPACE1" PAGESIZE
8K MANAGED BY DATABASE USING
(FILE '<filename>' 50000) bufferpool bf81
上一頁567891011下一頁 其中,tablespace的名稱是從新數據庫的SCHEMA文件中提取出來的。本例中,它們都使用同一個緩沖池。""需要按照PC機硬盤空余空間的情況,修改為實際的全路徑文件名稱。 8、用新的SCHEMA創建數據庫: 執行以下命令,按照新數據庫的SCHEMA創建其中的各種對象,如表、索引等:db2 -tvf cusnew.sql。 9、裝入數據,執行以下命令,將舊數據庫的數據裝入到剛創建的新數據庫中:db2move cusgadev load。 該命令使用的修改后的db2move.lst作為裝入表的清單。 有選擇的將新庫中獨有的表的數據導入到本地新數據庫中對于僅在新數據庫中存在的表,可以根據需要有選擇的將其數據從SIT環境導入到單元測試環境。本文中,不考慮新表對于其他表的外鍵關聯。 假設某個僅在新數據庫中存在的表的名稱為"newtable",在SIT環境執行以下命令卸出數據: db2 unload to newtable.ixf of ixf select * from newtable。將文件“newtable.ixf”傳輸到單元測試環境所在的PC機上,執行以下命令:db2 load from newtable.ixf of ixf insert into newtable。假如這個新表對于其他表有外鍵關聯,還需要導入其他相關表的數據。 檢查數據庫的完整性 檢查完整性的SHELL程序以下是"CheckIntegrity.sh"的源代碼。該程序用于在數據load結束以后,檢查數據庫的完整性。#!/usr/bin/sh
# 在數據load結束后,檢查數據庫的完整性
# Copyright: SI HITECH 2006
# 作 者: 鄭靖華
# 創建日期: 2006 年 8 月 2 日
# 指定數據庫名稱
if [ $# -lt 1 ]
then
DBNAME=ccdb
else
DBNAME=$1
fi
# 檢查db2move的lst文件
if [ ! -r db2move.lst ]
then
echo "當前目錄下沒有db2move的清單文件
[ db2move.lst ],請確保目錄正確并再次執行本命令!"
exit 1
fi
# 生成執行完整性檢查的SHELL程序
awk -F"!" -v_dbname=${DBNAME} 'BEGIN{
printf("connect to %s;
", _dbname);
}{
printf("set integrity for %s immediate checked;
", $2);
}' db2move.lst > $DBNAME.integrity.sql
# 執行檢查程序
db2 -tvf $DBNAME.integrity.sql
echo "完整性檢查完畢,請仔細查看檢查結果!"
exit 0
上一頁67891011下一頁 新聞熱點
疑難解答