国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

MS SQL SERVER2005 XML 最佳實踐

瀏覽:136日期:2023-11-02 09:29:09

SQL Server 2005 為 XML 數據處理提供了廣泛支持??梢詫?XML 值以本機方式存儲在 xml 數據類型列中,后者可以根據 XML 架構的集合進行類型化,也可以保持非類型化狀態??梢詫?XML 列創建索引。此外,通過使用 XQuery 和 XML DML 可支持精細的數據操作。XML DML 是針對數據修改的擴展。

SQL Server 2000 和 SQLXML Web 版本提供了強大的 XML 數據管理功能。這些功能著重于關系數據和 XML 數據之間的映射??梢允褂脦⒌?XSD (AXSD) 來定義關系數據的 XML 視圖,以提供以 XML 為中心的方法,該方法支持對 XML 數據執行大容量數據加載、查詢和更新功能。Transact-SQL 擴展提供了一個以 SQL 為中心的方法,以便使用 FOR XML 將關系查詢結果映射到 XML,以及使用 OPENXML 從 XML 生成關系視圖。這些支持已在 SQL Server 2005 中進行了擴展。結合新添加的本機 XML 支持,SQL Server 2005 提供了一個強大的平臺,以針對半結構化和非結構化數據管理開發功能豐富的應用程序。

本主題提供了 SQL Server 2005 中的 XML 數據建模和使用準則,包含下列兩個部分:

數據建模

可以通過使用本機 xml 數據類型和拆分到表中的 XML,以多種方式在 SQL Server 2005 中存儲 XML 數據。本主題提供了為對 XML 數據進行建模做出適當選擇的準則。另外,還介紹了對 XML 數據創建索引、屬性提升和 XML 實例的類型化。

使用

本部分討論了與使用相關的主題,例如將 XML 數據加載到服務器和查詢編譯中的類型推理。本部分還解釋和區分了密切相關的功能,并就如何適當使用這些功能提出了建議。這些均通過示例進行了說明。

數據建模本部分概述了應使用 SQL Server 2005 中的 XML 功能的理由,另外還提供了在本機 XML 存儲和 XML 視圖技術之間進行選擇的準則,并給出了數據建模建議。

關系或 XML 數據模型如果您的數據是高度結構化的,具有已知架構,則對于數據存儲,關系模型可能最適用。SQL Server 提供了您可能需要的必要功能和工具。另一方面,如果結構是半結構化或非結構化的或者未知的,則必須考慮對這類數據進行建模。

如果您需要一個與平臺無關的模型,以便通過使用結構和語義標記來確保數據的可移植性,則 XML 是一個不錯的選擇。此外,下列情況下,適于做此選擇:

您的數據為稀疏數據,或您不了解數據的結構,或數據結構將來可能會有重大變化。

您的數據體現的是包容層次結構而不是在實體間的引用,并且可能是遞歸數據。

您的數據本身具有順序性。

您希望基于數據的結構查詢數據或更新部分數據。

如果上述條件均不滿足,則應使用關系數據模型。例如,如果數據為 XML 格式,但應用程序只是使用數據庫來存儲和檢索數據,則只需要 [n]varchar(max) 列。將數據存儲在 XML 列中還有其他好處,包括讓引擎確定數據格式是否正確或有效,以及支持對 XML 數據進行精細查詢和更新。

在 SQL Server 2005 中存儲 XML 數據的理由下面是一些使用 SQL Server 2005 中的本機 XML 功能而不是在文件系統中管理 XML 數據的理由:

您希望以一種高效的事務處理方式來共享、查詢和修改 XML 數據。精細的數據訪問對于您的應用程序而言很重要。例如,您可能需要提取 XML 文檔中的某些部分,或者您可能需要插入新的部分而不是替換整個文檔。

您有關系數據和 XML 數據,希望在應用程序中進行關系數據和 XML 數據之間的互操作。

您需要語言支持,以便對于跨域應用程序可以進行查詢和數據修改。

您希望服務器能夠保證數據格式正確,并能夠視情況根據 XML 架構來驗證您的數據。

您希望對 XML 數據創建索引以實現高效的查詢處理和良好的可伸縮性,并使用一流查詢優化器。

您希望對 XML 數據進行 SOAP、ADO.NET 和 OLE DB 訪問。

您希望使用數據庫服務器的管理功能來管理 XML 數據。例如,這可能是備份、恢復和復制。

如果上述條件均不滿足,最好將數據存儲為非 XML 大型對象類型,如 [n]varchar(max) 或 varbinary(max)。

XML 存儲選項SQL Server 2005 中的 XML 存儲選項包括:

采用 xml 數據類型的本機存儲

數據以保留數據的 XML 內容的內部表示形式進行存儲,XML 內容包括包容層次結構、文檔順序、元素和屬性值等。具體來說,就是保留 XML 數據的 InfoSet 內容。有關 InfoSet 的詳細信息,請訪問 http://www.w3.org/TR/xml-infoset。InfoSet 內容并不是文本 XML 的精確副本,因為其中未保留下列信息:無關緊要的空格、屬性順序、命名空間前綴和 XML 聲明。

對于類型化的 xml 數據類型(即綁定到 XML 架構的 xml 數據類型),后架構驗證 InfoSet (PSVI) 將類型信息添加到 InfoSet,并以內部表示形式進行編碼。這會顯著提高分析速度。有關詳細信息,請參閱 http://www.w3.org/TR/xmlschema-1 和 http://www.w3.org/TR/xmlschema-2 上的 W3C XML 架構規范。

在 XML 和關系存儲之間映射

通過使用帶批注的架構 (AXSD),將 XML 分解到一個或多個表中的列。這可保留在關系級別上的數據保真度。因此,盡管忽略了元素間的順序,但仍保留了層次結構。架構不能是遞歸的。

大型對象存儲 [n]varchar(max) 和 varbinary(max)

存儲數據的精確副本。這對于特殊用途的應用(如法律文檔)很有用。大多數應用不需要完全相同的副本,且 XML 內容(InfoSet 保真度)即可滿足需要。

通常,您必須結合使用這些方法。例如,您可能需要將 XML 數據存儲在 xml 數據類型列中,并將其中的屬性提升到關系列中?;蛘?,您可能需要使用映射技術將非遞歸部分存儲到非 XML 列中,而只將遞歸部分存儲在 xml 數據類型列中。

XML 技術的選擇XML 技術(本機 XML 與 XML 視圖)的選擇通常取決于下列因素:

存儲選項

您的 XML 數據可能更適于大型對象存儲(例如,產品手冊),或更適于存儲在關系列中(例如,轉換為 XML 的行項)。每個存儲選項都在不同程度上保留文檔保真度。

查詢功能

您可能會發現,基于查詢的特性和對 XML 數據進行查詢的程度,某一個存儲選項比其他選項更合適。在兩個存儲選項中,對 XML 數據的精細查詢(例如,XML 節點上的謂詞評估)得到不同程度的支持。

對 XML 數據創建索引

您可能希望對 XML 數據創建索引以提高 XML 查詢的性能。索引選項隨存儲選項的不同而不同,您必須做出適當的選擇才能優化工作負荷。

數據修改功能

某些工作負荷涉及對 XML 數據進行精細修改。例如,在文檔中添加新的部分,而其他工作負荷(如 Web 內容)則不涉及。對于您的應用程序來說,數據修改語言支持可能很重要。

架構支持

您的 XML 數據可通過架構進行說明,該架構可能是 XML 架構文檔,也可能不是。對架構綁定的 XML 的支持取決于 XML 技術。

此外,不同的選擇具有不同的性能特征。

本機 XML 存儲您可以將 XML 數據存儲在服務器上的 xml 數據類型列中。下列情況下,適于做此選擇:

您希望使用一種簡單的方法將 XML 數據存儲在服務器上,同時保留文檔順序和文檔結構。

您可能有對應于您的 XML 數據的架構,也可能沒有。

您希望查詢和修改 XML 數據。

您希望對 XML 數據創建索引,以提高查詢處理的速度。

您的應用程序需要系統目錄視圖以管理您的 XML 數據和 XML 架構。

如果您的 XML 文檔具有多種結構,或您的 XML 文檔符合不同的或復雜的架構,而這些架構很難映射到關系結構,本機 XML 存儲很有用。

示例:使用 xml 數據類型對 XML 數據進行建模例如有一個 XML 格式的產品手冊,其中每個主題對應單獨的一章,而每章中又包含多節。一節可以包含多個小節。因此,<section> 是一個遞歸元素。產品手冊包含大量混合內容、關系圖和技術材料;數據是半結構化的。用戶可能希望對感興趣的主題執行上下文搜索,例如,在有關“索引”的章中搜索有關“聚集索引”的節,并查詢技術數量。

適于您的 XML 文檔的存儲模型是 xml 數據類型列。這可保留 XML 數據的 InfoSet 內容。對 XML 列創建索引有利于提高查詢性能。

示例:保留 XML 數據的精確副本為了進行說明,假定政府條例要求您保留 XML 文檔的精確文本副本。例如,這些文檔可能為簽署的文檔、法律文檔或股票交易單。您可能希望將文檔存儲在 [n]varchar(max) 列中。

查詢時,先在運行時將數據轉換為 xml 數據類型,然后對其執行 Xquery。運行時轉換開銷可能很高,尤其是在文檔較大的情況下。如果經常查詢,可以采取冗余方式將文檔存儲在 xml 數據類型列中,并對其創建索引,同時從 [n]varchar(max) 列中返回精確的文檔副本。

XML 列可以是基于 [n]varchar(max) 列的計算列。但不能對 XML 計算列創建 XML 索引,也不能對 [n]varchar(max) 或 varbinary(max) 列創建 XML 索引。

XML 視圖技術通過定義 XML 架構和數據庫中的表之間的映射,可以創建持久性數據的“XML 視圖”。通過 XML 視圖,可使用 XML 大容量加載來填充基礎表。您可以使用 XPath 1.0 版來查詢 XML 視圖;這種查詢將被轉換為針對表的 SQL 查詢。與此類似,更新也會被傳播到那些表。

在下列情況下,此技術很有用:

您希望擁有以 XML 為中心的編程模型,該模型使用現有關系數據上的 XML 視圖。

您有對應于您的 XML 數據的架構(XSD、XDR),該架構可能由外部伙伴提供。

數據中的順序并不重要,或查詢表數據不是遞歸的,或事先已知最大遞歸深度。

您希望使用 XPath 1.0 版通過 XML 視圖查詢和修改數據。

您希望通過 XML 視圖來大容量加載 XML 數據,并將其分解到基礎表。

相關示例包括顯示為用于數據交換和 Web 服務的 XML 的關系數據。有關詳細信息,請參閱 MSDN Online Library。

示例:使用帶批注的 XML 架構 (AXSD) 對數據進行建模為了進行說明,假定您具有希望將其作為 XML 處理的關系數據(如客戶、訂單和行項)。請使用 AXSD 在關系數據上定義 XML 視圖。通過使用 XML 視圖可以將 XML 數據大容量加載到表,以及使用 XML 視圖查詢和更新關系數據。如果必須在 SQL 應用程序不間斷工作時與其他應用程序交換包含 XML 標記的數據,該模型很有用。

混合模型通常,對于數據建模,適于結合使用關系列和 xml 數據類型列。可以將 XML 數據中的某些值存儲在關系列中,而將其余或全部 XML 值存儲在 XML 列中。這可獲得更好的性能,您可以更好地控制對關系列創建的索引和鎖定特征。

要存儲在關系列中的值取決于您的工作負荷。例如,如果基于路徑表達式 /Customer/@CustId 檢索所有 XML 值,則將 CustId 屬性的值提升到關系列并對其創建索引可以獲得更快的查詢性能。另一方面,如果您的 XML 數據是以非冗余方式廣泛地分解為關系列中,則重新匯集的開銷可能很大。

對于高度結構化的 XML 數據,例如,表的內容已轉換為 XML,您可以將所有值映射到關系列,并且可能使用 XML 視圖技術。

使用 xml 數據類型進行數據建模本部分討論有關本機 XML 存儲的數據建模主題,包括對 XML 數據創建索引、屬性提升和類型化的 xml 數據類型。

相同或不同的表可以在包含其他關系列的表中,或在與主表具有外鍵關系的單獨表中創建 xml 數據類型列。

如果滿足下列條件之一,請在同一個表中創建 xml 數據類型列:

您的應用程序對 XML 列執行數據檢索,并且不需要 XML 列的 XML 索引。

您希望對 xml 數據類型列生成 XML 索引,并且主表的主鍵與其聚集鍵相同。有關詳細信息,請參閱“對 xml 數據類型列創建索引”。

如果滿足下列條件,請在單獨的表中創建 xml 數據類型列:

您希望對 xml 數據類型列生成 XML 索引,但主表的主鍵與其聚集鍵不同,或主表沒有主鍵,或主表是一個堆(即沒有聚集鍵)。如果主表已存在,可能會這樣。

您不希望因為表中存在 XML 列而降低表掃描的速度。無論該列是存儲在行內還是行外,都會占用空間。

XML 數據的粒度XML 列中存儲的 XML 數據的粒度對鎖定至關重要,在一定程度上,對更新也很重要。SQL Server 對 XML 數據和非 XML 數據都使用相同的鎖定機制。因此,行級鎖定會導致鎖定行中的所有 XML 實例。當粒度較大時,鎖定大型 XML 實例以便進行更新會導致多用戶情況下的吞吐量下降。另一方面,過度分解會丟失對象封裝,并增加重新匯集開銷。

對于良好的設計而言,重要的是保持數據建模要求與鎖定和更新特征之間的平衡。但在 SQL Server 2005 中,實際存儲的 XML 實例的大小并不十分重要。

例如,通過使用對部分二進制大型對象 (BLOB) 和部分索引更新(將存儲的現有 XML 實例與其更新后的版本進行比較)的新支持,對 XML 實例進行更新。部分二進制大型對象 (BLOB) 更新在兩個 XML 實例之間執行差異比較,并只更新差異之處。部分索引更新只修改那些必須在 XML 索引中更改的行。

非類型化、類型化和約束的 xml 數據類型SQL Server 2005 xml 數據類型實現了 ISO SQL-2003 標準 xml 數據類型。因此,它可以在非類型化的 XML 列中存儲格式正確的 XML 1.0 版的文檔、具有文本節點和任意數量頂級元素的所謂的 XML 內容片段。系統將檢查數據格式是否正確,但不要求將列綁定到 XML 架構,并且拒絕在擴展意義上格式不正確的數據。對于非類型化的 XML 變量和參數也是如此。

如果您有說明 XML 數據的 XML 架構,則可以將架構與 XML 列相關聯以產生類型化的 XML。XML 架構用于驗證數據,在編譯查詢和數據修改語句過程中執行比非類型化的 XML 更精確的類型檢查,以及優化存儲和查詢處理。

在下列情況下,請使用非類型化的 xml 數據類型:

您沒有對應于您的 XML 數據的架構。

您有架構,但不希望服務器驗證數據。當應用程序在將數據存儲到服務器之前執行客戶端驗證時,或臨時存儲根據架構確定無效的 XML 數據時,或在服務器上使用不受支持的架構組件(如 key/keyref)時,有時會出現這種情況。

在下列情況下,請使用類型化的 xml 數據類型:

您有對應于您的 XML 數據的架構,并且希望服務器根據 XML 架構驗證 XML 數據。

您希望充分利用基于類型信息的存儲和查詢優化。

您希望在編譯查詢過程中更好地充分利用類型信息。

類型化的 XML 列、參數和變量可以存儲 XML 文檔或內容。但是,必須使用標志指定在聲明時是存儲文檔還是存儲內容。此外,必須提供 XML 架構集合。如果每個 XML 實例都剛好有一個頂級元素,請指定 DOCUMENT。否則,請使用 CONTENT。查詢編譯器在編譯查詢過程中的類型檢查中使用 DOCUMENT 標志以推斷單一的頂級元素。

除了對 XML 列進行類型化之外,還可以對類型化或非類型化的 xml 數據類型列使用關系(列或行)約束。在下列情況下,請使用約束:

無法在 XML 架構中表達業務規則。例如,花店的交貨地址必須在其營業地點周圍 50 英里之內。這可以編寫為 XML 列的約束。約束可能涉及 xml 數據類型方法。

您的約束涉及表中的其他 XML 列或非 XML 列。例如,強制使 XML 實例中的客戶 ID (/Customer/@CustId) 與 CustomerID 關系列中的值匹配。

文檔類型定義 (DTD)可以使用 XML 架構來對 xml 數據類型列、變量和參數進行類型化,但不能使用 DTD 進行此項操作。但是,內聯 DTD 既可用于非類型化的 XML,也可用于類型化的 XML,以便提供默認值,并將實體引用替換為其擴展形式。

可以通過使用第三方工具將 DTD 轉換為 XML 架構文檔,然后將 XML 架構加載到數據庫中。

對 xml 數據類型列創建索引可以對 xml 數據類型列創建 XML 索引。它將對列中 XML 實例的所有標記、值和路徑進行索引,從而提高查詢性能。在下列情況下,您的應用程序可以從 XML 索引中獲益:

對 XML 列進行查詢在您的工作負荷中很常見。必須考慮數據修改過程中的 XML 索引維護開銷。

XML 值相對較大,而檢索的部分相對較小。生成索引避免了在運行時分析所有數據,并且索引查找有利于進行高效的查詢處理。

XML 列的第一個索引是主 XML 索引。使用它時,可以對 XML 列創建三種類型的輔助 XML 索引,以提供常見種類的查詢的速度,如以下部分所述。

主 XML 索引這將對 XML 列中 XML 實例的所有標記、值和路徑進行索引。基表(即包含 XML 列的表)的主鍵必須具有聚集索引。主鍵用于將索引行與基表中的行相關聯。可從 XML 列中檢索完整的 XML 實例,例如 SELECT *。查詢使用主 XML 索引,并通過使用索引本身返回標量值或 XML 子樹。

示例:創建主 XML 索引在大多數示例中,使用包含非類型化的 XML 列的表 T (pk INT PRIMARY KEY, xCol XML)??梢圆捎煤唵蔚姆绞綄⑦@些示例擴展為類型化的 XML。有關如何使用類型化的 XML 的詳細信息,請參閱 xml 數據類型。為簡化起見,針對 XML 數據實例說明了查詢,如下所示:

復制代碼 <book genre='security' publicationdate='2002' ISBN='0-7356-1588-2'><title>Writing Secure Code</title><author>;;;<first-name>Michael</first-name>;;;<last-name>Howard</last-name></author><author>;;;<first-name>David</first-name>;;;<last-name>LeBlanc</last-name></author><price>39.99</price></book>

以下語句對表 T 的 XML 列 xCol 創建 XML 索引(名為 idx_xCol):

復制代碼 CREATE PRIMARY XML INDEX idx_xCol on T (xCol)

輔助 XML 索引創建了主 XML 索引之后,您可能希望創建輔助 XML 索引來提高工作負荷中不同種類查詢的速度。三種類型的輔助 XML 索引(即 PATH、PROPERTY 和 VALUE)分別用于優化基于路徑的查詢、自定義屬性管理方案和基于值的查詢。PATH 索引功能是按文檔順序對列中的所有 XML 實例生成各個 XML 節點的 (path, value) 對的 B+ 樹。PROPERTY 索引功能是創建各個 XML 實例中 (PK, path, value) 對的聚集 B+ 樹,其中 PK 是基表的主鍵。最后,VALUE 索引功能是按文檔順序對 XML 列中的所有 XML 實例創建每個節點的 (value, path) 對的 B+ 樹。

下面是創建一個或多個這些索引的一些準則:

如果工作負荷對 XML 列大量使用路徑表達式,則 PATH 輔助 XML 索引可能會提高工作負荷的處理速度。最常見的情況是在 Transact-SQL 的 WHERE 子句中對 XML 列使用 exist() 方法。

如果工作負荷通過使用路徑表達式從單個 XML 實例中檢索多個值,則在 PROPERTY 索引中聚集各個 XML 實例中的路徑可能會很有用。這種情況通常出現在屬性包方案中,此時提取對象的屬性并且已知其主鍵值。

如果工作負荷涉及查詢 XML 實例中的值,但不知道包含那些值的元素名稱或屬性名稱,則您可能希望創建 VALUE 索引。這通常出現在 descendant 軸查找中,例如 //author[last-name='Howard'],其中 <author> 元素可以出現在層次結構的任何級別上。這種情況也出現在通配符查詢中,例如 /book [@* = 'novel'],其中查詢將查找具有某個值為“novel”的屬性的 <book> 元素。

示例:基于路徑的查找為了進行說明,假定以下查詢在您的工作負荷中很常見:

復制代碼 SELECT pk, xColFROMTWHERE; xCol.exist ('/book/@genre[.='novel']') = 1

路徑表達式 /book/@genre 和值“novel”對應于 PATH 索引的鍵字段。因此,PATH 類型的輔助 XML 索引對此工作負荷很有用:

復制代碼 CREATE XML INDEX idx_xCol_Path on T (xCol)USING XML INDEX idx_xCol FOR PATH

示例:提取對象的屬性例如,下面的查詢從表 T 中的各行檢索書的屬性 genre、title 和 ISBN:

復制代碼 SELECT xCol.value ('(/book/@genre)[1]', 'varchar(50)'),;xCol.value ('(/book/title/text())[1]', 'varchar(50)'),;xCol.value ('(/book/@ISBN)[1]', 'varchar(50)')FROM;T

在這種情況下,屬性索引很有用,其創建方式如下:

復制代碼 CREATE XML INDEX idx_xCol_Property on T (xCol)USING XML INDEX idx_xCol FOR PROPERTY

示例:基于值的查詢在下面的查詢中,descendant-or-self (//) 指定部分路徑,以便基于 ISBN 值的查找從 VALUE 索引的使用中獲益。

復制代碼 SELECT xColFROM;TWHERE;xCol.exist ('//book/@ISBN[. = '0-7356-1588-2']') = 1

VALUE 索引的創建方式如下:

復制代碼 CREATE XML INDEX idx_xCol_Value on T (xCol)USING XML INDEX idx_xCol FOR VALUE

對 XML 列的全文索引您可以對 XML 列創建一個全文索引,該索引對 XML 值的內容進行索引,但忽略 XML 標記。屬性值不在全文索引范圍內,因為它們被視為標記的一部分,并且元素標記被用作標記邊界。如有可能,可以按下列方式將全文搜索和 XML 索引結合起來:

首先,使用 SQL 全文搜索篩選感興趣的 XML 值。

然后,查詢那些使用 XML 列的 XML 索引的 XML 值。

示例:將全文搜索和 XML 查詢結合起來對 XML 列創建了全文索引后,下面的查詢將檢查 XML 值是否在書的標題中包含“custom”一詞:

復制代碼 SELECT * FROMT WHERE; CONTAINS(xCol,'custom') AND;xCol.exist('/book/title/text()[contains(.,'custom')]') =1

contains() 方法使用全文索引來將文檔中任何位置包含“custom”一詞的 XML 值組合為一個子集。exist() 子句確保“custom”一詞出現在書的標題中。

使用 contains() 的全文搜索與 XQuery contains() 具有不同語義。后者是子字符串匹配,前者是使用詞干匹配的標記匹配。因此,如果搜索標題中包含“run”的字符串,則匹配結果將包括“run”、“runs”和“running”,因為同時滿足全文 contains() 和 Xquery contains()。但是,查詢不匹配標題中的“customizable”一詞,因為全文 contains() 失敗,而滿足 Xquery contains()。通常,對于純子字符串匹配,應刪除全文 contains() 子句。

此外,全文搜索使用詞干匹配,而 XQuery contains() 是文字匹配。這一區別在下一個示例中進行說明。

示例:使用詞干匹配對 XML 值進行全文搜索通常不能消除上一個示例中執行的 XQuery contains() 檢查。請看下面的查詢:

復制代碼 SELECT * FROMT WHERE; CONTAINS(xCol,'run')

因為使用了詞干匹配,所以文檔中的“ran”一詞匹配搜索條件。此外,不通過使用 XQuery 來檢查搜索上下文。

當通過使用 AXSD 將 XML 分解為全文索引的關系列時,對 XML 視圖執行的 XPath 查詢不對基礎表執行全文搜索。

屬性提升如果主要是對少數元素和屬性值進行查詢,您可能希望將那些數量提升到關系列。檢索整個 XML 實例,但只對一小部分 XML 數據進行查詢時,這很有用。不必對 XML 列創建 XML 索引。但可以對提升的列創建索引。必須編寫查詢來使用提升的列。也就是說,查詢優化器不會將對 XML 列的查詢再定向到提升的列。

提升的列可以是同一個表中的計算列,也可以是表中用戶維護的單獨列。從每個 XML 實例提升單一值時,這就足夠了。但是,對于多值屬性,則必須為屬性創建單獨的表,如以下部分所述。

基于 xml 數據類型的計算列可以使用調用 xml 數據類型方法的用戶定義函數來創建計算列。計算列的類型可以是任何 SQL 類型,包括 XML。下面的示例說明了這一點。

示例:基于 xml 數據類型方法的計算列為書的 ISBN 號創建用戶定義函數:

復制代碼 CREATE FUNCTION udf_get_book_ISBN (@xData xml)RETURNS varchar(20)BEGINDECLARE @ISBNvarchar(20)SELECT @ISBN = @xData.value('/book[1]/@ISBN', 'varchar(20)')RETURN @ISBN END

在表中為 ISBN 添加計算列:

復制代碼 ALTER TABLE;;;TADDISBN AS dbo.udf_get_book_ISBN(xCol)

可以按通常的方式對計算列創建索引。

示例:對基于 xml 數據類型方法的計算列的查詢若要獲得其 ISBN 為 0-7356-1588-2 的 <book>:

復制代碼 SELECT xColFROMTWHERE; xCol.exist('/book/@ISBN[. = '0-7356-1588-2']') = 1

可以重新編寫對 XML 列的查詢以使用計算列,如下所示:

復制代碼 SELECT xColFROMTWHERE; ISBN = '0-7356-1588-2'

您可以創建返回 xml 數據類型的用戶定義函數,并使用用戶定義函數來創建計算列。但是,不能對 XML 計算列創建 XML 索引。

創建屬性表您可能希望將 XML 數據中的某些多值屬性提升到一個或多個表中,對那些表創建索引,并再次定向查詢以使用這些表。典型的情況是少數屬性占了大部分查詢工作負荷。您可以執行下列操作:

創建一個或多個表來保存多值屬性。您會發現可以很方便做到:每個表存儲一個屬性,以及在屬性表中復制基表的主鍵以便與基表進行后向聯接。

如果希望維護屬性的相對順序,必須為相對順序引入一個單獨的列。

為 XML 列創建觸發器以維護屬性表。在觸發器中,執行下列操作之一:

使用 xml 數據類型方法(如 nodes() 和 value())來插入和刪除屬性表的行。

在公共語言運行時 (CLR) 中創建流式表值函數來插入和刪除屬性表的行。

編寫對屬性表進行 SQL 訪問的查詢和對基表中的 XML 列進行 XML 訪問的查詢,這些表之間通過主鍵聯接起來。

示例:創建屬性表為了進行說明,假定您希望提升作者的名字。書有一個或多個作者,因此名字為多值屬性。每個名字都存儲在屬性表的單獨行中。在屬性表中復制基表的主鍵以便進行后向聯接。

復制代碼 create table tblPropAuthor (propPK int, propAuthor varchar(max))

示例:創建用戶定義函數以從 XML 實例生成行集以下表值函數 udf_XML2Table 接受主鍵值和 XML 實例。它檢索 <book> 元素的所有作者的名字,然后返回主鍵-名字對行集。

復制代碼 create function udf_XML2Table (@pk int, @xCol xml)returns @ret_Table table (propPK int, propAuthor varchar(max))with schemabindingasbegin;;;insert into @ret_Table;;;;select @pk, nref.value('.', 'varchar(max)');;;from@xCol.nodes('/book/author/first-name') R(nref);;;returnend

示例:創建觸發器以填充屬性表插入觸發器將行插入屬性表:

復制代碼 create trigger trg_docs_INS on T for insertas;;;declare @wantedXML xml;;;declare @FK int;;;select @wantedXML = xCol from inserted;;;select @FK = PK from insertedinsert into tblPropAuthorselect * from dbo.udf_XML2Table(@FK, @wantedXML)

刪除觸發器根據刪除行的主鍵值刪除屬性表中的行:

復制代碼 create trigger trg_docs_DEL on T for deleteasdeclare @FK intselect @FK = PK from deleteddelete tblPropAuthor where propPK = @FK

更新觸發器根據更新的 XML 實例刪除屬性表中的現有行,然后將新行插入屬性表:

復制代碼 create trigger trg_docs_UPDon Tfor updateasif update(xCol) or update(pk)begin;;;declare @FK int;;;declare @wantedXML xml;;;select @FK = PK from deleted;;;delete tblPropAuthor where propPK = @FKselect @wantedXML = xCol from insertedselect @FK = pk from insertedinsert into tblPropAuthor;;;;select * from dbo.udf_XML2Table(@FK, @wantedXML)end

示例:查找其作者名字為“David”的 XML 實例可以對 XML 列執行查詢。此外,也可以在屬性表中搜索名字“David”,然后與基表進行后向聯接以返回 XML 實例。例如:

復制代碼 SELECT xCol FROM;;T JOIN tblPropAuthor ON T.pk = tblPropAuthor.propPKWHERE;tblPropAuthor.propAuthor = 'David'

示例:使用 CLR 流式表值函數的解決方案此解決方案包括下列步驟:

定義 CLR 類 SqlReaderBase,它實現 ISqlReader,并通過在 XML 實例上應用路徑表達式來生成流式表值輸出。

創建程序集和 Transact-SQL 用戶定義函數來啟動該 CLR 類。

通過使用用戶定義函數來定義插入、更新和刪除觸發器,以維護屬性表。

若要如此,首先創建流式 CLR 函數。xml 數據類型顯示為 ADO.NET 中的托管類 SqlXml,支持返回 XmlReader 的 CreateReader() 方法。

注意:; 本部分中的示例代碼使用了 XPathDocument 和 XPathNavigator。這些都強制要求您將所有 XML 文檔加載到內存中。如果您要在您的應用程序中使用類似代碼來處理多個大型 XML 文檔,此代碼并不可伸縮。而是應盡可能保持較小的內存分配并使用流式接口。有關性能的詳細信息,請參閱 Architecture of CLR Integration。

復制代碼 public class c_streaming_xml_tvf {public static ISqlReader streaming_xml_tvf (SqlXml xmlDoc, string pathExpression) {;;;return (new TestSqlReaderBase (xmlDoc, pathExpression));}}// Class that implements ISqlReaderpublic class TestSqlReaderBase : ISqlReader {XPathNodeIterator m_iterator;;public SqlChars FirstName;// Metadata for current resultsetprivate SqlMetaData[] m_rgSqlMetaData; public TestSqlReaderBase (SqlXml xmlDoc, string pathExpression) { // Variables for XPath navigation;;;XPathDocument xDoc;;;;XPathNavigator xNav;;;;XPathExpression xPath; // Set sql meta data;;;m_rgSqlMetaData = new SqlMetaData[1];;;;m_rgSqlMetaData[0] = new SqlMetaData ('FirstName',; SqlDbType.NVarChar,50);;//Set up the Navigator;;;if (!xmlDoc.IsNull); xDoc = new XPathDocument (xmlDoc.CreateReader());;;;else; xDoc = new XPathDocument ();;;;xNav = xDoc.CreateNavigator();;;;xPath = xNav.Compile (pathExpression);;;;m_iterator = xNav.Select(xPath);}public bool Read() {;;;bool moreRows = true;;;;if (moreRows = m_iterator.MoveNext()) FirstName = new SqlChars (m_iterator.Current.Value);;;;return moreRows;}}

然后,創建程序集和與 CLR 函數 streaming_xml_tvf 對應的 Transact-SQL 用戶定義函數 SQL_streaming_xml_tvf(不顯示)。該用戶定義函數用于定義表值函數 CLR_udf_XML2Table 以便生成行集:

復制代碼 create function CLR_udf_XML2Table (@pk int, @xCol xml)returns @ret_Table table (FK int, FirstName varchar(max))with schemabindingasbegin;;;insert into @ret_Table;select @pk, FirstName;FROMSQL_streaming_xml_tvf (@xCol, '/book/author/first-name');;;returnend

最后,定義觸發器,如“創建觸發器以填充屬性表”示例中所示,但用 CLR_udf_XML2Table 函數替換了 udf_XML2Table。以下示例中顯示了插入觸發器:

復制代碼 create trigger CLR_trg_docs_INS on T for insertasdeclare @wantedXML xmldeclare @FK intselect @wantedXML = xCol from insertedselect @FK = PK from insertedinsert into tblPropAuthor;;;select *from;dbo.CLR_udf_XML2Table(@FK, @wantedXML)

刪除觸發器與非 CLR 版本相同。但是,更新觸發器只是用 CLR_udf_XML2Table() 函數替換了函數 udf_XML2Table()。

XML 架構集合XML 架構集合是關系架構作用域內的元數據實體。它包含一個或多個可能相關(如通過 <xs:import>)也可能無關的 XML 架構。XML 架構集合中各個 XML 架構通過使用其目標命名空間來標識。

XML 架構集合是通過使用 CREATE XML SCHEMA COLLECTION (Transact-SQL) 語法并提供一個或多個 XML 架構來創建??梢酝ㄟ^使用 ALTER XML SCHEMA COLLECTION (Transact-SQL) 語法,將多個 XML 架構組件添加到現有 XML 架構中,并將多個架構添加到 XML 架構集合中。可以通過使用 SQL Server 2005 中的安全模式像任何 SQL 對象那樣保證 XML 架構集合的安全。

多類型化列XML 架構集合 C 根據多個 XML 架構對 XML 列 xCol 進行類型化。此外,DOCUMENT 標志和 CONTENT 標志指定是否可以將 XML 樹或片段分別存儲在 xCol 列中。

對于 DOCUMENT,每個 XML 實例都指定實例中頂級元素的目標命名空間,XML 實例根據它來進行類型化和驗證。另一方面,對于 CONTENT,每個頂級元素都可以指定 C 中任何一個目標命名空間。XML 實例根據實例中存在的所有目標命名空間來進行驗證和類型化。

架構演變XML 架構集合用于對 XML 列、變量和參數進行類型化。它提供了 XML 架構演變的機制。為了進行說明,假定您將具有目標命名空間 BOOK-V1 的 XML 架構添加到 XML 架構集合 C 中。使用 C 類型化的 XML 列 xCol 可以存儲符合 BOOK-V1 架構的 XML 數據。

然后,假定某個應用程序希望用新的架構組件(如復雜類型定義和頂級元素聲明)擴展 XML 架構??梢詫⑦@些新的架構組件添加到 BOOK-V1 架構中,并且不需要重新驗證 xCol 列中的現有 XML 數據。

假定該應用程序以后希望提供新版本的 XML 架構,并且它選擇目標命名空間 BOOK-V2??梢詫⒋?XML 架構添加到 C 中。XML 列可以存儲 BOOK-V1 和 BOOK-V2 的實例,并且可以對符合這些命名空間的 XML 實例執行查詢和數據修改。

加載 XML 數據將 XML 數據從 SQL Server 2000 傳輸到 SQL Server 2005您可以采用多種方式將 XML 數據傳輸到 SQL Server 2005。例如:

如果將數據存儲在 SQL Server 2000 數據庫中的 [n]text 或 image 中,則可以使用 SQL Server Integration Services 將表導入 SQL Server 2005 數據庫中。使用 ALTER TABLE 語句將列類型更改為 XML。

可以使用 bcp out 從 SQL Server 2000 大容量復制數據,然后使用 bcp in 將數據大容量插入 SQL Server 2005 數據庫中。

如果將數據存儲在 SQL Server 2000 數據庫的關系列中,請創建具有 [n]text 列和(可選)用于行標識符的主鍵列的新表。使用客戶端編程檢索在服務器上通過 FOR XML 生成的 XML,并將其寫入 [n]text 列。然后,使用上述方法將數據傳輸到 SQL Server 2005 數據庫中。您可以選擇將 XML 直接寫入 SQL Server 2005 數據庫中的 XML 列。

示例:將列類型更改為 XML假定您希望將 R 表中的 [n]text 列或 image 列 XYZ 的類型更改為非類型化的 XML。以下語句執行此類型更改:

復制代碼 ALTER TABLE R ALTER COLUMN XYZ XML

如果需要,可以通過指定 XML 架構集合將目標為類型化為 XML。

大容量加載 XML 數據可以通過使用 SQL Server 的大容量加載功能(如 bcp)將 XML 數據大容量加載到服務器中。通過使用 OPENROWSET 可以將文件中的數據加載到 XML 列中。以下示例說明了這一點。

示例:從文件中加載 XML此示例顯示了如何在表 T 中插入行。從文件 C:MyFilexmlfile.xml 中將 XML 列的值作為 CLOB 加載,并為整數列提供了值 10。

復制代碼 INSERT INTO TSELECT 10, xColFROM;(SELECT *;;;;;FROM OPENROWSET (BULK 'C:MyFilexmlfile.xml', SINGLE_CLOB); AS xCol) AS R(xCol)

文本編碼SQL Server 2005 以 Unicode (UTF-16) 存儲 XML 數據。從服務器檢索的 XML 數據均采用 UTF-16 編碼。如果需要采用不同的編碼,必須對檢索到的數據執行所需的轉換。有時,XML 數據可能采用不同的編碼。如果是這樣,加載數據時必須非常小心。例如:

如果文本 XML 采用 Unicode(UCS-2、UTF-16),可以將其賦給 XML 列、變量或參數,不會有任何問題。

如果由于源代碼頁的原因,編碼不是 Unicode 而是隱式的,則數據庫中的字符串代碼頁應與要加載的碼位相同或與其兼容。如果需要,請使用 COLLATE。如果不存在這樣的服務器代碼頁,則必須添加使用正確編碼的顯式 XML 聲明。

若要使用顯式編碼,請使用 varbinary() 類型(它與代碼頁沒有任何交互),或使用字符串類型的相應代碼頁。然后,將數據賦給 XML 列、變量或參數。

示例:顯式指定編碼假定您有一個 XML 文檔 vcdoc,它存儲為沒有顯式 XML 聲明的 varchar(max)。以下語句添加編碼為“iso8859-1”的 XML 聲明,將 XML 文檔串聯起來,將結果轉換為 varbinary(max) 以便保留字節表示形式,最終將其轉換為 XML。這樣,XML 處理器就可以根據指定的編碼“iso8859-1”分析數據,并為字符串值生成相應的 UTF-16 表示形式。

復制代碼 SELECT CAST( CAST (('<?xml version='1.0' encoding='iso8859-1'?>'+ vcdoc) AS VARBINARY (MAX)); AS XML)

XQuery 和類型推理Transact-SQL 中嵌入的 XQuery 語言支持查詢 xml 數據類型。該語言正在由萬維網聯盟 (W3C) 開發,Microsoft 的所有主要數據庫供應商都參與其中。它包含了 XPath 2.0 版作為導航語言。同時,還提供了針對 xml 數據類型的數據修改語言構造。有關 SQL Server 中支持的 XQuery 構造、函數和運算符的詳細信息,請參閱針對 xml 數據類型的 XQuery 函數。

錯誤模型語法不正確的 Xquery 表達式和 XML DML 語句會返回編譯錯誤。編譯階段會檢查 XQuery 表達式和 DML 語句的靜態類型正確性,并針對類型化的 XML 使用 XML 架構進行類型推理。如果表達式在運行時由于類型安全沖突而失敗,會引起靜態類型錯誤。靜態錯誤的示例包括將字符串添加到整數,以及在不存在的節點中查詢類型化的數據。

與 W3C 標準有所不同的是,XQuery 運行時錯誤被轉換為空序列。這些序列根據調用上下文,可以作為空 XML 或 NULL 傳播到查詢結果。

通過顯式轉換為正確的類型,用戶可以解決靜態錯誤的問題,盡管運行時轉換錯誤將被轉換為空序列。

下列部分詳細介紹了類型檢查。

單一性檢查如果編譯器無法確定是否在運行時保證單一性,則要求單一性的位置步驟、函數參數和運算符將返回錯誤。此問題經常出現在非類型化數據上。例如,對屬性的查找需要單一的父元素。選擇單個父節點的序號即可滿足需要。計算 node()-value() 組合以提取屬性值可能不需要指定序號。如以下示例中所示。

示例:已知單一性在此示例中,nodes() 方法為每個 <book> 元素生成一個單獨的行。對 <book> 節點進行計算的 value() 方法提取 @genre 值,其作為屬性,具有單一性。

復制代碼 SELECT nref.value('@genre', 'varchar(max)') LastNameFROMT CROSS APPLY xCol.nodes('//book') AS R(nref)

XML 架構用于對類型化的 XML 進行類型檢查。如果某個節點指定為 XML 架構中單一的節點,則編譯器將使用該信息,并且不會發生任何錯誤。否則,需要選擇單個節點的序號。特別的情況是,使用 descendant-or-self (//)(如在 /book//title 中)會丟失 <title> 元素的單一性基數推理,即使 XML 架構指定其如此。因此,您應該將其重寫為 (/book//title)[1]。

對于類型檢查,務必注意 //first-name[1] 和 (//first-name)[1] 之間的差異。前者返回一組 <first-name> 節點,其中每個節點都是其同級節點間最左側的 <first-name> 節點。后者返回 XML 實例中按文檔順序的第一個單一的 <first-name> 節點。

示例:使用 value()下面對非類型化的 XML 列的查詢導致發生靜態的編譯錯誤。這是因為 value() 希望將一個單一節點作為第一個參數,而編譯器無法確定在運行時是否將僅有一個 <last-name> 節點:

復制代碼 SELECT xCol.value('//author/last-name', 'nvarchar(50)') LastNameFROMT

可以考慮下面的解決辦法:

復制代碼 SELECT xCol.value('//author/last-name[1]', 'nvarchar(50)') LastNameFROMT

但是,該解決辦法不解決錯誤,因為在每個 XML 實例中可能會有多個 <author> 節點。采用下面的重寫代碼可以解決問題:

復制代碼 SELECT xCol.value('(//author/last-name/text())[1]', 'nvarchar(50)') LastNameFROMT

此查詢返回每個 XML 實例中第一個 <last-name> 元素的值。

parent 軸如果無法確定節點的類型,它將成為 anyType。這不會隱式轉換為任何其他類型。在使用 parent 軸(如 xCol.query('/book/@genre/../price'))進行導航的過程中,尤其會發生這種情況。父節點類型確定為 anyType。在 XML 架構中,也可以將元素定義為 anyType。在這兩種情況下,丟失更為精確的類型信息經常會導致發生靜態類型錯誤,并需要將原子值顯式轉換為其特定類型。

Data()、text() 和 string() 取值函數XQuery 有一個從節點提取類型化標量值的函數 fn:data()、一個返回文本節點的節點測試 text(),以及一個返回節點的字符串值的函數 fn:string()。它們的用法容易混淆。以下是在 SQL Server 2005 中正確使用它們的準則。使用 XML 實例 <age>12</age> 進行說明。

非類型化的 XML:路徑表達式 /age/text() 返回文本節點“12”。函數 fn:data(/age) 返回字符串值“12”,fn:string(/age) 也是如此。

類型化的 XML:對于任何簡單的類型化的 <age> 元素,表達式 /age/text() 都返回靜態錯誤。另一方面,fn:data(/age) 返回整數 12。fn:string(/age) 產生字符串“12”。

聯合類型的函數和運算符由于類型檢查,聯合類型要求進行小心地處理。下列示例中說明了其中兩個問題。

示例:聯合類型的函數例如,以下聯合類型的 <r> 的元素定義:

復制代碼 <xs:element name='r'><xs:simpleType><xs:union memberTypes='xs:int xs:float xs:double'/></xs:simpleType></xs:element>

在 XQuery 上下文中,“average”函數 fn:avg (//r) 返回靜態錯誤,因為 XQuery 編譯器無法對 fn:avg() 的參數中的 <r> 元素的不同類型(xs:int、xs:float 或 xs:double)的值求和。為了解決此問題,請將函數調用重寫為 fn:avg(for $r in //r return $r cast as xs:double ?)。

示例:聯合類型的運算符加法運算(“+”)要求使用精確類型的操作數。因此,表達式 (//r)[1] + 1 返回靜態錯誤,該錯誤包含前面所述的 <r> 元素的類型定義。一個解決方法是將其重寫為 (//r)[1] cast as xs:int? +1,其中“?”表示取值 0 或 1。SQL Server 2005 要求帶有“?”的“cast as”,因為任何轉換都可能由于運行時錯誤導致產生空序列。

Value()、Nodes() 和 OpenXML()您可以在 SELECT 子句中對 xml 數據類型使用多個 value() 方法以生成所提取值的行集。nodes() 方法為可用于其他查詢的每個所選節點生成一個內部引用。生成行集時,如果行集有多個列且用于生成行集的路徑表達式比較復雜,結合使用 nodes() 和 value() 方法可能會更有效。

nodes() 方法生成特定 xml 數據類型的實例,每個實例的上下文都設置為不同的所選節點。這種 XML 實例支持 query()、value()、nodes() 和 exist() 方法,并可用于 count(*) 聚合。所有其他用法都會導致錯誤。

示例:使用 nodes()假定您希望提取作者的名字和姓氏,而名字不是“David”。此外,您希望提取該信息作為一個包含兩列 FirstName 和 LastName 的行集。通過使用 nodes() 方法和 value() 方法便可以完成該操作,如下所示:

復制代碼 SELECT nref.value('(first-name/text())[1]', 'nvarchar(50)') FirstName,;;;;nref.value('(last-name/text())[1]', 'nvarchar(50)') LastNameFROMT CROSS APPLY xCol.nodes('//author') AS R(nref)WHERE; nref.exist('first-name[. != 'David']') = 1

在此示例中,nodes('//author') 生成一個由對每個 XML 實例的 <author> 元素引用組成的行集。通過計算與那些引用相關的 value() 方法,即可獲得作者的名字和姓氏。

SQL Server 2000 提供了通過使用 OpenXml() 從 XML 實例生成行集的功能。您可以指定行集的關系架構,以及如何將 XML 實例中的值映射到行集中的列。

示例:對 xml 數據類型使用 OpenXml()可以通過使用 OpenXml() 重寫上一個示例中的查詢,如下所示。方法是創建一個游標,該游標將每個 XML 實例讀取到 XML 變量,然后向其應用 OpenXML:

復制代碼 DECLARE name_cursor CURSORFORSELECT xCol;FROMTOPEN name_cursorDECLARE @xmlVal XMLDECLARE @idoc intFETCH NEXT FROM name_cursor INTO @xmlValWHILE (@@FETCH_STATUS = 0)BEGINEXEC sp_xml_preparedocument @idoc OUTPUT, @xmlValSELECT*FROMOPENXML (@idoc, '//author'); WITH (FirstName; varchar(50) 'first-name',;;;;;LastNamevarchar(50) 'last-name') RWHERE; R.FirstName != 'David'EXEC sp_xml_removedocument @idocFETCH NEXT FROM name_cursor INTO @xmlValENDCLOSE name_cursorDEALLOCATE name_cursor

OpenXml() 創建一個內存中的表示形式,并且使用工作表而不是查詢處理器。它依賴于 MSXML 3.0 版的 XPath 1.0 版處理器,而不是 XQuery 引擎。工作表不在對 OpenXml() 的多個調用間共享(即使是在同一個 XML 實例上)。這就限制了它的可伸縮性。在未指定 WITH 子句時,可以通過 OpenXml() 訪問 XML 數據的邊緣表格式。另外,也可以通過它在單獨的“overflow”列中使用其余的 XML 值。

將 nodes() 和 value() 函數結合起來可有效地使用 XML 索引。因此,與 OpenXml 相比,這種結合有更高的可伸縮性。

使用 FOR XML 從行集生成 XML可以通過在 FOR XML 中使用新的 TYPE 指令,從行集生成 xml 數據類型實例。

可以將結果賦給 xml 數據類型列、變量或參數。另外,可以嵌套 FOR XML 以生成任何層次結構。這使得嵌套的 FOR XML 比 FOR XML EXPLICIT 更容易編寫,但對于較深的層次結構,它的性能可能不太好。FOR XML 還引入了新的 PATH 模式。這個新模式指定某個列的值在 XML 樹中的路徑。

可以使用新的 FOR XML TYPE 指令,采用 SQL 語法來定義關系數據上的只讀 XML 視圖。可以使用 SQL 語句和嵌入式 XQuery 查詢該視圖,如下面的示例所示。另外,您還可以在存儲過程中引用這些 SQL 視圖。

示例:返回生成的 xml 數據類型的 SQL 視圖以下 SQL 視圖定義對關系列 pk 和從 XML 列中檢索到的書作者創建 XML 視圖:

復制代碼 CREATE VIEW V (xmlVal) ASSELECT pk, xCol.query('/book/author')FROMTFOR XML AUTO, TYPE

V 視圖包含一個行,該行只有一個 XML 類型的 columnxmlVal。可以查詢像常規 xml 數據類型實例那樣對它進行查詢。例如,下面的查詢返回名字為“David”的作者:

復制代碼 SELECT xmlVal.query('//author[first-name = 'David']')FROMV

SQL 視圖定義與使用帶批注的架構創建的 XML 視圖有些相似。但二者之間存在重要的差異。SQL 視圖定義是只讀的,且必須使用嵌入式 XQuery 來操作。XML 視圖是通過使用帶批注的架構創建的。此外,SQL 視圖在應用 XQuery 表達式之前具體化 XML 結果,而對 XML 視圖的 XPath 查詢是對基礎表計算 SQL 查詢。

添加業務邏輯可以采用多種方式將業務邏輯添加到 XML 數據中:

您可以編寫行或列約束,以在插入和修改 XML 數據時強制實施特定于域的約束。

您可以在 XML 列上編寫插入或更新列中的值時激發的觸發器。該觸發器可以包含特定于域的驗證規則或填充屬性表。

您可以采用托管代碼編寫 SQLCLR 函數并將向其傳遞 XML 值,并且使用 System.Xml 命名空間提供的 XML 處理功能。例如,將 XSL 轉換應用到 XML 數據。另外,您可以將 XML 反序列化為一個或多個托管類,并使用托管代碼對它們進行操作。

您可以編寫 Transact-SQL 存儲過程和函數,對 XML 列進行處理以滿足業務需要。

示例:應用 XSL 轉換例如,CLR 函數 TransformXml(),它接受 xml 數據類型實例和文件中存儲的 XSL 轉換,將轉換應用到 XML 數據,然后在結果中返回轉換的 XML。以下是用 C# 編寫的主干函數:

復制代碼 public static SqlXml TransformXml (SqlXml XmlData, string xslPath) {// Load XSL transformationXslCompiledTransform xform = new XslCompiledTransform();XPathDocument xslDoc = new XPathDocument (xslPath);xform.Load(xslDoc);// Load XML data;XPathDocument xDoc = new XPathDocument (XmlData.CreateReader());// Return the transformed valueMemoryStream xsltResult = new MemoryStream();xform.Transform(xDoc, null, xsltResult);SqlXml retSqlXml = new SqlXml(xsltResult);return (retSqlXml);}

在注冊了程序集并創建了與 TransformXml() 對應的用戶定義 Transact-SQL 函數 SqlXslTransform() 之后,就可以從 Transact-SQL 中調用該函數,如下面的查詢所示:

復制代碼 SELECT SqlXslTransform (xCol, 'C:MyFilexsltransform.xsl')FROM;TWHERE; xCol.exist('/book/title/text()[contains(.,'custom')]') =1

查詢結果包含轉換的 XML 的行集。

SQLCLR 擴展了這樣一些功能:將 XML 數據分解到多個表或屬性提升,以及通過使用 System.Xml 命名空間中的托管類查詢 XML 數據。有關詳細信息,請參閱 SQL Server 聯機叢書和 .Net Framework SDK 文檔。

跨域查詢當您的數據同時保存在關系和 xml 數據類型列中時,您可能希望編寫將關系和 XML 數據處理結合起來的查詢。例如,您可以通過使用 FOR XML 將關系列和 XML 列中的數據轉換為 xml 數據類型實例,并使用 XQuery 對其進行查詢。相反,您可以從 XML 值生成行集,并使用 Transact-SQL 對其進行查詢。

一種編寫跨域查詢的更方便且有效的方法是在 XQuery 或 XML DML 表達式中使用 SQL 變量或列的值:

您可以在 XQuery 或 XML DML 表達式中,通過使用 sql:variable() 來使用 SQL 變量的值。

您可以在 XQuery 或 XML DML 表達式中,通過使用 sql:column() 來使用關系列中的值。

通過這兩種方法,應用程序可以對查詢進行參數化,如以下示例所示。但在 sql:variable() 和 sql:column() 中不允許使用 XML 和用戶定義類型。

示例:使用 sql:variable() 的跨域查詢下面的查詢是“示例:對基于 xml 數據類型方法的計算列的查詢”中所示查詢的修改版本。在下面的版本中,使用 SQL 變量 @isbn 傳入了此特定 ISBN。通過將常量替換為 sql:variable(),可以使用查詢來搜索任何 ISBN,而不僅是 ISBN 為 0-7356-1588-2 的書。

復制代碼 DECLARE @isbn varchar(20)SET;;@isbn = '0-7356-1588-2'SELECT; xColFROM;TWHERExCol.exist ('/book/@ISBN[. = sql:variable('@isbn')]') = 1

可以用相似的方式使用 sql:column(),它提供了其他好處??梢允褂昧械乃饕齺硖岣咝?,這由基于開銷的查詢優化器決定。另外,計算列可以存儲提升的屬性。

用于本機 XML 支持的目錄視圖目錄視圖用于提供有關 XML 用法的元數據信息。以下部分中討論了其中某些視圖。

XML 索引XML 索引項位于目錄視圖 sys.indexes 中,索引“type”為 3。名稱列包含 XML 索引的名稱。

另外,XML 索引還記錄在目錄視圖 sys.xml_indexes 中。此視圖包含 sys.indexes 的所有列和對 XML 索引有用的某些特定列。secondary_type 列中的值 NULL 表示主 XML 索引;值“P”、“R”和“V”分別表示 PATH、PROPERTY 和 VALUE 輔助 XML 索引。

可以在表值函數 sys.dm_db_index_physical_stats 中找到 XML 索引的空間使用情況。它提供了所有索引類型的相關信息,例如,占用的磁盤頁數、平均行大小(字節)和記錄數。其中也包括 XML 索引。對于每個數據庫分區,都提供此信息。XML 索引使用基表的相同分區方案和分區函數。

檢索 XML 架構集合XML 架構集合在目錄視圖 sys.xml_schema_collections 中枚舉出來。XML 架構集合“sys”由系統定義。它包含無需顯式加載即可在所有用戶定義的 XML 架構集合中使用的預定義命名空間。此列表包含 xml、xs、xsi、fn 和 xdt 的命名空間。另外兩個目錄視圖是 sys.xml_schema_namespaces(它枚舉每個 XML 架構集合中的所有命名空間)和 sys.xml_components(它枚舉每個 XML 架構中的所有 XML 架構組件)。

內置函數 XML_SCHEMA_NAMESPACE(schemaName、XmlSchemacollectionName、namespace-uri)生成 xml 數據類型實例。此實例包含在 XML 架構集合中所包含架構(預定義的 XML 架構除外)的 XML 架構片段。

可以按下列方式枚舉 XML 架構集合的內容:

編寫對 XML 架構集合的相應目錄視圖的 Transact-SQL 查詢。

使用內置函數 XML_SCHEMA_NAMESPACE()。您可以對此函數的輸出應用 xml 數據類型方法。但不能修改基礎 XML 架構。

這些在下列示例中進行了說明。

示例:枚舉 XML 架構集合中的 XML 命名空間對 XML 架構集合“myCollection”使用下面的查詢:

復制代碼 SELECT XSN.nameFROM;sys.xml_schema_collections XSC JOIN sys.xml_schema_namespaces XSN;ON (XSC.xml_collection_id = XSN.xml_collection_id)WHERE;XSC.name = 'myCollection'

示例:枚舉 XML 架構集合的內容以下語句枚舉關系架構 dbo 中的 XML 架構集合“myCollection”的內容。

復制代碼 SELECT XML_SCHEMA_NAMESPACE (N'dbo', N'myCollection')

通過將目標命名空間指定為 XML_SCHEMA_NAMESPACE() 的第三個參數,可以按 xml 數據類型實例的形式獲得集合中的單個 XML 架構。如下面的示例所示。

示例:從 XML 架構集合輸出指定的架構以下語句從關系架構 dbo 中的 XML 架構集合“myCollection”輸出目標命名空間為“http://www.microsoft.com/books”的 XML 架構。

復制代碼 SELECT XML_SCHEMA_NAMESPACE (N'dbo', N'myCollection', N'http://www.microsoft.com/books')

查詢 XML 架構可以按下列方式查詢加載到 XML 架構集合的 XML 架構:

編寫對 XML 架構命名空間的目錄視圖的 Transact-SQL 查詢。

創建包含 xml 數據類型列的表以存儲 XML 架構,并將這些架構加載到 XML 類型系統中??梢酝ㄟ^使用 xml 數據類型方法查詢 XML 列。另外,還可以對此列生成 XML 索引。但是,使用此方法時,應用程序必須保持 XML 列中存儲的 XML 架構和 XML 類型系統之間的一致性。例如,如果從 XML 類型系統中刪除 XML 架構命名空間,還必須從表中刪除它以保持一致性。

標簽: Sql Server 數據庫
主站蜘蛛池模板: 成人国产精品久久久免费 | 亚洲欧美激情在线 | 国产伦精品一区二区三区免费 | 欧美日韩一区二区三区在线播放 | 国产免费自拍视频 | 免费区欧美一级毛片 | 中文字幕色站 | 欧美成人久久久免费播放 | 亚洲欧美日韩综合久久久久 | 日本免费一区视频 | 18视频网站在线观看 | 三级色网| 国产精品亚洲专一区二区三区 | 久久狠狠一本精品综合网 | 久久精品国产一区二区三区不卡 | av国产精品 | 最新精品亚洲成a人在线观看 | 国产午夜久久影院 | 国产精品色综合久久 | 99精品久久精品一区二区 | 初爱视频教程在线观看高清 | 一级毛片无毒不卡直接观看 | 欧美一级视频免费 | 老司机午夜性生免费福利 | 久久亚洲网 | 亚洲免费一 | 成年人在线视频观看 | www成人国产在线观看网站 | 国产高清a毛片在线看 | 久久久网站亚洲第一 | 精品在线播放视频 | 成人毛片在线视频 | 国产永久在线视频 | 免费一级a毛片免费观看欧美大片 | 欧美一级免费看 | 国产精品一区二区久久精品涩爱 | 国产一级一片免费播放i | 国产免费久久精品99re丫y | 性盈盈影院在线观看 | 欧美黑人巨大最猛性xxxxx | 亚洲欧美精品一区天堂久久 |