在針對 DB2 存儲過程的開發中,您是否覺得 DB2 提供的開發工具雖然功能強大,但是執行速度較慢,稍顯笨重,而我們的日常開發中僅僅使用了一些比較常用的功能。你是否覺得雖然其工具操作起來比較直觀,但是在處理大量創建、修改操作或者重復執行一些操作時就會比較費時?是否感覺使用其工具,無法方便的記錄跟蹤我們執行過的操作?如果您有上述的問題,本文會給您提供一個解決辦法——使用 Windows 腳本進行 DB2 存儲過程開發。腳本通常執行速度快捷,靈活;善於處理批量操作;以文本格式編寫的腳本也方便我們查看具體我們執行了哪些操作。腳本的特點恰恰幫助我們解決了剛剛提到的問題。
本文主要討論使用 Windows 腳本與 DB2 交互的一些常用技巧和方法。介紹了利用 Windows 的腳本(批處理程序)連接數據庫,查詢表結構,UDF之間的引用關系,存儲過程中使用了哪些表等等。同時通過一個演示項目的開發過程的介紹來展示如何使用文中的腳本進行開發。
背景知識簡介
Windows 腳本常用命令
Windows 腳本也稱之為批處理程序,是一個包含了一些需要順序執行的 Windows 命令的文本文件,其擴展名為 bat 或 cmd。由於本文的腳本需要傳入參數,讀者需要在控制台中執行本文提供的 Windows 腳本。
下面是 Windows 中的一些常用命令和符號。這裡僅僅列出一些說明,如果想了解 Window 命令的詳細信息,請參考本文提供的參考資料。
REM:行注釋命令,它不會被執行,只是起一個注釋的作用,便於代碼的閱讀和維護;
ECHO:命令主要參數有 OFF 和 ON,用於控制是否在控制台上顯示正在執行的命令。也可以使用 ECHO message 來顯示一個特定的消息;
GOTO: 即為跳轉的意思。在腳本中以“:XXX”構建一個標號然後用GOTO XXX 來執行標號後的命令;
CALL: 命令用於在主腳本執行過程中調用子腳本,當子腳本執行完畢後再繼續執行主腳本。如果我們不使用 CALL 來調用子腳本,而是在主腳本中直接調用子腳本,那麼被調用的子腳本執行完畢,也就表示主腳本執行的完畢,主腳本後續的命令將不會被執行;
PAUSE: 暫時停止腳本的執行;
PROMPT: 修改命令提示符。PROMPT [text]。text 表示新的提示符。 $P 代表當前路徑,$G 代表 >;
START:打開一個新的窗口執行某個命令。如果 START 後面跟的是一個文件名,那麼 Windows 會調用打開該種文件的程序將其打開。例如,如果你設定 notepad(記事本)為 *.log 文件的打開程序。那麼執行 START my.log 命令後,Windows 會啟動 notepad(記事本)程序,並且打開 my.log 文件;
符號(@):@ 符號可以關閉當前命令行的回顯。我們從上面知道用命令 echo off 可以關掉整個批處理的命令回顯但卻不能不顯示 echo off 這個命令。現在我們在這個命令前加上 @,這樣 echo off 這一命令就被 @ 關閉了回顯,從而達到所有命令均不回顯的要求;
管道(輸出重定向)命令 > 和 >>:將命令輸出的結果重定向到特定文件中, > 與 >> 的區別在於,> 會清除文件中原來的內容,然後把輸出結果寫入文件,而 >> 只會追加內容到文件中,而不會改動其中原有的內容;
Windows 腳本參數:我們可以向腳本傳遞參數,並且可以在腳本中通過 %n 來引用。腳本每次能處理的變量從 %0~%9 共 10 個。其中 %0 默認為批處理的文件名。
DB2 CLP 簡介
DB2 Command Line Processor(DB2 CLP)是所有 DB2 產品中都有的,可以使用這個應用程序運行 DB2 命令、操作系統命令或 SQL 語句。DB2 CLP 可以成為強大的工具,因為它能夠將經常使用的命令或語句序列存儲在批處理文件中,可以在必要的時候運行這些批處理文件。在 Windows 系統中,必須先(從普通命令窗口)運行 db2cmd 命令來啟動 DB2 命令行環境。
在什麼時候使用本文介紹的腳本?
腳本的優勢在於可以重復執行。如果一個任務會被執行多次,或者被多人執行。那麼將該任務編寫成腳本會提高任務的執行效率和准確性。本文介紹的腳本都是一些在我們進行存儲過程開發和調試中經常用到的。讀者在後面會漸漸體會到腳本給我們帶來的便利。
DB2 系統表的功能
編寫針對 DB2 的腳本,我們需要首先了解 DB2 為我們提供了哪些命令和信息。DB2 為我們提供了大量的命令例如連接數據庫,執行一個 SQL 文件,獲得表結構的信息等等。我們會在下面解釋具體的腳本的同時對一些簡單的 DB2 命令進行解釋說明。同時,DB2 把數據庫對象的很多信息都存儲到了系統表中。熟悉這些系統表就能夠通過 SQL 語句獲得我們需要的信息。下面我們先來學習一下 DB2 系統表。
在 DB2 數據庫被創建的時候,DB2 會創建一些系統表。這些系統表中記錄了所有數據庫對象的信息,表或視圖的列的數據類型,約束的定義,對象的權限和對象之間的依賴關系等。這些系統表的模式為 SYSIBM,其表名以 SYS 作為前綴。例如: SYSTABLES、SYSVIEWS 等等。DB2 為這些系統表建立了相對應的只讀視圖。這些視圖的模式是 SYSCAT,它們的內容是其相對應的系統表的全部或者部分內容。這些視圖的名字沒有 SYS 的前綴。例如:SYSCAT.TABLES 是 SYSIBM.SYSTABLES 的視圖。
我們可以通過 LIST TABLES FOR SYSTEM 或 LIST TABLES FOR SCHEMA schemaname 命令查看所有的系統表和相關的視圖信息。下面我們會介紹一些本文用到的系統表和視圖。
SYSCAT.TABLES:數據庫中對象的信息,包括 table,vIEw,nickname 和 alias 的一些定義。詳細說明見表 1。
表 1. SYSCAT.TABLES 視圖的說明
列名 數據類型 描述 TABSCHEMA VARCHAR(128) 記錄 schema 的名字 TABNAME VARCHAR(128) 記錄數據庫對象的名稱。包括表、視圖、別名等 TYPE CHAR(1) 表示該數據庫對象是表,視圖還是別名 ('T'表示table; 'V'表示 vIEw; 'N' 表示nickname; 'A' 表示 alias。) COLCOUNT SMALLINT 表或視圖中列的個數 ……
SYSCAT.VIEWS:視圖的定義信息。詳細說明見表 2。
表 2. SYSCAT.VIEWS 視圖的說明
列名 數據類型 描述 VIEWSCHEMA VARCHAR(128) 視圖的 Schema VIEWNAME VARCHAR(128) 視圖名稱 READONLY CHAR(1) 視圖是否只讀:
Y = 視圖是只讀
N = 視圖不是只讀
VALID CHAR(1) 視圖狀態是否合法:Y = 視圖狀態合法(valid)
X = 視圖狀態不合法(invalid)
TEXT CLOB (64K) 視圖的源程序(DDL) ……SYSCAT.ROUTINES:DB2 UDF,系統方法(system-generated method),用戶定義方法(user-defined method)和存儲過程(SP)的定義。我們可以認為該視圖包含了數據庫中程序的定義。見表 3。
表 3. SYSCAT.ROUTINES 視圖的說明
列名 數據類型 描述 ROUTINESCHEMA VARCHAR(128) 記錄程序的 schema ROUTINENAME VARCHAR(128) 記錄程序名稱 ROUTINETYPE CHAR(1) 記錄程序類型:
F = Function
M = Method
P = Procedure
SPECIFICNAME VARCHAR(128) 程序實例的名稱(可以指定,也可以由系統自動生成) VALID CHAR(1) 如果存儲過程依賴的一些對象被刪除或修改了,該存儲過程必須要被重建Y = SQL 存儲過程是合法的
N = SQL 存儲過程是非法的
X = SQL 存儲過程是不可操作的
TEXT CLOB(1M) 如果是用 SQL 編寫的程序,該字段記錄了其創建的 DDL …表 4 所示的 SYSCAT.ROUTINEDEP 說明了 DB2 UDF與其他對象的依賴關系。
表 4. SYSCAT.ROUTINEDEP 視圖的說明
列名 數據類型 描述 ROUTINESCHEMA VARCHAR(128) 依賴於其他對象的 DB2 程序的 schema ROUTINENAME VARCHAR(128) 依賴於其他對象的 DB2 程序的名稱 BTYPE CHAR(1) 依賴對象的類型:
A = Alias
S = Materialized query table
T = Table
V = VIEw
BSCHEMA VARCHAR(128) 被依賴的對象的 schema BNAME VARCHAR(128) 被依賴的對象的名稱表 5 所示的 SYSCAT.COLUMNS 說明了表或視圖的每一個列的信息。
表 5. SYSCAT.COLUMNS 視圖的說明
列名 數據類型 描述 TABSCHEMA VARCHAR(128) 表或視圖的 Schema TABNAME VARCHAR(128) 表或視圖名稱 COLNAME VARCHAR(128) 列名稱 KEYSEQ SMALLINT 記錄列在其表的主鍵的位置
表 6 所示的 SYSCAT.PACKAGEDEP 說明了 Pachage 與其他數據庫對象的依賴關系。
表 6. SYSCAT.PACKAGEDEP 視圖的說明
列名 數據類型 描述 PKGSCHEMA VARCHAR(128) Package 的 schema PKGNAME VARCHAR(18) Package 的名稱 BTYPE CHAR(1) 依賴對象的類型:
A = Alias
B = Trigger
I = Index
S = Materialized query table
T = Table
V = VIEw
BSCHEMA VARCHAR(128) 被依賴的對象的 schema BNAME VARCHAR(128) 被依賴的對象的名稱表 7 所示的 SYSCAT.TABDEP 說明了視圖或者固化視圖和 DB2 對象之間的依賴關系。
表 7. SYSCAT.TABDEP 視圖的說明
列名 數據類型 描述 TABSCHEMA VARCHAR(128) 視圖或者固化視圖的 schema TABNAME VARCHAR(128) 視圖或者固化視圖的名稱 DTYPE CHAR(1) 視圖的類型:
S = Materialized query table
V = VIEw (untyped)
W = Typed vIEw
BTYPE CHAR(1) 依賴對象的類型:A = Alias
S = Materialized query table
T = Table
V = VIEw
BSCHEMA VARCHAR(128) 被依賴的對象的 schema BNAME VARCHAR(128) 被依賴的對象的名稱使用腳本進行存儲過程開發
在 DB2 開發過程中我們經常使用的操作是:
連接數據庫;
在不同的數據庫中執行編寫好的 SQL 文件,對創建的數據庫對象進行簡單測試;
當我們編寫存儲過程或者 UDF 的時候,我們需要查看其依賴的數據庫表或視圖的定義;
修改表結構的時候,我們需要獲得所有依賴這個表的存儲過程和 UDF,防止因為表結構變化,使得相關的存儲過程和 UDF 不可用。
以上操作我們可以在 CLP 下通過調用 DB2 提供的命令或者通過 SELECT 語句從 DB2 系統表中查出相關信息來完成。我們把這些操作編寫為如清單 1 所示的腳本。
清單 1. conn.bat ――使用腳本連接數據庫
1. @echo off
2. if {%1}=={} goto noparms
3. if {%1}=={dev} goto dev
4. if {%1}=={test} goto test
5. if {%1}=={prod} goto prod
6. if {%1}=={off} goto terminate
7. goto dev
8. :noparms
9. echo Usage: conn db2type
10. echo example: conn dev
11. echo db2type -- dev, test, prod, off
12. goto end
13. :dev
14. db2 connect to db2dev user username using passWord
15. PROMPT $P(%1)$G
16. goto end
17. :test
18. db2 connect to db2test user username using passWord
19. PROMPT $P(%1)$G
20. goto end
21. :prod
22. db2 connect to db2prod user username using passWord
23. PROMPT $P(%1)$G
24. goto end
25. :terminate
26. db2 terminate
27. PROMPT $P$G
28. goto end
29. :end
每次連接數據庫我們只需要鍵入 conn dev/test 就可以完成數據庫的連接,簡化了命令輸入,避免輸入錯誤的用戶和密碼。同時這個腳本也可被其他的腳本調用。
第 2 個批處理腳本是如清單 2 所示的執行 SQL 文件的腳本。使用方法是 esql test.sql [logs\out.log]。
清單 2. esql.bat――執行SQL文件
1. @echo off
2. if {%2} =={} goto setlog
3. set LogFile=%2
4. goto exe
5. rem 如果沒有指定輸出文件,設置默認輸出文件
6. :setlog
7. set LogFile=logs\run.log
8.
9. :exe
10. echo %LogFile%
11. echo --------------------- execute file:%1-------------------- >> %LogFile%
12. db2 values(current time) >> %LogFile%
13. db2 -td@ -f %1 -z %LogFile%
14. db2 values(current time) >> %LogFile%
15. pause
其中 –td@ 選項表示 SQL 文件中各 SQL 語句間的分割符為 @。–z 選項可以使 sql 的執行結果輸出到指定的 Log 文件中。這裡我們使用 -z 而不使用腳本中的管道符號(>)是因為 -z 不僅可以把執行結果記錄到指定的文件中,同時還會在控制台上顯示,這樣即方便我們在執行 sql 的時候實時掌握 sql 運行情況,又可以在 log 中查找分析 sql 執行情況。
該腳本需要兩個參數,第一個參數指明要執行的 sql 文件,第二個參數指明 log 文件名稱,該參數可選。在腳本的第 12 行,第 14 行,我們使用 values(current time) 來記錄腳本執行的開始時間和結束時間。這樣可以幫助我們計算出腳本執行完畢需要多長時間。
第 3 個批處理腳本的作用是獲得表定義,包括字段屬性、主鍵、前 20 條記錄,如果是視圖,顯示其創建語句,並顯示視圖中包含的表。如清單 3 所示。它的使用方法是 vIEwtable schema tablename。
清單 3. vIEwtable.bat ――獲得表定義
1. @echo off
2. mkdir logs
3. set logfile=logs\vIEw_%2.txt
4. db2 describe table %1.%2 show detail >%logfile%
5. echo -----------------------below is (are) pk------------------------- >>%logfile%
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
6. db2 "select substr(colname,1,30) as pk from syscat.columns
where keyseq is not null and tabschema=upper('%1')
and tabname = upper('%2')" >>%logfile%
7. echo ---------------below are the fisrt 20 rows in the %1.%2 table---- >>%logfile%
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
8. db2 select * from %1.%2 fetch first 20 rows only >>%logfile%
9. echo -----------------------below is the sql of the %1.%2 vIEw --------- >>%logfile%
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
10. db2 "select varchar(text,32670) from syscat.vIEws
where viewschema=upper('%1')and vIEwname = upper('%2')" >>%logfile%
11. echo ---------------below are tables of the %1.%2 vIEw --------- >>%logfile%
12. db2 "select distinct bname from syscat.vIEwdep
where vIEwname= upper('%1') and btype='T'" >>%logfile%
13. start %logfile%
腳本中第 4 行的 describe 命令用於顯示數據庫表或視圖的結構。包括字段名稱,數據類型等。第 6 行用於查出表中的主鍵。視圖 syscat.columns 中的 keyseq 字段表明了該字段在表的主鍵的順序,為空表示該字段不是表的主鍵。第 8 行是獲得表或視圖中的前 20 條記錄,便於我們對其分析。第 10 行是獲得視圖的 SQL 定義。第 12 行獲得視圖中依賴的表。
第 4 個批處理腳本的作用是查看存儲過程或 UDF 的定義。如清單 4 所示。它的使用方法是 vIEw spname。
清單 4. vIEw.bat ――查看存儲過程或 UDF 的定義
1. @echo off
2. set logfile=logs\vIEw_%1.sql
3. db2 select varchar(text,32670) from syscat.routines
where routinename=upper('%1') > %logfile%
4. echo -----------------------below are tables used by %1 --------- >>%logfile%
5. db2 select bname from syscat.packagedep
where (btype='T' or btype='V') and pkgname in
(select bname from sysibm.sysdependencIEs where dname =upper('%1')) >> %logfile%
6.
7. start %logfile%
在腳本中我們之所以使用 VARCHAR 函數來格式 TEXT 字段中的內容,是因為 TEXT 字段是 CLOB 類型,其存儲的存儲過程或 UDF 的創建語句的字符比較多。如果我們不使用 VARCHAR 函數進行格式化,DB2 就會使用默認的 CHAR 函數(CHAR 的最大長度是 254)對其格式化,這樣返回的 SQL 創建語句就可能被截去後面的部分。
第 5 行中腳本首先獲得依賴某存儲過程的所有的包(package)名,然後查找依賴這些包的所有的表和視圖。這樣就可以獲得存儲過程中使用的表和視圖。
第 4 個批處理腳本的作用是使用腳本獲得依賴某個表的所有存儲過程,UDF 和視圖。如清單 5 所示。它的使用方法是 dep schema spname。
清單 5. dep.bat ――使用腳本獲得依賴某個表的所有存儲過程,UDF 和視圖
1. @echo off
2. mkdir logs
3. set logfile=logs\%2.dep.txt
4. echo --- dependent SPs --- >> %logfile%
5. db2 "select r.routineschema, r.routinename from syscat.routines r,
syscat.packagedep pdep where pdep.bname=upper('%2') and pdep.bschema=upper('%1')
and pdep.pkgname = 'p'||substr(char(r.lib_id+10000000),2) " >> %logfile%
6. echo --- dependent UDF --- >> %logfile%
7. db2 select routineschema, routinename from syscat.routinedep
where bschema = upper('%1') and bname = upper('%2') and btype ='T'
order by bname >> %logfile%
8. echo --- dependent vIEw --- >> %logfile%
9. db2 select viewschema, viewname from syscat.vIEwdep
where bschema = upper('%1') and bname = upper('%2') and btype ='T'
order by bname >> %logfile%
10. start %logfile%
腳本第 5 行是獲得依賴某表的存儲過程。因為存儲過程會被編譯成包(package)。所以,存儲過程和表的依賴關系實際上是存儲過程對應的包(package)和表之間的依賴關系。這種關系被記錄在 syscat.packagedep 視圖中。同樣的,我們可以通過查詢 syscat.routinedep 和 syscat.vIEwdep 視圖,獲得 UDF 和表,視圖和表之間的依賴關系。
開發實例
使用上面的腳本,進行數據庫開發就會很方便。下面我們看一個開發的例子。
需求描述
由於業務變更,我們的《訂單管理系統》中的表 MIS.ORDER 需要加一個字段 GOV_FLAG SMALLINT 來標識是否是政府訂單,如果是則需要執行特殊的折扣政策。同時需要去除冗余字段 ORDER_PRICE_TOT DECIMAL(19,4)。
需求描述
開發過程
我們需要修改相應的表,存儲過程和 UDF 的 SQL 文件,並把它們重新裝載到開發數據庫和集成測試數據庫中。並需要保留表中原有數據。
假設我們有兩個數據庫,一個是名為 dev 的開發數據庫,一個是名為 test 的集成測試數據庫。只有項目組長擁有在 test 數據庫上執行的權限,開發人員只可以在 dev 數據庫上執行操作。
首先項目組長會分析需求,制定任務分配;然後開發人員根據任務分配編寫相應的 SQL 和腳本文件,並且在 dev 數據庫上進行裝載和測試;最後項目組長把開發人員提交的腳本文件匯總起來,在 test 數據庫上進行裝載和測試。
1. 項目組長
項目組長需要把這個任務分配給組員去完成。首先組長使用腳本 vIEwtable MIS ORDER 查看一下當前在數據庫中表的結構,檢查添加的字段是否會和其他字段有沖突。然後項目組長使用腳本 dep MIS ORDER 獲得依賴表 MIS.ORDER 的所有 DB2 對象。經過分析這些依賴對象,項目組長發現,表結構的修改會導致存儲過程 MIS.SP_ADD_ORDER、UDF MIS.F_CHECK_ORDER 和視圖 MIS.V_ORDER 的修改,並會導致兩個存儲過程需要 rebind。分析結果匯總如下表 8 所示:
表 8. 項目組長的分析結果
名稱 執行操作 備注 MIS.SP_ADD_ORDER 修改 MIS.SP_UPDATE_ORDER rebind 沒有使用要刪除的字段,不必修改 MIS.SP_ADD_ORDER rebind 沒有使用要刪除的字段,不必修改 MIS.F_CHECK_ORDER 修改 MIS.V_ORDER 修改
於是項目組長進行如表 9 的任務分配。
表 9. 項目組長制定的任務分配
編號 任務 執行人 前提條件 完成標志 10 修改 ORDER.SQL,在 MIS.ORDER 中:
添加一個字段 GOV_FLAG SMALLINT;
去除冗余字段 ORDER_PRICE_TOT DECIMAL(19,4);
備注:在刪除原表前,需要首先刪除依賴該表的 UDF 和視圖。創建新表後,需要把除了 MIS.F_CHECK_ORDER 和 MIS.V_ORDER 以外的其他的 UDF 等重新裝載到數據庫中,並且 rebind 存儲過程 MIS.SP_UPDATE_ORDER 和 MIS.SP_SELECT_ORDER。
A 無 項目組長檢查完畢 SQL 腳本;在開發數據庫實例 db2dev 上創建和測試成功。
20 根據新的 MIS.ORDER 表結構修改儲存過程: SP_ADD_ORDER.SQL B 任務 10 完成 項目組長檢查完畢 SQL 腳本;在開發數據庫實例 db2dev 上創建和測試成功。
30 根據 MIS.ORDER 表結構修改 UDF F_CHECK_ORDER.SQL 和視圖 V_ORDER.SQL備注:請先刪除依賴它們的 DB2 對象,並重新裝載它們,使它們的狀態合法。
C 任務 10 完成 項目組長檢查完畢 SQL 腳本;在開發數據庫實例 db2dev 上創建和測試成功。
2. 開發人員 A
A 接到任務後,從 CVS 中獲得表創建 SQL 文件 ORDER.SQL,根據任務要求修改了字段 GOV_FLAG 和 ORDER_PRICE_TOT。下面 A 需要把它裝載到數據庫中。在重新創建表 MIS.ORDER 前,我們需要先做一些准備工作:
備份表 MIS.ORDER 中的數據;
獲得依賴表 MIS.ORDER 所有 UDF,備份這些UDF;
獲得依賴表 MIS.ORDER 的所有存儲過程,以便在重新創建表後,對它們進行 rebind。
A 首先編寫了備份表的 SQL 文件 BACKUP_MIS_ORDER.SQL;然後編寫恢復數據的 SQL 文件 RESTORE_MIS_ORDER.SQL;執行 dep MIS ORDER 獲得依賴該表的 UDF 和存儲過程。編寫 DROP_UDF_4_ORDER.SQL,RELOAD_UDF_4_ORDER.SQL 和 REBIND_SP_4_ORDER.SQL。
當所有的 SQL 文件編寫完後,A 開始編寫執行腳本,如清單 6 所示:
清單 6. 開發人員 A 的執行腳本
rem 連接開發數據庫 dev
conn dev
rem 備份表
esql BACKUP_MIS_ORDER.SQL
rem 刪除依賴表的 UDF
esql DROP_UDF_4_ORDER.SQL
rem 重建表
esql ORDER.SQL
rem 恢復表數據
esql RESTORE_MIS_ORDER.SQL
rem 恢復 UDF
esql RELOAD_UDF_4_ORDER.SQL
rem rebind 相關存儲過程
esql REBIND_SP_4_ORDER.SQL
rem 斷開數據庫連接
conn off
通過上面的腳本,A 成功的完成了他的任務。他把 SQL 和 Windows 腳本提交給項目組長。
3. 開發人員 B
B 接到任務後,從 CVS 中得到 SP_ADD_ORDER.SQL。 為了避免其他人也在修改這個存儲過程,B 使用腳本 vIEw SP_ADD_ORDER 命令獲得了當前數據庫中的存儲過程腳本,然後和 CVS 上的進行比較。當確認獲得了最新的 SP_ADD_ORDER.SQL 後,B 開始修改 SP_ADD_ORDER.SQL。修改完畢以後,B 又修改了針對該存儲過程的測試腳本 TEST_SP_ADD_ORDER.SQL。所有的 SQL 修改完,並且被檢查通過後,B 開始編寫腳本把存儲過程裝載到數據庫中。腳本內容大致如清單 7 所示。
清單 7. 開發人員 B 的執行腳本
rem 連接開發數據庫
conn dev
rem 重建修改過的存儲過程
esql SP_ADD_ORDER.SQL
rem 對重建的存儲過程進行測試
esql TEST_SP_ADD_ORDER.SQL
conn off
通過上面的腳本,B 成功的完成了他的任務。他把 SQL 和 Windows 腳本提交給項目組長。
4. 開發人員 C
C 同樣使用 dep MIS F_CHECK_ORDER 和 dep MIS V_ORDER 獲得依賴它們的對象,發現只是 F_CHECK_ORDER 有一些依賴對象需要重建。所以 C 編寫了下面的 SQL 文件:DROP_UDF_4_MIS_F_CHECK_ORDER.SQL 和 RESTORE_UDF_4_MIS_F_CHECK_ORDER.SQL。下面是 Windows 腳本,如清單 8 所示:
清單 8. 開發人員 C 的執行腳本
rem 連接開發數據庫
conn dev
rem 刪除 F_CHECK_ORDER 的依賴對象
esql DROP_UDF_4_MIS_F_CHECK_ORDER.SQL
rem 重建修改的 UDF 和視圖
esql V_ORDER.SQL
esql F_CHECK_ORDER.SQL
rem 恢復依賴對象
esql RESTORE_UDF_4_MIS_F_CHECK_ORDER.SQL
rem 測試重建的 UDF 和視圖
esql TEST_V_ORDER.SQL
esql TEST_F_CHECK_ORDER.SQL
conn off
通過上面的腳本,C 成功的完成了他的任務。他把 SQL 和 Windows 腳本提交給項目組長。
5. 項目組長
項目組長把 A、B、C 提交上的 Windows 腳本合並成一個腳本,並改為連接集成測試數據庫,把這些存儲過程,UDF 等的改變裝載到了集成開發測試數據庫中。腳本如清單 9 所示:
清單 9. 合並執行腳本
conn test
esql BACKUP_MIS_ORDER.SQL
…
esql TEST_V_ORDER.SQL
…
conn off
這樣,一個數據庫對象的修改就完成了。在實際開發中的情況可能要更復雜一些。但是通過這個例子我們可以看到,通過使用 Windows 腳本,我們可以節省一些重復性的工作並且提高了工作的准確性。當整個團隊熟悉了這些腳本,工作效率的提高是相當可觀的。
總結
對腳本的靈活快捷特性以及 DB2 系統表含義的理解,是編寫出文中腳本的根本。利用腳本和 DB2 系統表的方式和方法遠比本文描述的要豐富得多。有興趣的讀者可以加深對它們的研究。相信會對大家的日常工作有所幫助。
本文示例源代碼或素材下載