最近要把.net開發的CMS系統跟JAVA開發的系統數據打通。由于N個系統用的數據庫有SQL-Server和Oracle兩種,之間的數據讀取成了最大的難題。
我準備了兩種實行方案,進行了技術驗證。方案一:改寫底層數據層和邏輯層。方案二:把Oracle數據做定時導向,無需讓Cms做太大的改變。
我做的CMS是基于模板的系統架構,底層規則已經寫得比較死,要改換底層數據庫鏈接或者存在多個數據庫鏈接簡直根重寫系統沒有太大的區別,從開發成本上分析,決定使用第二方案,做數據采集工程。
但是Oracle那邊的系統存在N個庫(即用戶),其中的讀取規則各不相同,要如何開發統一導表程序也是個大問題。其中邏輯非常復雜。風險難以控制。在想了幾天之后,發現了MSSQL和Oracle互通的功能,大喜。接著就開始著手開發。于是有了這文章。
在MSSQL中有個叫做鏈接服務器的功能(這個在Oracle里稱為透明網關)。能把不同的異類數據庫附加鏈接到MSSQL中,做為一個“虛庫”(我給的名稱)使用。比如Oracle,DB2,Sybase,access等等,基本上MS能提供驅動程序的都能做。
架好服務器,開通個Job,就實現了定時導數據的功能。
具體實現:
首先,在Oracle上創建View,給MsSql提供必要的數據源。
在MsSql的服務器上安裝Oracle10g的客戶端。在ODBC創建好數據源。之后在MsSql上架設鏈接服務器。
test一下。'SELECT id,title,thedate,summary,lid,city,ptype FROM {0}..{1}.{2}' --0,為數據源名稱;1,為用戶名;2為表名。格式要依照PL/SQL語法。 ok~
但是發現,這樣讀取View出錯。所以換了一種寫法:
select * from openquery(***,'SELECT id,title,thedate,summary,lid,city,ptype FROM ***.***')
這樣是利用MsSql的分布式方法去讀取Oracle。
接著,創建采集的存儲過程。
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE PROCEDURE [dbo].[usp_tranDigital] AS
select * from openquery(***,'SELECT id,title,thedate,summary,lid,city,ptype FROM ***.***')
用游標獲取結果集的行。這個方法在Oracle比較常用
OPEN authors_cursor
FETCH NEXT FROM authors_cursor into @ID,@TITLE,@THEDATE,@SUMMARY,@LID,@CITY,@PTYPE
WHILE @@FETCH_STATUS = 0
BEGIN
execute Digital_Insert
調用存儲過程插入。
FETCH NEXT FROM authors_cursor into
@ID,@TITLE,@THEDATE,@SUMMARY,@LID,@CITY,@PTYPE
END
CLOSE authors_cursor
DEALLOCATE authors_cursor
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
在Job里調用該存儲過程。任務完結。
這樣,我在不要任何程序修改的情況下,把不同數據庫上的數據都挪到同一個地方。