能讓SQL語句調用自己在程序裏定義的方法,實現SQL與程序的數據交互簡直不可思議吧!其實這完全可以做到的!
通常情況下都是我們在程序中寫一些方法去執行SQL語句,讓SQL執行返回我們想要的內容,不管是執行SQL語句還是調用存儲過程以及數據變動影響到觸發器的動作這都是程序在主動與SQL交互,那麼SQL能否主動與程序進行逆向交互呢?這樣做有必要嗎?答案時肯定的。
舉個例子:最近在做到一個項目,需要兩個服務器數據庫數據同步,就用到了觸發器來完成這個艱鉅的任務,可兩個數據庫表結構不盡相同(兩個表實現同樣的存儲目的,但數據字段上設計有所不同),本地服務器表中的數據存儲的數據包格式,而遠程數據庫表中卻直接存儲數據,也就是說從本地同步到遠程庫中必須要經過數據包解析,說到解析並不難,數據包都是固定的格式,在程序中按部就班的解析應該很容易,可是要想數據同步能夠捕獲到用戶對本地數據庫表的每一個動作就必須用觸發器,用了觸發器數據解析就必須在SQL中完成,但是畢竟SQL不如程序更強大,對數據包字符串的解析來說SQL實現基本是不可能的,這怎辦呢?於是就想到了將SQL觸發器與程序結合起來完成該項任務,那麼當觸發器觸發的話怎麼才能通知程序去解析我的數據包呢,也就是說我們如何讓SQL在他需要的時候去主動調程序呢,這就是我要說的重點了!
看下面。。。
我們一起來做個示例,在.NET中新建一個類,並在這個類裏新建一個方法,然後在SQL Server中調用這個方法。按照微軟所述,通過宿主 Microsoft .NET Framework 2.0 公共語言運行庫 (CLR),SQL Server 2005顯著地增強了數據庫編程模型。這使得開發人員可以用任何CLR語言(如C#、VB.NET或C++等)來寫存儲過程、觸發器和用戶自定義函數。
我們如何實現這些功能呢?
爲了使用CLR,我們需要做如下幾步:
1、在.NET中新建一個類,並在這個類裏新建一個public方法。
2、編譯這個類爲一個DLL。
3、在SQL
Server中註冊這個DLL。
4、新建一個SQL Server函數來訪問指定的.NET方法。
接下來,我們一起來完成一個示例
首先,在Visual
Studio中新建一個名爲“SQLServerCLRTest”的類庫項目。然後,新建一個名爲“CLRFunctions”的類,並在其內添加一個名爲“HelloWold”的方法,代碼如下:
public
class CLRFunctions
{
public static string
HelloWorld(string Name)
{
return ("Hello " +
Name);
}
}
這是一個非常簡單的方法(爲了讓SQL
Server可以調用它,它必須要是public和static的),這個方法有一個string類型的參數,返回信息爲“Hello”加上你傳入的參數。
現在,我們需要編譯這個項目爲一個DLL,並在SQL
Server中註冊它。這也是比較簡單的,在VS中右鍵單擊項目,選擇“生成”後程序就會生成一個DLL。如果你的項目是調試模式的話,那麼就可以在如下所示那樣的路徑裏找到編譯好的DLL。
C:\Documents
and Settings\mark.smith\My Documents\Visual Studio
2005\Projects\SQLServerCLRTest\SQLServerCLRTest\bin\Debug\SQLServerCLRTest.dll
找到這個DLL後,我們就可以把它拷貝到我們的SQL
Server機器上了,如果是相同機器的話我們只要記住這個路徑即可。
啓用CLR功能
默認情況下,SQL Server中的CLR是關閉的,所以我們需要執行如下命令打開CLR:
exec
sp_configure 'clr enabled',1
reconfigure
go
註冊DLL
爲了調用我們寫的那個方法,需要在SQL
Server中註冊我們剛剛編譯好的那個DLL。我們可以在數據庫中使用如下命令來註冊DLL(路徑爲你的DLL文件的路徑)
CREATE ASSEMBLY
asmHelloWorld FROM 'C:\SQLServerCLRTest.dll'
在SQL Server中調用我們的.NET方法
爲了調用.NET方法,我們可以寫一個SQL Server自定義函數,並在其內使用“EXTERNAL
NAME”來通知SQL Server使用CLR功能。 代碼如下:
CREATE FUNCTION
dbo.clrHelloWorld
(
@name as
nvarchar(200)
)
RETURNS
nvarchar(200)
AS EXTERNAL NAME
asmHelloWorld.[SQLServerCLRTest.CLRFunctions].HelloWorld
上面的自定義函數做了兩項工作。首先是聲明瞭一個nvarchar參數,它等同於.NET裏的string類型(如果將其設置爲varchar並且後面使用了“EXTERNAL
NAME”的話就會報錯)。然後使用“EXTERNAL NAME”來調用.NET方法。
語法如下:
程序集名.類名.方法名
但是,當我使用這個語法調用.NET方法的時候,SQL
Server就會報錯,所以爲了讓它正常工作,我使用瞭如下語法:
程序集名.[類名].方法名
現在我們就可以通過如下語句調用.NET方法了:
SELECT
dbo.clrHelloWorld('Mark')
當你運行這段代碼的時候,就會得到一個返回結果“Hello Mark”。
我們通過一個很簡單的示例演示瞭如何實現SQL Server的CLR,它可以給我們帶來很多非常有用的幫助。
這樣就可以實現SQL觸發器獲取數據,程序解析數據後再返回觸發器繼續執行其他操作進而實現數據同步操作。
感謝:夏日冰激凌