隨著技術(shù)的不斷升級(jí),微軟的王牌數(shù)據(jù)庫(kù)SQL Server 2000正在逐漸淡出人們的視線,而新版的SQL Server 2005正成為企業(yè)和開(kāi)發(fā)人員的新寵。本文重點(diǎn)關(guān)注SQL Server 2005的功能,尤其是CLR集成,這是開(kāi)發(fā)人員經(jīng)常要使用的功能之一。
1、SQL Server 2005簡(jiǎn)介
SQL Server 2005較SQL Server 2000有了長(zhǎng)足進(jìn)步。SQL Server 2005帶來(lái)了大量新功能,新圖形化用戶(hù)界面(GUI)和新管理工具。下面列舉了一些簡(jiǎn)單的功能介紹:
能夠在數(shù)據(jù)庫(kù)中托管.NET Framework中的通用語(yǔ)言運(yùn)行時(shí)(CLR),那么開(kāi)發(fā)人員就可以使用Visual Basic 2005和C#編寫(xiě)程序集。這對(duì)于SQL Server數(shù)據(jù)庫(kù)編程人員可能是件有趣的事情,以前的編程人員受限于SQL和T-SQL,而如今卻有力的暗示了應(yīng)用程序的構(gòu)建方法。
通過(guò)完全成熟的,能夠保存多個(gè)相關(guān)數(shù)據(jù)類(lèi)型的XML數(shù)據(jù)類(lèi)型對(duì)XML進(jìn)行深入支持。開(kāi)發(fā)人員可以將XML文檔存儲(chǔ)到數(shù)據(jù)庫(kù)中,同時(shí)驗(yàn)證其有效性,并且抽取文檔的部分內(nèi)容。這意味著可以將半結(jié)構(gòu)化數(shù)據(jù)與關(guān)系型數(shù)據(jù)相結(jié)合,同時(shí)將它們存儲(chǔ)到同一地方,并采取相同方式處理它們。另外,服務(wù)器端還提供了XML查詢(xún)(XQuery)和XML架構(gòu)定義語(yǔ)言(XSD)標(biāo)準(zhǔn)。
完全更新的GUI管理工具SQL Server Management Studio(SSMS),該工具提供的單個(gè)集成環(huán)境可滿(mǎn)足配配置/管理需求。
將報(bào)表框架(SQL Server Reporting Services,縮寫(xiě)為SSRS)作為數(shù)據(jù)庫(kù)整體的一部分。
為實(shí)現(xiàn)異步消息傳遞創(chuàng)建新的應(yīng)用程序框架Service Broker。
經(jīng)過(guò)大量改進(jìn)和擴(kuò)展的SQL Server Integration Services(SSIS,以前是Data Transformation Services),該工具可用于提取,轉(zhuǎn)換和加載數(shù)據(jù)(另外,關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)使用這個(gè)功能代價(jià)昂貴)。
以上只是介紹了SQL Server 2005的一些重點(diǎn)功能,每個(gè)功能都可以讓開(kāi)發(fā)人員細(xì)細(xì)品味,限于篇幅,本文重點(diǎn)介紹其中的CLR集成功能。
在SQL Server 2005中可使用通用語(yǔ)言運(yùn)行時(shí)(CLR)集成,這意味著在SQL Server實(shí)例中提供對(duì)于.NET Framework編程模型的訪問(wèn)是很有必要的。為此,在SQL Server 2005中引入了程序集概念。程序集是.NET編譯和托管的DLL文件。SQL Server使用程序集部署對(duì)象,例如存儲(chǔ)過(guò)程、用戶(hù)定義類(lèi)型、觸發(fā)器和用戶(hù)定義函數(shù)。這些對(duì)象通常使用T-SQL編寫(xiě),但是而今使用多種受管語(yǔ)言代碼(例如VB.NET或者C#)也能夠創(chuàng)建和編寫(xiě)這些對(duì)象。SQL Server 2005的這種新功能還提供了在數(shù)據(jù)庫(kù)對(duì)象(例如存儲(chǔ)過(guò)程,函數(shù)和類(lèi)型)中,訪問(wèn)經(jīng)過(guò)改進(jìn)的.NET Framework編程模型的能力。.NET Framework 2.0版本具有多方面增強(qiáng)功能,這些經(jīng)過(guò)改進(jìn)的功能有很多已經(jīng)可以為CLR集成使用。
2、受管程序集的概念
在SQL Server 2005之前,程序集也稱(chēng)為受管代碼,它是一組編譯為.dll或者.exe的文件。在.NET Framework中仍然存在這個(gè)術(shù)語(yǔ)和特性。然而,在SQL Server 2005中,程序集術(shù)語(yǔ)則變得有點(diǎn)模糊。
在SQL Server范圍內(nèi),程序集是一個(gè)引用物理程序集.dll文件的對(duì)象。受管代碼是.dll文件,該文件使用.NET Framework CLR和可訪問(wèn)其他受管代碼來(lái)創(chuàng)建。更確切的說(shuō),是在SQL Server內(nèi)部的其他受管代碼。每段受管代碼都包括兩個(gè)重要的片段信息。一個(gè)是描述程序集的元數(shù)據(jù),例如程序集方法和屬性,程序集版本號(hào)。第二個(gè)片段信息是實(shí)際的受管代碼,組成程序集的方法和屬性。通常,使用一些高級(jí)編程語(yǔ)言(例如C#或者Visual Basic.NET)編寫(xiě)受管代碼,這些代碼共享類(lèi)庫(kù),同時(shí)被編譯為中間語(yǔ)言(Intermediate Language,縮寫(xiě)為IL)。
程序集中的受管代碼實(shí)現(xiàn)SQL Server對(duì)象的功能,例如存儲(chǔ)過(guò)程、UDT、CLR函數(shù)和CLR觸發(fā)器。更為重要的是,程序集自身控制受管代碼訪問(wèn)內(nèi)部和外部資源的權(quán)限級(jí)別。當(dāng)在SQL Server中利用CREATE ASSEMBLY語(yǔ)句創(chuàng)建程序集時(shí),.dll文件會(huì)物理的加載到SQL Server中,這樣SQL Server引擎就能夠引用和使用程序集。SQL Server 2005中有兩個(gè)說(shuō)明所創(chuàng)建程序集的表,它們是sys.assemblies和sys.assembly_files。
3、啟用CLR集成的方法
當(dāng)開(kāi)發(fā)人員開(kāi)始在SQL Server 2005中使用程序集之前,需要告知SQL Server已經(jīng)準(zhǔn)備好在SQL Server中與CLR交互。默認(rèn)情況下,禁用CLR集成功能,必須啟用CLR集成才能SQL Server中訪問(wèn).NET對(duì)象。
為了啟用CLR集成,在SQL Server Management Studio的查詢(xún)窗口中執(zhí)行以下代碼:
EXEC sp_configure 'clr enabled', 1 GO RECONFIGURE GO
要啟用CLR集成,必須具有ALTER SETTINGS服務(wù)器權(quán)限。該權(quán)限由sysadmin和serveradmin固定服務(wù)器角色的成員顯式持有。
啟用CLR集成的另一種方法是利用SQL Server外圍應(yīng)用配置器工具。為打開(kāi)這個(gè)工具,可在Microsoft SQL Server 2005配置工具菜單中選擇“SQL Server外圍應(yīng)用配置器”。要配置CLR集成,可單擊對(duì)話(huà)框底部的“功能的外部應(yīng)用配置器”。在彈出的對(duì)話(huà)框中,選擇左邊Database Engine之下的CLR集成,然后選中右邊的CLR集成復(fù)選框。單擊確定按鈕,從而啟用該選項(xiàng),同時(shí)關(guān)閉窗口。接下來(lái)就可以使用受管代碼創(chuàng)建SQL Server中的對(duì)象了,例如創(chuàng)建存儲(chǔ)過(guò)程。
4、使用受管代碼創(chuàng)建存儲(chǔ)過(guò)程
第一個(gè)示例很簡(jiǎn)單,其用于幫助讀者初步理解在程序集中使用SQL Server 2005的方法。首先,在C:\Projects目錄下創(chuàng)建名為sample1的文件夾。打開(kāi)編輯器,輸入以下代碼,接著將其保存為HelloWorldStoredProcedures.cs:
using System; using System.Data; using Microsoft.SqlServer.Server; using System.Data.SqlTypes; public class HelloWorldStoredProcedures { public static void HelloWorld() { SqlContext.Pipe.Send("Hello World"); } }
在HellpWorld()方法中,通過(guò)調(diào)用SqlContext類(lèi)的Pipe屬性能夠獲取指向SqlPipe對(duì)象的引用。當(dāng)獲取指向SqlPipe對(duì)象的引用后,接著可將表格式結(jié)果和消息發(fā)送到客戶(hù)端。這個(gè)工作可由SqlPipe類(lèi)的Send()方法完成。SqlPipe對(duì)象類(lèi)似于ASP.NET中的Response對(duì)象。通過(guò)調(diào)用Send()的多種重載方法,開(kāi)發(fā)人員可通過(guò)管道將數(shù)據(jù)發(fā)送給調(diào)用方應(yīng)用程序。Send()的各種重載方法如下所示:
Send(SqlDataReader):允許以SqlDataReader對(duì)象格式發(fā)送表格式結(jié)果。
Send(SqlDataRecord):允許以SqlDataRecord對(duì)象格式發(fā)送結(jié)果。
Send(String):使用該方法可將消息發(fā)送給調(diào)用方應(yīng)用程序。
一旦創(chuàng)建了類(lèi),下一步是創(chuàng)建受管代碼。為此,通過(guò)開(kāi)始→所有程序→Microsoft .NET Framework SDK v2.0→SDK命令提示符,可打開(kāi)命令提示符窗口。
在命令提示符窗口下,訪問(wèn)C:\Projects\sample1目錄,接著執(zhí)行以下命令:
CSC /target:library C:\Projects\sample1\HelloWorldStoredProcedures.cs
此時(shí),在sample1目錄會(huì)看到一個(gè)新文件HelloWorldStoredProcedures.dll。
下一步是在SQL Server中注冊(cè)程序集。在SQL Server Management Studio中打開(kāi)查詢(xún)窗口,確認(rèn)選中AdventureWorks數(shù)據(jù)庫(kù),接著執(zhí)行以下T-SQL語(yǔ)句:
CREATE ASSEMBLY HelloWorld FROM 'C:\Projects\sample1\HelloWorldStoredProcedures.dll' WITH PERMISSION_SET = SAFE
CREATE ASSEMBLY語(yǔ)句將程序集加載到SQL Server中,此時(shí)可以在SQL Server內(nèi)部引用該程序集。在SQL Server中,可以以相同文件名稱(chēng)存儲(chǔ)程序集的多個(gè)版本,只要每個(gè).dll文件具有不同的版本號(hào)。
需要注意的一件事情是CREATE ASSEMBLY語(yǔ)句是以WITH PERMISSION_SET子句結(jié)尾。該子句設(shè)置了當(dāng)SQL Server使用和訪問(wèn)程序集時(shí),對(duì)程序集的訪問(wèn)權(quán)限。該子句的可用值是:
SAFE:這是默認(rèn)級(jí)別,具有最大限制性。這意味著,代碼不需要使用任何外部資源,在SQL Server內(nèi)部可以完全控制操作。SAFE代碼能夠訪問(wèn)本地SQL Server數(shù)據(jù)庫(kù)中的數(shù)據(jù),或者執(zhí)行計(jì)算,以及處理不包括訪問(wèn)本地?cái)?shù)據(jù)庫(kù)之外資源的業(yè)務(wù)邏輯。階乘計(jì)算是一個(gè)好例子。階乘計(jì)算只需要整型輸入,然后返回另外一個(gè)整數(shù)。計(jì)算階乘無(wú)需打開(kāi)磁盤(pán)上的文件。
EXTERNAL_ACCESS:該級(jí)別表示可以使用某些外部資源,例如文件、網(wǎng)絡(luò)、Web服務(wù)、環(huán)境變量和注冊(cè)表。因此,如果代碼計(jì)劃將某些結(jié)果寫(xiě)入磁盤(pán)文件中,那么需要在SQL Server的EXTERNAL_ACCESS安全類(lèi)別下注冊(cè)這些代碼。
UNSAFE:這個(gè)級(jí)別設(shè)置代碼能夠完成任何事情,因此應(yīng)該盡量避免使用。換言之,開(kāi)發(fā)人員要求不做任何級(jí)別的控制,因此代碼與外部存儲(chǔ)過(guò)程具有相同權(quán)限。即使獲得了與外部存儲(chǔ)過(guò)程相同的權(quán)限,CLR仍然會(huì)為開(kāi)發(fā)人員代碼一些方便。然而,這樣在邏輯上可能存在漏洞,那么黑客就能夠隨意訪問(wèn)系統(tǒng)的關(guān)鍵部分。因此,應(yīng)該避免在SQL Server中使用UNSAFE代碼。
本示例代碼通過(guò)使用HelloWorldStoredProcedures.dll,同時(shí)將權(quán)限設(shè)置為SAFE創(chuàng)建了名為HelloWorld的程序集。
在創(chuàng)建程序集之后,下一步是創(chuàng)建一個(gè)使用該程序集的簡(jiǎn)單T-SQL存儲(chǔ)過(guò)程。以下DDL語(yǔ)句為程序集創(chuàng)建了入口點(diǎn):
CREATE PROCEDURE HelloWorld AS EXTERNAL NAME HelloWorld.HelloWorldStoredProcedures.HelloWorld 在執(zhí)行存儲(chǔ)過(guò)程之前,查看一下CREATE PROCEDURE語(yǔ)句中的EXTERNAL NAME語(yǔ)法,其設(shè)置了.NET程序集的方法,其語(yǔ)法格式如下:
Assembly_name.Class_name.Method_name
當(dāng)使用前面的示例時(shí),程序集名稱(chēng)來(lái)自CREATE ASSEMBLY,在此處是HelloWorld。第二部分是類(lèi)名稱(chēng),其來(lái)自HelloWorldStoredProcedures.cs文件代碼。第三部分是方法名稱(chēng),它也來(lái)自HelloWorldStoredProcedures.cs,在本示例中是HelloWorld。
將這些片段信息一起置于EXTERNAL NAME子句,其告知存儲(chǔ)過(guò)程所執(zhí)行的內(nèi)容。
此時(shí),可以準(zhǔn)備測(cè)試程序集和獲取返回?cái)?shù)據(jù)。為了測(cè)試示例,通過(guò)運(yùn)行以下語(yǔ)句來(lái)執(zhí)行存儲(chǔ)過(guò)程:
EXEC HelloWorld
雖然本示例很簡(jiǎn)單,但是它說(shuō)明了創(chuàng)建和部署程序集的基本步驟。下一個(gè)示例將在此代碼之上,說(shuō)明涉及訪問(wèn)SQL Server數(shù)據(jù)的更為復(fù)雜的功能。
讀者肯定在想:“必須有一種更為簡(jiǎn)單的方法來(lái)生成和部署這些程序集”。實(shí)際上是存在這種方法的。然而,通過(guò)這些步驟手動(dòng)生成和部署程序集的原因是,幫助讀者理解程序集生成過(guò)程發(fā)生的內(nèi)幕。下面將說(shuō)明如何使用Visual Studio 2005專(zhuān)業(yè)版創(chuàng)建CLR存儲(chǔ)過(guò)程。
4.1 創(chuàng)建復(fù)雜CLR存儲(chǔ)過(guò)程
在這個(gè)示例中,將創(chuàng)建從AdventureWorks數(shù)據(jù)庫(kù)的Production.Product表返回?cái)?shù)據(jù)的存儲(chǔ)過(guò)程。首先,選擇“文件”→“新建項(xiàng)目”,然后在彈出窗口的左邊導(dǎo)航菜單中選擇“Visual C#”→“數(shù)據(jù)庫(kù)”,接著將項(xiàng)目模板選擇為“SQL Server項(xiàng)目”,這樣可在Visual Studio 2005中創(chuàng)建新項(xiàng)目SqlServerDataAccess。如果單擊新建項(xiàng)目對(duì)話(huà)框中的OK按鈕,那么會(huì)要求添加數(shù)據(jù)庫(kù)引用。如果AdventureWorks引用還不可用,那么可使用“添加新引用”選項(xiàng)來(lái)添加指向AdventureWorks數(shù)據(jù)庫(kù)的引用。
當(dāng)選擇啟用CLR存儲(chǔ)過(guò)程調(diào)試和項(xiàng)目建立后,在菜單中選擇“項(xiàng)目”→“添加存儲(chǔ)過(guò)程”項(xiàng),接著設(shè)置類(lèi)名稱(chēng)為GetProducts.cs。一旦創(chuàng)建了類(lèi),可根據(jù)示例1修改代碼。
示例1:由CLR存儲(chǔ)過(guò)程返回表格式結(jié)果集