本文是根據 Microsoft SQL Server(代號“Yukon”)的 Beta 1 撰寫的,其中包含的所有信息均可能更改
注:本文是在產品投放生產之前編寫的,因此,我們無法保證此處包含的任何細節都與在交付使用的產品中發現的細節完全一致。文中信息描述的是本文發布之時的產品,僅供規劃之用。這些信息可在任何時候更改,恕不預先通知。
Transact-SQL 的增強功能 SQL Server Yukon .Net 編程
利用 CLR 在 T-SQL 和托管代碼之間選擇 用戶定義的類型、函數和聚合 托管存儲過程
XML 和 SQL Server Yukon XML 數據類型 XSD 和XML 數據類型 XML 查詢了解 Microsoft XQuery Designer 了解 SQL Server 服務代理 數據庫集成 SQL Server Yukon 的可編程場景
小結
在 Microsoft SQL Server™ 下一版本(代號為“Yukon”)的規劃階段,考慮更多的是數據庫的未來發展以及 SQL Server 的編程能力。Microsoft 內部的開發人員很早就意識到,未來必須引入更加對稱的編程模型,還要為不同的數據模型提供更多的靈活性。編程模型對稱的目的意味著,普通的數據訪問和操作任務可以通過多種途徑進行 — 使用 XML、Microsoft .Net 框架或 Transact-SQL (T-SQL) 代碼。
這種規劃帶來的結果就是一個新的數據庫編程平台,它在許多方面都進行了擴展。首先,寄主 .NET 框架公共語言運行庫 (CLR) 的功能將數據庫擴展到過程化編程和托管代碼的領域。其次,.Net 框架宿主集成提供了來自 SQL Server 內部強大的對象數據庫功能。對 XML 的深入支持是通過功能完善的 XML 數據類型實現的,它擁有關系數據類型的所有功能。此外,還添加了對 XML 查詢 (XQuery) 和 XML 架構定義語言 (XSD) 標准的服務器端支持。最後,SQL Server Yukon 包含了 T-SQL 語言的重要增強功能。
這些新的編程模型和增強的語言共同創造了一系列的可編程性,它們補充並擴展了目前的關系型數據庫模型。這種體系結構帶來的最終結果是能夠創建更可伸縮、更可靠、更健壯的應用程序,並提高了開發人員的工作效率。這些模型的另一個結果就是一種稱為 SQL 服務代理的新應用程序框架 — 用於異步消息傳遞的分布式應用程序框架。稍後,我將在文中對 Yukon SQL 服務代理做進一步討論。現在,請先看看編程模型中的主要更改和增強功能,讓我們從
現在讓我們看一看 .Net 框架的某些功能,以及它們是如何與 Yukon 相輔相成的。
返回頁首Yukon 支持可擴展的 CLR 類型系統。這些類型在服務器端可用作表定義的一部分,在客戶端可作為對象來操作。UDT 使您能夠通過創建在托管代碼中實現的新類型,來擴展現有的類型系統。某些 UDT 示例為地理空間類型、自定義金融類型和特定日期/時間類型。可以將 UDT 看成是服務器引擎和代碼之間的協定。
在 .Net 術語中,UDT 是一個結構或引用類型,而不是類或枚舉。這就是說內存的使用可以優化。但是,UDT 並不支持繼承和多態。它即可以包含公共函數,也可以包含私有函數。事實上,像約束檢查這樣的任務應該作為私有類來完成。如果您的 UDT 由多個信息(例如,地理空間類型會包含經度、緯度可能還有海拔)構成,您就需要提供包含這些元素的私有字段。創建 UDT 之後,您可以使用 T-SQL 在 SQL Server 中注冊類型。完成後,DLL 的內容就實際存儲到數據庫中了。
UDF 有兩個變體:標量值函數和表值函數。標量值函數返回單一值,如字符串、整數或比特。表值函數返回的是可以由一個或多個列構成的結果集。
能夠創建系統中現有函數以外的其他聚合函數的能力,是使用舊版 SQL Server 的開發人員無法做到的。借助 Yukon,開發人員可以在托管代碼中創建自定義聚合函數,並使這些函數能夠被 T-SQL 或其他托管代碼訪問。用戶定義的聚合也是一個要引用數據庫中已有程序集的 .Net 類。
您可以使用 UDAgg 將存儲在數據庫中的數據轉換為數學值。例如,一個統計函數。您可以存儲包含來自一個關系表中量化調查結果的數據。為了計算出這些結果的加權平均值或標准偏差,您可以調用 UDAgg 來計算和返回這些信息。
返回頁首
作為存儲過程工作的托管代碼例程,最適用的情況是:將簡單的結果集稍加修改後返回給調用方,或要簡單地執行一個數據操作語言 (DML) 或數據定義語言 (DDL) 語句的場合。在服務器上注冊後,使用代碼就和編寫一個存儲過程一樣簡單。
要使用存儲過程包裝一個托管代碼方法,請使用 CREATE PROCEDURE 語句。CREATE PROCEDURE 使用以下原型中的語法:
CREATE PROCEDURE mysproc (@username NVARCHAR(4000)) AS EXTERNAL NAME YukonCLR:[MyNamespace.CLRCode]:: myfunction
返回頁首
XML 在 SQL Server Yukon 中的歷史實際上始於 SQL Server 2000。該版本的 SQL Server 引入了以 XML 的格式返回關系型數據、大量加載和切分 XML 文檔,以及將數據庫對象公開為基於 XML 的 Web 服務等功能。
Web 服務工具包,也稱為 SQLXML 3.0,為存儲過程、XML 模板和 SQL Server UDF 提供了 Web 服務功能。該 XML 技術缺少了兩個重要的部分:原生 XML 存儲機制(XML 數據類型)和支持對半結構化數據進行查詢的高級查詢語言。Yukon 提供了這兩個元素,以及更多的 Web 服務增強功能和對 T-SQL FOR XML 語句的擴展。讓我們從原生 SQL Server 數據類型(XML 數據類型)的主要增強功能開始。
返回頁首
XML 從一種表示技術發展為一種線路格式,現在又被看作是一種存儲格式。XML 中的持久存儲已經引起了廣泛關注,並出現了許多 XML 數據類型的可能應用。首先,XML 在不知道對象架構的情況下很有用。其次,XML 數據類型對於信息要不斷重新組織情況中的動態架構很有用。第三,XML 持久性是 XML 文檔應用的中心。沒有什麼單一的應用場景能夠最好地體現 XML 數據類型的正確使用。稍後,我將在本文給出的編程示例中,將 XML 用作一種動態架構(以發送給服務器的消息形式表示用戶定單)的存儲格式。
XML 數據類型是功能完善的數據類型。它具有 SQL Server 中其他類型的所有能力和功能。這一點的重要性怎麼強調都不過分。作為一種功能完善的類型,XML 列可以進行索引,可以通過 XSD 架構(雖然不需要 XSD 架構)添加行和列的約束,還可以使用 T-SQL 中嵌入的 XQuery 表達式進行查詢。這些功能都已追加到 XQuery W3C 規范中。此外,使用 XMLdt::modify 方法,用戶還可以添加子樹、刪除子樹和更新標量值。
XML 數據類型很靈活。您可以選擇是否要將 XML 架構定義 (XSD) 架構與一列相關聯。當一個列具有 XSD 架構關聯時,它就稱為類型化 XML。如果沒有 XSD 關聯,它就是非類型化 XML。XSD 架構可用於在將 XML 列導入數據庫後,對其類型化。然後,它可以用來為系統目錄創建索引和其他元數據。在查詢時,類型化 XML 列比非類型化 XML 列更快,也更靈活。使用場景將決定 XML 列的類型,雖然大多數應用程序都偏向於 XSD 架構引用。
另請注意,您可以在同一列中存儲 XML 文檔和 XML 片段。此外,您還必須針對 XML 列創建特殊的“XML”索引。這將為標簽、值和 XML 值中的路徑創建索引。
創建 XML 列時,您應該添加一個 XSD 文檔並將其與該列關聯。XSD 架構關聯是從 SQL Server Workbench 內部執行的。XSD 關聯還可以使用 DDL:
CREATE TABLE T (pk INT, xCol('mySchema'))
將一個架構導入數據庫時,它被分析為各種類型的組件,包括 ELEMENT、ATTRIBUTE、TYPE(對於簡單類型或復雜類型)、ATTRIBUTEGROUP 和 MODELGROUP。然後,這些組件以及所有關聯的命名空間都將存儲到各種系統表中。您可以使用專用的系統視圖來查看這些組件。換句話說,架構不是原封不動地存儲起來的。這至少包含兩層意思。首先,架構標簽及其關聯的屬性並未存儲。而 XML 標簽屬性(targetNamespace、attributeFormDefault、elementFormDefault 等)都被重新分配給架構的組件。其次,SQL Server 不提供在導入後恢復和查看原始架構文檔的功能。建議您保留一份所有架構的副本,或將它們的內容存儲到專用的數據庫表中。為此,使用一個 XML 列就足夠了。此外,您還可以使用內置函
您正在看的SQLserver教程是:XML、T-SQL 和 CLR 攜手開創數據庫編程新天地。數 XML_SCHEMA_NAMESPACE ('uri') 來檢索 XML 架構。這將返回命名空間 'uri' 的內容。
當 XML 列和 XSD 架構組合在一起時,XML 數據的查詢功能將是常規關系型數據和查詢的補充。雖然我不建議您以 XML 的格式存儲所有數據,但是能夠在數據庫中使用 XML,還是使 XML 文檔的管理和其他應用場景大大簡化了。
現在數據已經存儲好了,我將轉到 XQuery 上來,因為不提它,我的討論將是不完整的。
返回頁首
XML 查詢語言,通常稱為 XQuery,是一種為查詢所有類型的 XML 數據而進行優化的智能、健壯的語言。借助 XQuery,您可以使用類型關聯的方法,對 XML 數據類型的變量和列運行查詢。通過調用查詢方法,您可以在同一批中跨關系型數據和 XML 數據進行查詢。
與許多 XML 標准一樣,XQuery 的開發(目前還是一個工作草案)是在 W3C 的指導下進行的。Yukon 支持 2001 年 12 月 20 日到 2002 年 11 月 15 日之間的 XQuery 1.0 工作草案的一個靜態類型化子集。要了解所有草案,請參閱 http://www.w3c.org。
XQuery 是從一種稱為 Quilt 的查詢語言演變而來的,該查詢語言以多種其他語言(如 XPath 1.0、XQL 和 SQL)為基礎。它還包含一個 XPath 2.0 的子集。您可以在 XPath 中使用現有的技巧,而無需學習一門全新的語言。然而,SQL Server Yukon 中包含了一些超越 Xpath 的重要增強功能,如特殊的函數和對更好的迭代、結果排序和構造的支持。
XQuery 語句由一個前導和語句體組成。前導包含一個或多個命名空間聲明,和/或為查詢處理創建上下文的架構導入。語句體包含一個指定查詢條件的表達式序列。
然後,這些語句將用在前面提到的 XML 數據類型的一個方法(query、value、exist 或 modify)中。XQuery 能夠查詢類型化 XML(與 XML 架構關聯的數據)以及 XML 文檔。
返回頁首
XQuery Designer 是一個新工具,它集成在新的 SQL Server Workbench 中,可以簡化 XML 數據的使用。XQuery Designer 有助於編寫查詢,從 XML 列和 XML 文檔中操作和檢索數據。XQuery Designer 的中心開發主題就是使用戶無需學習 XML Query 語言的細節就可以進行 XQuery 開發。有關運行中的 XQuery Designer,請參見sqlserver/art/XMLTsqlCLRfig01.gif" target="_blank">圖 1 所示。
到現在為止,我已談論了 Yukon 的新增 .Net 功能和 XML 功能。結合使用這些技術,可以創造新的機會來解決流行領域(如電子商務)中的應用場景。SQL Server 開發最近的關注點在分布式應用程序上,其中業務工作流和邏輯都要在數據庫應用程序中表示。使用 Yukon 中構建的對基於 Web 的應用程序的強大支持,讓我們深入探究一下此處講述的新功能。
返回頁首
在過去 10 年中,電子商務應用程序的迅速發展,產生了對提高跨數據庫應用程序流程管理水平的需求。如果您構建過定單輸入系統或在網上進行過購物,就會對工作流模型非常熟悉。當一個用戶為一本書下定單時,系統必須向庫存、發貨和信用卡系統提交一個事務,然後必須通過另一個 Web 應用程序發送定單確認信息。等待這些流程中每一個過程的同步不是很能好地伸縮。過去,開發人員必須編寫復雜的存儲過程,並使用遠程過程調用代碼將消息排入隊列。Yukon 為構建異步消息路由提供了一種新的、可伸縮的體系結構。
SQL Server 服務代理是一項 Yukon 技術,它允許內部或外部流程使用常規 T-SQL DML 的擴展來發送和接收有保證的異步消息。消息可以發送到與發送者共享的數據庫中的一個隊列內、同一個 SQL Server 實例中的另一個數據庫內,或同一台服務器上或遠程服務器上的另一個 SQL Server 實例內。
在傳統的消息處理系統中,應用程序負責消息的排序和協調。消息復制、同步化和排序都是企業級數據系統必須處理的困難問題。
SQL Server 服務代理可通過自動處理消息序列、唯一傳遞和會話標識,來解決這些問題。當會話在兩個服務代理終結點之間建立後,應用程序會按照消息發送的順序,對每個消息只接收一次。應用程序可以按順序處理一次消息,而無需附加代碼。服務代理會自動在每個消息中添加標識符。應用程序始終可以分辨出特定消息所屬的會話。
服務代理將消息排入隊列以進行傳遞。如果目標服務不能立即獲得,消息將重復發送服務和傳遞嘗試,直到消息發送成功。這可允許一個會話在兩個服務之間可靠地繼續傳遞下去,即使一個服務在會話期間的某個時刻暫時不可用。
SQL Server 服務代理提供了啟動方服務和目標服務之間的松耦合。服務可以將消息排入隊列,然後繼續它的應用程序處理任務,依賴 SQL Server 服務代理保證消息到達其目的地。這種松耦合帶來了調度上的靈活性。啟動方可以發出多個消息,並且多個目標服務可以並行地處理它們。每個目標服務都可以按自己的速度處理消息,這取決於系統目前的工作負荷。
排隊還允許系統將處理更加均衡地分布,以降低服務器所需的峰值能力。這可以整體提高數據庫應用程序的吞吐量和性能。例如,定單輸入應用程序可能會在每天中午遇到請求增加的情況,這會導致資源的大量消耗和緩慢的響應速度。通過服務代理,定單輸入應用程序在接收定單時不需要執行所有的定單處理。相反,應用程序可以輸入定單,然後提交請求以進行後台處理,如付帳、發貨和庫存管理。後台應用程序可靠地執行一段時間的處理,同時定單輸入應用程序繼續接收新的定單。
在消息處理應用程序中最難實現的一件事情就是,允許多個程序並行地從同一個隊列中讀取。這樣的情況將導致消息不按順序處理,即使它們是按順序接收的。
下面看一個傳統的定單處理應用程序。消息 A 包含創建定單標頭的相關指令,消息 B 包含創建定單行項目的相關指令,它們都是在隊列中接收的。如果這些消息都被單獨的服務程序實例取出隊列,並同時進行處理,定單行項目事務可能會首先嘗試提交,然後會因為定單還不存在而失敗。失敗會導致事務回滾,使消息又重新進入隊列並再次處理,從而浪費了資源。傳統情況下,這個問題是通過將消息 A 和消息 B 中的信息結合到一個消息中解決的。雖然這個方法對於這兩個消息很直接,但是在系統涉及要協調幾十個或幾百個消息時,它很難伸縮。
服務代理通過自動鎖定與同一任務有關的所有消息解決了這個問題,因此這些消息只能由一個服務程序實例接收和處理。同時,其他服務程序實例可以繼續將與其他任務相關的消息取出隊列並進行處理。這使多個並行服務程序能夠可靠且高效地工作。
服務代理最有用的功能之一是激活。激活可以在消息到達時,自動啟動一個服務程序,從隊列讀取消息。如果消息到達的速度比處理它們的速度快,系統就會啟動服務程序的其他實例,直至達到配置的最大值。如果消息到達的速度減慢了,活動的服務程序將檢查隊列,如果發現沒有消息需要處理,服務程序就會自己關閉。這使服務程序實例的數量能夠隨著服務負荷的更改進行動態地增加和減少。如果系統發生故障或重啟,當系統恢復時,將自動啟動服務程序來讀取隊列中的消息。傳統的消息處理系統缺乏這種行為,經常在給定時刻使專用於某個特定
您正在看的SQLserver教程是:XML、T-SQL 和 CLR 攜手開創數據庫編程新天地。隊列的資源不是太多就是太少。
服務代理的集成設計為應用程序的性能和管理提供了許多優勢。與 SQL Server 集成能夠使用事務性消息處理;也就是說,一個服務程序的每個循環(接收消息、處理消息和發送回復消息)可以封裝在一個數據庫事務中。如果事務失敗,所有工作都會回滾,已經接收的消息會重新排入隊列,以便進行另一次嘗試對其進行的處理。在應用程序提交事務之前,所有操作都不會生效。應用程序會保持一致狀態,而無需增加資源開銷和分布式事務協調器的復雜性。
當數據、消息和應用程序邏輯都在數據庫中時,管理就更簡單了。只有一項(而不是三個或四個單獨的組件)需要為災難恢復、群集、安全、備份等進行維護。例如,在傳統的消息處理系統中,消息存儲區和數據庫可能是不同步的。例如,當一個組件從備份中恢復時,另一個組件也必須同時從備份中恢復,否則消息存儲區和數據庫就可能不一致。讓消息和數據使用一個數據庫,這就不再是問題了。
使用公共開發環境也是一個優勢。應用程序的消息處理和數據部分可以使用服務代理應用程序中的同一種語言和工具。這使開發人員對數據庫編程技術的熟悉擴展到了基於消息的編程。實現服務代理服務的存儲過程可以用 T-SQL 或任一種以 CLR 為目標的語言編寫。
此外,數據庫集成使自動資源管理成為可能。服務代理在 SQL Server 實例的上下文中運行,因此代理可以維護所有准備從實例的所有數據庫中傳輸的消息的聚合視圖。這允許每個數據庫維護自己的隊列,同時還能在跨整個 SQL Server 實例的資源使用上保持平衡。
返回頁首
讓我們看看這些概念在定單輸入應用程序中是怎樣結合的,其中用戶在一個 Web 站點下定單。在服務之間傳送的消息存儲在一個 XML 列中。為了說明問題,我將使用一個基於 ASP.Net 的 Web 服務,該服務已在 SQL Server 中由一個 CLR 的實例注冊並寄存。該服務與一個合作伙伴通信,以發送和接收購買定單信息。使用消息的 XML 列可允許架構的封裝和簡化。
用戶在 Web 站點上下定單。當定單事務提交後,包含定單信息的消息會放入定單輸入服務隊列中。定單將以 XML 列的形式發送給定單輸入服務。這可將所有的定單信息合並到一列中。有關此流程的完整視圖,請參見圖 2。
定單輸入服務啟動事務,接收消息,然後處理它。然後,定單輸入服務向信用限制服務發送一個請求,以驗證信用狀態。如果沒問題,定單輸入服務將執行下一步。
定單輸入服務檢查定單中每一項的庫存。XQuery 會處理庫存檢查。此時,如果商品項可以發貨,將向發貨服務隊列發送一個消息。
發貨服務(一個 T-SQL 存儲過程)使用 XQuery 分析 XML 消息。用戶信息用於生成定單發貨。當發貨完成後,將向付帳服務隊列發送一個消息。當付帳服務隊列接收到“發貨完成”的消息後,將更新數據庫中的定單狀態,以表示定單已經發貨。所有來自和發送到定單輸入服務的消息都會寫到一個審計表中,供以後分析和解決問題使用。
從這個簡單的示例中,您可以看到如何使用新的 Yukon 可編程功能(XML、CLR、服務代理和 T-SQL 增強功能),來構建可靠、可伸縮和完整的數據庫應用程序。
返回頁首
我只是觸及了 Yukon 中幾個新的、激動人心的體系結構功能。數據庫開發人員從來都沒有在數據訪問和存儲上獲得這麼多的選擇。此 SQL Server 服務代理示例僅在結合 SQL Server 的新功能時著重說明了幾項功能。開始使用 SQL Server Yukon Beta 版並繼續關注 MSDN Magazine 未來的內容。只要有所了解,您就會使用 Yukon,而且再也不會走老路了。
Eric Brown 大約在 3 年前加盟 Microsoft 公司的 SQL Server 小組。此前,他供職於 greatfood.com 和其他小公司,從事數據庫開發工作。