簡單有效的SQL 存儲過程移植方案(1)——從Sybase 到DB2

簡單有效的SQL Stored Procedure移植方案 (1)

本文將介紹一套簡單有效的移植方案,指導從Sybase到DB2 V9 FOR Z/OS 的SQL Stored Procedure的移植,並且基於實際移植案例給出了一個具體示例。

背景介紹

隨着企業業務的發展,數據量的海量增長,越來越多的企業採用了性能穩定而強大的 DB2 FOR Z/OS 作爲數據庫管理系統。如何將已有的應用程序移植到 DB2 FOR Z/OS 成爲其中重要的一個環節。在實際的案例中,我們發現目前越來越多的應用程序將數據庫業務處理部分儘可能的封裝到 SQL Stored Procedure 中,這樣不僅能得到了很好的模塊化、重用性和性能優化,而且因未來業務需求的改動而帶來的二次開發也將變得更快捷、更安全。


IBM 提供了強大而實用的 MTK 來幫助客戶完成移植過程,但是目前 MTK 並不支持從 Sybase 到 DB2 FOR Z/OS 的移植。

移植方案的技術介紹


當數據庫業務處理部分儘可能的封裝到 SQL Stored Procedure 時, Stored Procedure 的數量往往會達到上百甚至上千個,而且單個 Stored Procedure 的代碼量也可能達到上百或上千行,這時 SQL Stored Procedure 移植的工作量和難度將成爲整個項目移植的關鍵部分。由於目前沒有自動的移植工具,我們曾試驗了先利用 MTK 將 SQL Stored Procedure 移植到 DB2 FOR LUW ,然後再移植到 DB2 FOR Z/OS ,但效果不是很理想,所以我們的方案採用的是人工直接修改的策略。


由於參與移植的人員往往不全是原有程序的開發人員,對兩個數據庫管理系統也可能不是很熟悉,所以如何提高人工修改的效率和技術要求成爲移植的關鍵問題。我們的方案將分三步走。


第一階段中,挑選具有典型代表意義的 SQL Stored Procedure ,進行研究、移植試驗。


Sybase 和 DB2 在 SQL Stored Procedure 的語法和使用習慣上有很多細微的差異,目前還沒有一個完整的差異對照表,並且具體業務的不同以及開發人員編程習慣的不同,往往使得我們需要具體問題具體分析。


但是在同一個業務模塊中的Stored Procedure往往具有相似性。所以在第一階段,我們需要挑選各個業務模塊中典型的 Stored Procedure ,由技術骨幹來進行研究、試驗。在我們後面的案例中,大約 5% 左右的 Stored Procedure 即包含了所有 Stored Procedure 中的 95% 以上的移植點。我們需要對這些 Stored Procedure 逐個通讀代碼,發現移植點,研究出等價修改的方法。我們可以使用的調試工具有 Workbench ,文本編輯器等。


第二個階段中,形成移植手冊並加以優化以方便批量修改。


我們需要整理第一階段中的研究成果,將移植點及其移植方法加以分類整理。移植手冊的編制目標是儘可能地使得後期的同事可以根據其中的移植詳細步驟將一個 Sybase 的 SQL Stored Procedure 簡單地移植到 DB2 中,降低他們對業務和數據庫技術的要求。移植手冊應該包含絕大部分移植點,完成後最好請其他的同事使用若干第一階段中未選中 Stored Procedure 加以驗證,這樣可以發現其中的不足,加以改進優化,並且能夠評估後期的工作量。


移植手冊可以視具體情況包含多個部分,比如系統環境說明,移植詳細步驟,移植點詳細解答,移植樣例等等,其中移植詳細步驟和移植點詳細解答是核心。移植詳細步驟列舉了移植所需要做的修改操作及其順序。移植點詳細解答列舉了移植點的上下文、技術詳細解釋、等價修改及其注意點,是用來更好地理解、補充移植詳細步驟的。


第三個階段中,組織人員根據移植手冊進行真正的移植工作。


對於在移植手冊中未涵蓋的差異,在此期間具體問題具體解決。等全部 Stored Procedure 移植完成後,需要進行完整的功能測試以及必要的性能測試。

移植方案介紹


移植手冊是移植方案的核心,其中移植詳細步驟和移植點詳細解答是關鍵。限於篇幅,我們這裏只是舉例了移植詳細步驟。


注意:該系統採用 CCSID ASCII ,同時爲了信息安全,我們把實例中出現的變量名、列名、表名等有含義的名稱統一用 V_n,C_n,T_n (n=1,2,3,4….) 加以替換。


移植準備工作


修改工具: UltraEdit 文本編輯器


方法1:全局替換。查找關鍵詞,用替換詞替換即可。


方法2:全局查找,逐個確認替換。查找關鍵詞,確認情景是否符合,然後用替換詞替換。


方法3:全局查找,逐個確認,手工修改。查找關鍵詞,確認情景是否符合,根據具體情景修改。


說明:示例代碼中“ Sybase 代碼”部分是修改前的代碼,“ DB2 代碼”部分是修改後的代碼。


移植詳細步驟


第一步:常見替換


方法:方法1,全局替換。




查找關鍵詞:SUBSTRING(


替換詞:SUBSTR(




查找關鍵詞:len(


替換詞:length(




查找關鍵詞:char_length(


替換詞:length(




查找關鍵詞:DATALENGTH(


替換詞:length(




查找關鍵詞:ISNULL(


替換詞:IFNULL(




查找關鍵詞:+' //表示兩個字符串的連接


替換詞:||'




查找關鍵詞:!=


替換詞:<>




查找關鍵詞: <> NULL


替換詞:IS NOT NULL




第二步: 修改 Stored Procedure 定義的開頭,可以製作成統一的模板。


修改點:


◆把函數說明 ‘/**/’多行註釋,用‘--’進行單行註釋( DB2 不支持多行註釋)。

◆去掉 schema name: ‘dbo.’

◆傳入參數處添加‘( )’

◆傳入參數處添加IN 關鍵詞,並修改IN,OUT的位置

◆去掉關鍵詞‘AS’,換成 Stored Procedure 的參數選項

◆以BEGIN作爲函數體的開始,把BEGIN移到DECLARE前。

◆變量定義增加初始值及CCSID ASCII關鍵字。

清單1. Stored Procedure 定義的開頭修改示例


Sybase代碼:
CREATE PROCEDURE dbo.P_1
@p_1 VARCHAR(9),
@p_2 VARCHAR(256) OUT
AS
DECLARE @v_1 VARCHAR(50)
DECLARE @v_2 VARCHAR(1024)
BEGIN

DB2代碼:
CREATE PROCEDURE Pr_ChkExPreCorp (IN p_1 VARCHAR(9),
OUT p_2 VARCHAR(256))
LANGUAGE SQL
MODIFIES SQL DATA
WLM ENVIRONMENT FOR DEBUG MODE WLMENV1
ASUTIME NO LIMIT
NOT DETERMINISTIC
COMMIT ON RETURN NO
PARAMETER CCSID ASCII
PACKAGE OWNER TEST
QUALIFIER TEST
RESULT SETS 1
BEGIN
DECLARE v_1 VARCHAR(50) CCSID ASCII DEFAULT ’’;
DECLARE v_2 VARCHAR(100) CCSID ASCII DEFAULT ’’;



第三步:賦值語句的修改


方法:方法1,全局替換。


查找關鍵詞:SELECT @


替換詞:SET //注意:SET 後面帶一個空格



清單2 :賦值語句的修改


Sybase 代碼:
SELECT @v_1='0'

DB2 代碼:
SET v_1 ='0';


注意:該處使用全局替換可能錯誤地替換一些地方,比如語句


select @aaa=xxxx, @bbb = yyyy from …… where ……


但是情況不多,可以在 Deploy Stored Procedure 的時候發現錯誤並改回來。




第四步:全局變量 @@sqlstatus 和 WHILE 語句的改寫


方法:方法3,全局查找,逐個確認,手工修改。


查找關鍵詞:@@sqlstatus = 0 , WHILE


修改點:


◆去掉 BEGIN, 添加 DO;

◆END 改爲 END WHILE;

◆@@sqlstatus = 0 替換成 v_sqlcode = 0。//注意:v_sqlcode 的定義見後面HANDLER的定義;

◆在每個‘FETCH C1 INTO …’之前添加‘SET v_sqlcode =0’。

清單 3 :全局變量 @@sqlstatus 和 WHILE 語句的改寫


Sybase 代碼:
OPEN C1
FETCH C1 INTO ……
WHILE @@sqlstatus = 0
BEGIN
… …
FETCH C1 INTO ……
END

DB2 代碼:
OPEN C1;
set v_sqlcode = 0;
FETCH C1 INTO ……
WHILE v_sqlcode = 0 DO
… …
set v_sqlcode = 0;
FETCH C1 INTO ……
END WHILE;


第五步:全局變量 @@ERROR 的改寫


方法:方法3,全局查找,逐個確認,手工修改。


查找關鍵詞:@@ERROR


修改點:


(1)@@ERROR修改



清單4:@@ERROR修改


Sybase代碼:
SELECT @v_errcode = CONVERT(VARCHAR(10),@@ERROR)
IF ERROR <> 0
GOTO ERROR

DB2代碼:
IF (v_sqlcode < 0) THEN
GOTO ERROR;
END IF;


(2) 在前面 DECLARE 部分添加 HANDLER 處理的定義



清單5 :添加 HANDLER 處理的定義


DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE v_sqlcode INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
SET v_sqlcode = SQLCODE;
END;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING
BEGIN
SET v_sqlcode = SQLCODE;
END;

 

 

轉自:http://www.vstcn.net/JiShuWenZhangShow.asp?ID=741

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章