国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
DCMS先鋒論壇-SQL Server 2005中的XML的最佳實(shí)踐
SQL Server 2005中的XML的最佳實(shí)踐http://www.soft.e531.com/printpage.asp?BoardID=6&ID=57
以文本方式查看主題

-  DCMS先鋒論壇  (http://www.soft.e531.com/index.asp)
--  Sql Server技術(shù)交流  (http://www.soft.e531.com/list.asp?boardid=6)
----  SQL Server 2005中的XML的最佳實(shí)踐  (http://www.soft.e531.com/dispbbs.asp?boardid=6&id=57)

--  作者:admin
--  發(fā)布時間:2005-10-21 21:25:57

--  SQL Server 2005中的XML的最佳實(shí)踐

Microsoft SQL Server 2005 對XML數(shù)據(jù)處理提供了廣泛的支持。XML值可以以原生的形式存儲在具有XML數(shù)據(jù)類型的列中,它們可以是有類型的XML(typed XML),或者是無類型的XML(untyped XML)。你可以對XML列添加索引。此外,還可以使用XQuery和XML DML來精細(xì)地操作數(shù)據(jù),后者已成為數(shù)據(jù)修改功能的擴(kuò)展。


Microsoft SQL Server 2000和SQLXML web版提供了強(qiáng)大的XML數(shù)據(jù)管理能力。他們主要體現(xiàn)在關(guān)系型數(shù)據(jù)和XML數(shù)據(jù)的映射上。關(guān)系型數(shù)據(jù)的XML視圖可以用帶注解的XSD(AXSD)定義,來提供一個以XML為中心的方法用以支持?jǐn)?shù)據(jù)的大量裝載,查詢,以及對xml數(shù)據(jù)的改寫能力。T-SQL擴(kuò)展提供了一個以SQL為中心的方法來實(shí)現(xiàn)關(guān)系型的查詢結(jié)果映射成XML(使用FOR XML子句),以及從XML來生成關(guān)系型視圖(用OpenXML)。這些支持將在SQL Server 2005中得到更多的擴(kuò)展。加上最新增加的原生XML支持功能,SQL Server 2005提供了一個強(qiáng)大的平臺用來開發(fā)和管理半結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)應(yīng)用。

本文檔提供了一些SQL Server 2005中XML數(shù)據(jù)建模和使用的指導(dǎo)。它分為以下兩個主題:

·數(shù)據(jù)建模

  XML數(shù)據(jù)可以以多種形式儲存在SQL Server 2005中,例如,可以將原生XML數(shù)據(jù)類型或者是一個XML文檔數(shù)據(jù)的一部分存儲在表中。這個主題將指導(dǎo)大家如何正確的數(shù)據(jù)建模,還將涉及到如何對XML數(shù)據(jù)進(jìn)行索引,屬性提升(property promotion,),XML實(shí)例的類型化。

·用法

  這個主題將討論XML數(shù)據(jù)使用方面的內(nèi)容,諸如裝載XML數(shù)據(jù)到server中,輸入推論在查詢編輯中(and type inference in query compilation);解釋和區(qū)分相近的特性;對這些特性的建議用法。還用例子來做個演示。

如果想更好的閱讀本文檔,建議先對SQL Server中的XML特性有個基本的了解??梢圆榭?a target="_blank">XML Support in Microsoft SQL Server 2005.

數(shù)據(jù)建模

這一部分簡要的介紹了在SQL Server 2005中使用XML的原因,并對如何選擇原生XML存儲或XML視圖技術(shù)提供了一些指導(dǎo),和數(shù)據(jù)建模方面的建議。

關(guān)系型還是XML數(shù)據(jù)模型

如果數(shù)據(jù)具有高度的結(jié)構(gòu)化和熟悉的架構(gòu),那么采用關(guān)系型模型存儲數(shù)據(jù)更合適。微軟SQL Server為此提供了必要的功能和相應(yīng)的工具。另一方面,如果數(shù)據(jù)結(jié)構(gòu)很靈活(半結(jié)構(gòu)化或無結(jié)構(gòu)化)或者結(jié)構(gòu)未知,那你就必須為這些數(shù)據(jù)考慮合適的數(shù)據(jù)模型。

XML是個好的選擇,如果你還希望這個數(shù)據(jù)模型是平臺獨(dú)立的,數(shù)據(jù)能夠在結(jié)構(gòu)化和語義標(biāo)記間保持靈活的話。此外,如果考慮到下面幾個因素的話,就更合適了:

·數(shù)據(jù)稀疏,或者數(shù)據(jù)結(jié)構(gòu)未知,或者是數(shù)據(jù)結(jié)構(gòu)將來會有較大的改變。

·數(shù)據(jù)需要表現(xiàn)出層次性(并非實(shí)體之間的引用)且可能有遞歸。

·數(shù)據(jù)內(nèi)含順序特性。

·你希望根據(jù)數(shù)據(jù)的結(jié)構(gòu)來查詢或更改部分?jǐn)?shù)據(jù)。

如果你不需要滿足上面這些條件,那么你應(yīng)該選擇關(guān)系型數(shù)據(jù)模型。例如,如果你的數(shù)據(jù)是XML格式的,但應(yīng)用程序僅僅是存儲和檢索它,那么一個[n]varchar(max)列足夠了。將數(shù)據(jù)存儲在XML列有額外的優(yōu)點(diǎn):存儲引擎會檢查數(shù)據(jù)是否具有良好的格式、合法性,且支持對XML數(shù)據(jù)的精細(xì)的查詢和修改。

SQL Server 2005存儲XML數(shù)據(jù)的原因

下面是選擇在SQL Server 2005中存儲XML數(shù)據(jù)而非在文件系統(tǒng)中管理XML數(shù)據(jù)的原因:

·你希望能利用數(shù)據(jù)庫服務(wù)器的管理特性來管理XML數(shù)據(jù)(如,備份、恢復(fù)、復(fù)制)。

·你希望能夠以有效的、交易化的方式來共享、查詢和修改XML數(shù)據(jù)。對你的應(yīng)用程序而言,精細(xì)的數(shù)據(jù)訪問很重要。例如,你可能希望提取XML文檔中的某一部分,或者是希望插入一個新的部分而不是替換整個文檔。

·你已有關(guān)系型的數(shù)據(jù)和應(yīng)用程序,并且你希望在你的應(yīng)用程序中關(guān)系型數(shù)據(jù)和XML數(shù)據(jù)間能互操作,你需要一個能夠在整個應(yīng)用程序中查詢和修改數(shù)據(jù)的語言。

·你希望服務(wù)器能夠保證數(shù)據(jù)的良好結(jié)構(gòu)性,且能根據(jù)XML架構(gòu)驗(yàn)證數(shù)據(jù)。

·你希望能夠?qū)ML數(shù)據(jù)添加索引來獲得更有效的查詢處理和更好的擴(kuò)展性。

·你希望能夠用SOAP、ADO.NET、OLE DB來訪問XML數(shù)據(jù)。

如果不存在上面這些情況,把數(shù)據(jù)存儲為非XML的,大對象類型的如[n]varchar(max) 或 varbinary(max)更為合適。不然,你還是應(yīng)該采用XML來存儲數(shù)據(jù)。

XML存儲選項(xiàng)

SQL Server 2005中XML數(shù)據(jù)存儲選項(xiàng)如下:

·作為XML數(shù)據(jù)類型來存儲:

這種存儲方式將保留XML數(shù)據(jù)的內(nèi)容,如層次性、文檔順序、元素和屬性值等。特別是XML數(shù)據(jù)的InfoSet內(nèi)容被保留(更多InfoSet信息,請參見http://www.w3.org/TR/xml-infoset)。它不是XML文本的原樣拷貝,它忽略了一些信息:無意義的空格、屬性的順序、命名空間前綴、XML聲明。

對有類型的XML數(shù)據(jù)類型(也就是說XML數(shù)據(jù)類型和XML架構(gòu)相關(guān)聯(lián)),post-schema validation Infoset (PSVI,它將類型信息加入Infoset)被編碼到XML數(shù)據(jù)的內(nèi)部表示中,這將顯著提高語法分析速度。(更多信息,請查閱W3C架構(gòu)規(guī)范http://www.w3.org/TR/xmlschema-1http://www.w3.org/TR/xmlschema-2)。

·把XML數(shù)據(jù)映射成關(guān)系型數(shù)據(jù)來存儲:

通過AXSD,XML數(shù)據(jù)被分解到一個或多個表的列中,在關(guān)系級別上忠實(shí)的保留了數(shù)據(jù)——層次結(jié)構(gòu)被保留,然而元素的順序被忽略了。架構(gòu)不可被回歸,操作不可逆。

·大對象存儲([n]varchar(max)varbinary(max)):

這種方式是XML數(shù)據(jù)的原樣拷貝。這種方法對于一些特定的應(yīng)用很有用,如法律文本的保存。大多數(shù)應(yīng)用并不需要原樣拷貝,忠實(shí)的Infoset XML內(nèi)容就足夠了。

一般來說,可能需要把這幾種方式結(jié)合起來使用。例如,你可能需要把XML數(shù)據(jù)存儲在XML數(shù)據(jù)類型列中,并且要把其屬性提升到關(guān)系型的列中。反過來說,你也可能希望使用映射技術(shù)來將非遞歸的部分存儲在非XML的列中,在XML數(shù)據(jù)類型列中只存儲遞歸部分。

XML技術(shù)的選擇

在選擇原生XML還是XML視圖時,一般需要考慮下面幾個因素:

·存儲選項(xiàng):

  你的XML數(shù)據(jù)可能適合采用大對象存儲(如,產(chǎn)品手冊),也可能適合存儲在關(guān)系型的數(shù)據(jù)列中(如行項(xiàng)目轉(zhuǎn)化為XML數(shù)據(jù))。每種存儲選項(xiàng)對文檔忠實(shí)度的保留程度也不一樣。

·查詢能力:

  由于你的查詢XML數(shù)據(jù)的需要,你可能會覺得某種存儲方式比另外的更適合。例如,對XML節(jié)點(diǎn)的謂詞評估,在不同的存儲選項(xiàng)中對此支持的程度也不同。

·XML數(shù)據(jù)索引:

你可能希望索引XML數(shù)據(jù)以提高XML查詢性能。不同的存儲選項(xiàng)有著不同的索引方法,你需要選擇一個合適的方法來優(yōu)化應(yīng)用。

·數(shù)據(jù)修改能力:

某些應(yīng)用需要對XML數(shù)據(jù)能夠精細(xì)的修改(如,在一個XML文檔中增加一個新的部分),     有的則不需要(如web內(nèi)容管理)。語言對數(shù)據(jù)修改能力的支持可能對你的應(yīng)用程序很重要。

·架構(gòu)支持:

你的XML數(shù)據(jù)可能需要用架構(gòu)來描述,它可能是一個XML架構(gòu)文檔,也可能不是。不同的XML技術(shù)對架構(gòu)綁定的XML支持也不同。

很明顯,不同的選擇會導(dǎo)致系統(tǒng)有不同的性能表現(xiàn)。

原生XML存儲

你可以存儲XML數(shù)據(jù)在數(shù)據(jù)庫服務(wù)器的XML數(shù)據(jù)類型列中,這種存儲方式適用于:

·你希望有種直截了當(dāng)?shù)姆椒ò裍ML數(shù)據(jù)存儲在服務(wù)器中,同時保留XML文檔的順序和結(jié)構(gòu)。

·你的XML數(shù)據(jù)可能有架構(gòu)與其相關(guān)聯(lián)。

·你希望能夠查詢和修改XML數(shù)據(jù)。

·你希望能夠?qū)ML數(shù)據(jù)加索引以提高查詢速度。

·你的應(yīng)用程序需要系統(tǒng)編目視圖來管理XML數(shù)據(jù)和XML架構(gòu)。

如果你的XML文檔結(jié)構(gòu)很大,或者XML文檔需要和不同的XML架構(gòu)、復(fù)雜的XML架構(gòu)
相符合,很難被映射為關(guān)系型結(jié)構(gòu),這時原生XML存儲會很有用。

例:用XML數(shù)據(jù)類型對XML數(shù)據(jù)建模

想象一下這個場景:產(chǎn)品手冊采用XML格式,每個主題有各自的章節(jié),每章中有多個段落(section)。段落還包含子段落,因此<section>是個遞歸的元素(element)。產(chǎn)品手冊還包含大量的混合內(nèi)容、圖表、技術(shù)資料等,數(shù)據(jù)是半結(jié)構(gòu)化的。用戶希望能夠?qū)Ω信d趣的主題執(zhí)行語義查找(如”indexing”章節(jié)中的”clustered index”段落),這里,對XML文檔的合適的存儲模型是XML數(shù)據(jù)類型列。這將保留XML數(shù)據(jù)的Infoset內(nèi)容,并且可以對XML加索引提高查詢速度。

例:保持XML數(shù)據(jù)的原樣拷貝

假如政府規(guī)章(XML文檔格式)要求完全的原樣拷貝(如,簽署的文檔、法律文檔、股票交易單等),你可能需要存儲該文檔在[n]varchar(max)列中。

對查詢而言,SQL Server將在運(yùn)行是轉(zhuǎn)化數(shù)據(jù)為XML數(shù)據(jù),并且對其執(zhí)行Xquery操作。運(yùn)行時的轉(zhuǎn)化可能非常消耗資源,特別是當(dāng)文檔很大時。如果你需要頻繁的查詢,你應(yīng)該額外存儲文檔在一個XML數(shù)據(jù)列中,并對其加索引,僅在需要原樣文檔時才從[n]varchar(max)列中取得。

XML列可以是基于[n]varchar(max)列的計(jì)算列。你不能在XML計(jì)算列上創(chuàng)建XML索引,然而,你也不能在[n]varchar(max)varbinary(max) 列上創(chuàng)建XML索引。

XML視圖技術(shù)

借助于在XML架構(gòu)和數(shù)據(jù)庫的表之間定義映射,你可以為永久數(shù)據(jù)(不被改寫的)創(chuàng)建“XML視圖”。XML大容量裝載功能可以被用來往使用XML視圖的基礎(chǔ)表上裝填數(shù)據(jù)。你可以使用XPath 1.0 查詢XML視圖,該查詢被翻譯成施加在表上的SQL查詢。同樣的,改寫也是這么做的。

這項(xiàng)技術(shù)適用于下面幾種場合:

·你希望你的編程模型以XML為中心,這樣你可以使用XML視圖在已存在的關(guān)系型表上。

·你的XML數(shù)據(jù)有架構(gòu)對應(yīng)(XSD, XDR),該架構(gòu)是你的外部合作伙伴所提供的。

·XML數(shù)據(jù)的順序不重要,或者是需查詢的數(shù)據(jù)不是遞歸的,或者是將來的最大遞歸深度已知。

·你希望使用XPath 1.0 來通過XML視圖查詢和修改數(shù)據(jù)。

·你希望能大容量裝載XML數(shù)據(jù)并且能把它分解到使用XML視圖的基表中。

關(guān)系型的數(shù)據(jù)被暴露為XML數(shù)據(jù)用于數(shù)據(jù)交換和web service,帶固定架構(gòu)的XML數(shù)據(jù)。更多信息,請參見the SQLXML Developer Center.

例:使用帶注解的XML架構(gòu)(AXSD)對數(shù)據(jù)建模

假設(shè)你已有關(guān)系型數(shù)據(jù)(諸如客戶信息,訂單信息),你希望把它作為XML數(shù)據(jù)來操作。你可以在關(guān)系型數(shù)據(jù)上使用AXSD來定義一個XML視圖。這個XML視圖允許你大量導(dǎo)入XML數(shù)據(jù)到表中,并且能夠借助它查詢和修改關(guān)系型數(shù)據(jù)。如果你需要和其他應(yīng)用程序交換XML數(shù)據(jù),同時不影響SQL應(yīng)用程序的正常運(yùn)行,采用這種建模非常有用。

混合模型

常見的數(shù)據(jù)建模情況是結(jié)合了關(guān)系型和XML數(shù)據(jù)類型的混合模型。XML數(shù)據(jù)中的一些值可以存儲在關(guān)系型的數(shù)據(jù)列中,剩余的、也可以是全部的XML值被存儲在XML列中。這會導(dǎo)致較好的性能(如,你可以完全控制關(guān)系型列上的索引)和鎖的特性。然而,你必須對管理數(shù)據(jù)的存儲付出更多的勞動。

怎樣把值存儲在關(guān)系型列中依賴于你的實(shí)際情況。例如,如果你基于路徑表達(dá)式/Customer/@CustId檢索整個XML值,接著提升(promotingCustId屬性值到關(guān)系型列中,對該列加索引,將會得到很快的查詢速度。另一方面, 如果你的XML數(shù)據(jù)被徹底的且不帶冗余的分解到關(guān)系型的列中,重新拼裝的代價可能會很高。

對于那些有著高度結(jié)構(gòu)化的XML數(shù)據(jù)(如,表的內(nèi)容可以被轉(zhuǎn)換成XML數(shù)據(jù)),你可以使用XML視圖技術(shù)映射所有的值到關(guān)系型的列中。

使用XML數(shù)據(jù)類型的數(shù)據(jù)建模這一部分將討論原生XML存儲方式下的數(shù)據(jù)建模。包括:索引XML數(shù)據(jù)、屬性提升(property promotion)、有類型(typed)的XML數(shù)據(jù)類型。

同一個表中或不同表

XML數(shù)據(jù)類型列可以關(guān)系型列在一個表中共存,也可以單獨(dú)在另一張表中,通過主外鍵的方式和主表相聯(lián)。

當(dāng)滿足下面條件時,可以創(chuàng)建XML數(shù)據(jù)類型列和關(guān)系型列在同一張表中:

·應(yīng)用程序從XML數(shù)據(jù)列上檢索數(shù)據(jù),但并不要求其上有XML索引

或者

·你希望在XML數(shù)據(jù)類型列上構(gòu)建索引,主表的主鍵就是表的聚集索引。

當(dāng)滿足下面條件時,在另一張表中創(chuàng)建XML數(shù)據(jù)類型列:

·你希望在XML數(shù)據(jù)類型列上構(gòu)建XML索引,但主表的主鍵不是聚集索引,或者主表沒有主鍵,或者主表沒有聚集索引。

·你不希望由于表中XML列的原因?qū)е卤頀呙杷俣认陆?,不管它是in-row存儲還是out-of-row存儲。

XML數(shù)據(jù)粒度

存儲在XML列中的XML數(shù)據(jù)粒度對鎖和改寫特性至關(guān)重要。SQL Server 采用同樣的鎖機(jī)制對XML數(shù)據(jù)和非XML數(shù)據(jù),因此,行級鎖將造成一行中的所有XML實(shí)例被鎖。當(dāng)粒度較大時,更大的XML實(shí)例被鎖將導(dǎo)致在多用戶環(huán)境下的吞吐量下降。另一方面,過度的分解(粒度較?。?dǎo)致對象封裝的丟失和重新拼裝代價的提高。

在數(shù)據(jù)建模需求和鎖、改寫特性之間的平衡,對一個好的設(shè)計(jì)是非常重要的。

無類型、有類型和受約束的XML數(shù)據(jù)類型

SQL Server 2005 XML數(shù)據(jù)類型實(shí)現(xiàn)了ISO SQL-2003所定義的 標(biāo)準(zhǔn)XML數(shù)據(jù)類型。同樣,它可以存儲良好結(jié)構(gòu)的XML 1.0 文檔,以及所謂的帶文本節(jié)點(diǎn)和任意數(shù)量的頂級元素的XML內(nèi)容片段在無類型的XML列中。系統(tǒng)會檢查數(shù)據(jù)是否是良好結(jié)構(gòu)的,并不要求該列被綁定到XML架構(gòu)上,同時在引伸意義(extended sense)拒絕不具備良好結(jié)構(gòu)的數(shù)據(jù)。這對無類型的XML變量和參數(shù)也一樣。

如果你有XML架構(gòu)來描述XML數(shù)據(jù),你將能夠把架構(gòu)和XML列關(guān)聯(lián)起來產(chǎn)生有類型(typed)XML。相對于無類型的XML而言,在查詢和數(shù)據(jù)修改語句的編譯時,XML架構(gòu)被用來校驗(yàn)數(shù)據(jù),執(zhí)行更精確的類型檢查,此外,它還能優(yōu)化查詢和存儲處理。

在下面情況下使用無類型的XML數(shù)據(jù)類型:

·你的XML數(shù)據(jù)沒有架構(gòu)

·你有XML架構(gòu),但你不希望服務(wù)器校驗(yàn)數(shù)據(jù)。有時有這種情況:應(yīng)用程序在存儲數(shù)據(jù)到服務(wù)器之前在客戶端校驗(yàn)數(shù)據(jù),或者是臨時地根據(jù)架構(gòu)存儲非法的XML數(shù)據(jù),或者是服務(wù)器不支持這種架構(gòu)成分(如key/keyref)。

在下面情況下使用有類型的XML數(shù)據(jù)類型:

·你的XML數(shù)據(jù)有XML架構(gòu),同時你還希望服務(wù)器能根據(jù)XML架構(gòu)校驗(yàn)XML數(shù)據(jù)。

·你希望能夠根據(jù)類型信息在存儲和查詢方面的得到好處

·你希望在編譯查詢時得到

有類型的XML列,參數(shù)和變量都能夠存儲XML文檔或者內(nèi)容,只要你在聲明時分別的指定標(biāo)記(DOCUMENT 或 CONTENT),此外,你還可以提供XML架構(gòu)集。如果每個XML實(shí)例都有完整的一個頂級元素,那么指定DOCUMENT,否則指定CONTENT。查詢編譯器在編譯時使用DOCUMENT標(biāo)記進(jìn)行類型檢查,推斷出單獨(dú)的頂級元素。

除了類型化一個XML列之外,你還可以使用關(guān)系型的約束(列約束或者是行約束)在有類型或者是無類型的XML數(shù)據(jù)類型列上,通常使用在下面的場合:

·你的商業(yè)規(guī)則不能被表示為XML架構(gòu)。例如下面這個商業(yè)規(guī)則,花店的送貨地址必須在花店的50英里之內(nèi)。這時我們可以把它作為約束在XML列上。約束必須包含XML數(shù)據(jù)類型方法。

·你的約束包含表中的其他XML列或非XML列,一個例子是客戶ID的強(qiáng)制性(/Customer/@CustId),它被建立在一個XML實(shí)例上,用來匹配關(guān)系型CustomerID列的值。

文檔類型定義(DTD

XML數(shù)據(jù)類型列,變量和參數(shù)可以用XML架構(gòu)來類型化,但不能用DTD來做。然而,行內(nèi)(inline)的DTD可以被用來對有類型和無類型的XML提供默認(rèn)值,和替換實(shí)體引用。

你可以使用第三方工具轉(zhuǎn)換DTDs為XML架構(gòu)文檔,再把它加載到數(shù)據(jù)庫中。


--  作者:admin
--  發(fā)布時間:2005-10-21 21:32:39

--  

索引XML數(shù)據(jù)類型列

可以在XML數(shù)據(jù)類型列上創(chuàng)建XML索引。它將索引列中XML實(shí)例的所有標(biāo)簽(tags)、值和路徑,并且提高了查詢性能。在下面的場合中,應(yīng)用程序?qū)腦ML索引中受益:

·你的工作常要查詢XML列。在數(shù)據(jù)被修改時的XML索引維護(hù)成本必須要考慮進(jìn)去。

·XML值比較大同時要檢索的部分比較小,建立索引將避免解析整個數(shù)據(jù),從而提高查詢效率。

在XML列上所建的第一個索引被稱為主XML索引。通過它,可以創(chuàng)建三種類型的二級XML索引提高查詢速度,如下所述:

XML索引

它將在XML列上索引XML實(shí)例的所有標(biāo)簽(tags)、值和路徑?;恚ㄒ簿褪怯蠿ML列的表)的主鍵必須是聚集索引。主鍵被用來關(guān)聯(lián)索引行和基表中的行??梢詮腦ML列中檢索完整的XML實(shí)例(舉例來說,SELECT *)。使用主XML索引的查詢返回標(biāo)量值或XML子樹。

例:創(chuàng)建主XML索引

我們將在大多數(shù)例子中以表T(pk INT PRIMARY KEY, xCol XML)為例,它有一個無類型的XML列,通過簡單的方法可以被擴(kuò)展為有類型的XML。為了更容易理解,被查詢的XML實(shí)例如下:

<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上創(chuàng)建了XML索引idx_xCol:

CREATE PRIMARY XML INDEX idx_xCol on T (xCol)

二級XML索引

一旦主XML索引被建立,你便可以創(chuàng)建二級XML索引來針對不同查詢提高速度,有三種類型的二級索引:路徑、屬性、值分別能提高基于路徑的查詢、定制屬性管理、基于值的查詢速度。路徑索引針對列中所有XML實(shí)例按照每個XML節(jié)點(diǎn)在文檔中的順序構(gòu)建一個B+-樹(路徑,值)。屬性索引創(chuàng)建一個聚集的B+-數(shù)在(主鍵,路徑,值)上,值索引和路徑索引類似,但其創(chuàng)建的B+-樹是在(值,路徑)上的。

下面是一些創(chuàng)建二級索引的指南:

·如果你經(jīng)常在XML列上使用路徑表達(dá)式,路徑二級索引將會很有用,最常用的案例是在T-SQL的where子句中對XML列使用exist()方法。

·如果你需要使用路徑表達(dá)式從單個XML實(shí)例中檢索多個值,屬性二級索引中的聚集路徑將會對此有幫助,通常在屬性包場景中有這種情況,某個對象的屬性被提取,而它的主鍵值是已知的。

·如果你的工作需要查詢XML實(shí)例中的值,但你并不知道包含值的元素或是屬性名稱,你可能想為此創(chuàng)建值索引。這種情況通常發(fā)生在有后代(descendant axes)的查找上,諸如//author[last-name="Howard"],這里<author>元素可以是層次的在任何一個級別上。它也可能用在有通配符的查詢里,諸如/book [@* = "novel"],該查詢將為<book>元素查找值為"novel"的屬性。

例:基于路徑的查詢

假設(shè)有如下查詢:

SELECT pk, xCol

FROM   T

WHERE  xCol.exist (\‘/book[@genre = "novel"]\‘) = 1

路徑表達(dá)式 /book/@genre 和值"novel"對應(yīng)路徑索引的關(guān)鍵字,因此,一個二級的XML路徑索引將會有用:

CREATE XML INDEX idx_xCol_Path on T (xCol)

   USING XML INDEX idx_xCol FOR PATH

例:提取對象屬性

考慮下面這個查詢,它從表中每一行檢索屬性"genre," "title," 和ISBN:

SELECT xCol.value (\‘(/book/@genre)[1]\‘, \‘varchar(50)\‘),

    xCol.value (\‘(/book/title)[1]\‘, \‘varchar(50)\‘),

    xCol.value (\‘(/book/@ISBN)[1]\‘, \‘varchar(50)\‘)

FROM    T

下面創(chuàng)建的屬性索引對這個例子很有用:

CREATE XML INDEX idx_xCol_Property on T (xCol)

   USING XML INDEX idx_xCol FOR PROPERTY

例:基于值的查詢

在下面的查詢里,后代或自身斜杠(//)指定了一個部分路徑,因此基于ISBN的值的查詢將會用到值索引:

SELECT xCol

FROM     T

WHERE    xCol.exist (\‘//book[@ISBN = "1-8610-0157-6"]\‘) = 1

創(chuàng)建如下值索引:

CREATE XML INDEX idx_xCol_Value on T (xCol)

   USING XML INDEX idx_xCol FOR VALUE

XML列上的全文索引

你可以在XML列上創(chuàng)建全文索引,它將索引XML的值而忽略XML標(biāo)記。屬性值是不能被全文索引的(因?yàn)樗鼈儽豢醋鳂?biāo)記的一部份),元素標(biāo)記被用做邊界符。你可以把XML索引和全文索引結(jié)合起來用在這些場合:

·首先,使用SQL 全文索引過濾出感興趣的XML值。

·接著,使用XML索引查詢這些XML值。


--  作者:admin
--  發(fā)布時間:2005-10-21 21:33:40

--  
例:結(jié)合XML查詢的全文搜索
一旦全文索引被創(chuàng)建在XML列上,下面的查詢將檢查書的標(biāo)題中的XML值是否包含"custom"詞:

SELECT * 

FROM   T 

WHERE  CONTAINS(xCol,\‘custom\‘) 

AND    xCol.exist(\‘/book/title/text()[contains(.,"custom")]\‘) =1

CONTAINS()方法將使用全文索引找出XML文檔中包含"custom"詞的XML值的子集,接著,exist()子句確保"custom"詞是在書的標(biāo)題中出現(xiàn)而不是別處。

全文索引使用的CONTAINS()XQuerycontains()有著不同的語法。后者用于子串匹配,而前者使用單詞多形態(tài)(word stemming)來進(jìn)行記號(token)匹配。例如,如果搜索標(biāo)題中的字符串"run",那么,"run", "runs,"  "running"都匹配,因?yàn)槿乃饕?/font>CONTAINS()XQuerycontains()都被滿足。然而,如果標(biāo)題中有"customizable"詞,那么上面的查詢則不匹配(全文索引的CONTAINS()失敗,但是XQuerycontains()成功)。一般來說,對于純粹的子串匹配,應(yīng)該將全文索引的CONTAINS()去掉。

此外,全文搜索使用單詞多形態(tài),而XQuerycontains()是文字匹配。下面的例子說明了它們之間的區(qū)別。

例:使用多形態(tài)全文搜索XML

上個例子中的XQuerycontains()一般來說不能別去掉,考慮下面的查詢:

SELECT * 

FROM   T 

WHERE  CONTAINS(xCol,\‘run\‘) 

文檔中"ran"這個詞因?yàn)闈M足多形態(tài)的關(guān)系匹配搜索條件。此外,該查詢也沒有用XQuery來檢查搜索文本。

當(dāng)使用AXSD分解XML到有全文索引的關(guān)系型列上,對XML視圖的XPath查詢并不在基表上執(zhí)行全文搜索。

Property Promotion

如果查詢主要用于查找較少的元素和屬性的值(如,基于customer id查找客戶,/Customer/@CustId的值已被指定),你可以提升(promote)這些值到關(guān)系型的列中,這對于那些從整個XML實(shí)例中檢索小部分XML數(shù)據(jù)的查詢有一定幫助。此時創(chuàng)建XML索引顯得牛刀殺雞,相反,僅需對提升的列加索引即可。查詢必須被寫成使用提升列才行(也就是,查詢優(yōu)化器并不能把XML列上的查詢重定向到提升列上)。

提升列可以是在同一個表的計(jì)算列或另一個表的用戶維護(hù)的列,這對于從每個XML實(shí)例中提升單個值是足夠了(也就是說單值屬性),然而,對于多值屬性,你必須為其創(chuàng)建一個單獨(dú)的表,如下所示:

基于XML數(shù)據(jù)類型的計(jì)算列

計(jì)算列可以用含XML數(shù)據(jù)類型方法的用戶自定義函數(shù)來創(chuàng)建。這種類型的計(jì)算列可以是任何SQL類型,包括XML類型。如下所示:

例:基于XML數(shù)據(jù)類型方法的計(jì)算列

首先為書的ISBN創(chuàng)建用戶自定義函數(shù):

CREATE FUNCTION udf_get_book_ISBN (@xData xml)

RETURNS varchar(20)

BEGIN

   DECLARE @ISBN   varchar(20)

   SELECT @ISBN = @xData.value(\‘/book[1]/@ISBN\‘, \‘varchar(20)\‘)

   RETURN @ISBN 

END

接著在表中為ISBN增加一個計(jì)算列:

ALTER TABLE      T

ADD   ISBN AS dbo.udf_get_book_ISBN(xCol)

計(jì)算列可以用常規(guī)方式來添加索引。

例:針對該計(jì)算列的查詢

為了查找出ISBN0-7356-1588-2<book>,查詢?nèi)缦拢?p>

SELECT xCol

FROM   T

WHERE  xCol.exist (\‘/book[@ISBN = "0-7356-1588-2"]\‘) = 1

如果使用計(jì)算列,查詢?nèi)缦拢?p>

SELECT xCol

FROM   T

WHERE  ISBN = \‘0-7356-1588-2\‘

你可以創(chuàng)建用戶自定義函數(shù)來返回XML數(shù)據(jù)類型,也可以使用UDF返回計(jì)算列,但你不能在計(jì)算列上創(chuàng)建XML索引。

創(chuàng)建屬性表

你可能希望能夠提升一些XML數(shù)據(jù)中的多值屬性到一個或多個表中,為其創(chuàng)建索引,重定向查詢來使用它們。典型的應(yīng)用場景是一些小數(shù)量的屬性查找卻耗費(fèi)了大量的查詢資源。你可以這么做:

·創(chuàng)建一個或多個表來存放多值屬性。你可能會發(fā)現(xiàn)每個表存放一個屬性會更便利,在每個屬性表中復(fù)制基表的主鍵以便和基表相連。

·如果你希望維護(hù)屬性的順序,你需要為其引進(jìn)一個單獨(dú)的列。

·可以在XML列上創(chuàng)建觸發(fā)器來維護(hù)屬性表,在觸發(fā)器中,實(shí)現(xiàn)下面功能:

·使用XML數(shù)據(jù)類型方法,諸如nodes()value(),來向?qū)傩员聿迦牒蛣h除記錄。

·在CLR中創(chuàng)建流表值(streaming table-valued)函數(shù)來向?qū)傩员聿迦牒蛣h除記錄。

·針對屬性表采用SQL訪問方式,針對基表XML列使用XML訪問方式,用主鍵來連接它們。

例:創(chuàng)建一個屬性表

假設(shè)你希望提升authors的first name,書會有一個或多個作者,這樣first name是個多值屬性。每個first name被存在一個屬性表的不同行中?;淼闹麈I被復(fù)制到屬性表中用以向后連接。

create table tblPropAuthor (propPK int, propAuthor varchar(max))

例:創(chuàng)建用戶自定義函數(shù)來從XML實(shí)例中生成記錄集

下面的表值函數(shù)udf_XML2Table接受一個主鍵值和一個XML實(shí)例,它檢索<book>元素所有作者的first name,并返回一個(主鍵,first name)記錄集。

create function udf_XML2Table (@pk int, @xCol xml)

returns @ret_Table table (propPK int, propAuthor varchar(max))

with schemabinding

as

begin

      insert into @ret_Table 

      select @pk, nref.value(\‘.\‘, \‘varchar(max)\‘)

      from   @xCol.nodes(\‘/book/author/first-name\‘) R(nref)

      return

end

例:創(chuàng)建觸發(fā)器來填充屬性表

Inserted觸發(fā)器:向?qū)傩员碇胁迦胗涗?

create trigger trg_docs_INS on T for insert

as

      declare @wantedXML xml

      declare @FK int

select @wantedXML = xCol from inserted

      select @FK = PK from inserted

   insert into tblPropAuthor

   select * from dbo.udf_XML2Table(@FK, @wantedXML)

Delete觸發(fā)器:基于基表中要刪除行的主鍵值來刪除屬性表中的行

create trigger trg_docs_DEL on T for delete

as

   declare @FK int

   select @FK = PK from deleted

   delete tblPropAuthor where propPK = @FK

Update觸發(fā)器:根據(jù)被改寫的XML實(shí)例刪除屬性表中存在的記錄,再插入新的記錄到屬性表中

create trigger trg_docs_UPD

on T

for update

as

if update(xCol) or update(pk)

begin

      declare @FK int

      declare @wantedXML xml

      select @FK = PK from deleted

      delete tblPropAuthor where propPK = @FK

   select @wantedXML = xCol from inserted

select @FK = pk from inserted

insert into tblPropAuthor 

      select * from dbo.udf_XML2Table(@FK, @wantedXML)

end


--  作者:admin
--  發(fā)布時間:2005-10-21 21:34:38

--  

例:查找XML實(shí)例中first name"David"的作者

查詢可以在XML列上操作,可供選擇的另一種方法是,可以在屬性列上查找,然后和基表相關(guān)聯(lián)返回一個XML實(shí)例,如:

SELECT xCol 

FROM     T JOIN tblPropAuthor ON T.pk = tblPropAuthor.propPK

WHERE    tblPropAuthor.propAuthor = \‘David\‘

例:使用CLR流表值(streaming table-valued)函數(shù)

這種方法包括下面幾步:(a)定義一個CLR類SqlReaderBase,它實(shí)現(xiàn)ISqlReader,并且通過在XML實(shí)例上應(yīng)用路徑表達(dá)式生成流表值的輸出;(b)創(chuàng)建一個裝配件和T-SQL用戶自定義函數(shù)來調(diào)用CLR類;(c)定義insert, update, 和 delete觸發(fā)器維護(hù)屬性表。

首先,我們來創(chuàng)建流CLR函數(shù),它的主干如下所示。XML數(shù)據(jù)類型被暴露為ADO.NET中的一個受托管類,該類支持CreateReader()方法,返回一個XmlReader。

public class c_streaming_xml_tvf {

   public static ISqlReader streaming_xml_tvf 

(SqlXml xmlDoc, string pathExpression) {

      return (new TestSqlReaderBase (xmlDoc, pathExpression));

   }

}

// Class that implements ISqlReader

public class TestSqlReaderBase : ISqlReader {

XPathNodeIterator m_iterator;         

   public SqlChars FirstName;

// Metadata for current resultset

private 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;

   }

}

接下來,創(chuàng)建一個裝配件和T-SQL用戶自定義函數(shù)SQL_streaming_xml_tvf和CLR函數(shù)streaming_xml_tvf相對應(yīng)。用戶自定義函數(shù)被用來定義表值函數(shù)CLR_udf_XML2Table用以生成記錄集:

create function CLR_udf_XML2Table (@pk int, @xCol xml)

returns @ret_Table table (FK int, FirstName varchar(max))

with schemabinding

as

begin

      insert into @ret_Table 

   select @pk, FirstName 

   FROM   SQL_streaming_xml_tvf (@xCol, \‘/book/author/first-name\‘)

      return

end

最后,定義觸發(fā)器,用函數(shù)CLR_udf_XML2Table替代udf_XML2Table,這樣,insert觸發(fā)器如下:

create trigger CLR_trg_docs_INS on T for insert

as

   declare @wantedXML xml

   declare @FK int

   select @wantedXML = xCol from inserted

   select @FK = PK from inserted

   insert into tblPropAuthor

      select *

   from    dbo.CLR_udf_XML2Table(@FK, @wantedXML)

刪除觸發(fā)器無需改變,改寫觸發(fā)器僅僅需要把函數(shù)udf_XML2Table()替換為CLR_udf_XML2Table()即可。

XML架構(gòu)集

一個XML架構(gòu)集是一個元數(shù)據(jù)的實(shí)體,包含一個或多個相關(guān)的(例如通過<xs:import>)、也可以是不相關(guān)的XML架構(gòu)。一個XML架構(gòu)集中的單個XML架構(gòu)通過其命名空間來識別。

可以用CREATE XML SCHEMA COLLECTION語法來創(chuàng)建XML架構(gòu)集和提供一個或多個XML架構(gòu)??梢韵蛞粋€已有的XML架構(gòu)中添加XML架構(gòu)組件(component),也可以通過ALTER XML SCHEMA COLLECTION來向已有的XML架構(gòu)集中添加架構(gòu)。在SQL Server 2005中,XML架構(gòu)集可以向任何SQL對象那樣使用安全模型來確保安全。

多類型列

一個XML架構(gòu)集C根據(jù)多個XML架構(gòu)類型化一個XML列xCol,加之標(biāo)記DOCUMENT或CONTENT可以分別指定了是XML樹還是片斷被存儲在列xCol中。

對DOCUMENT來講,每個XML實(shí)例根據(jù)驗(yàn)證和類型指定了它的頂級元素的目標(biāo)命名空間,另一方面,對CONTENT,每個頂級元素可以指定在C中的任何一個目標(biāo)命名空間。XML實(shí)例依照其中的所有目標(biāo)命名空間來驗(yàn)證和類型化。

架構(gòu)進(jìn)化

XML架構(gòu)集被用來類型化列、變量和參數(shù),它提供了一種XML架構(gòu)進(jìn)化的機(jī)制。假設(shè)你要增加一個目標(biāo)命名空間為BOOK-V1 XML架構(gòu)到XML架構(gòu)集C。一個使用C來類型化的XML列xCol便可以存儲和BOOK-V1 架構(gòu)相一致的XML數(shù)據(jù)。

假設(shè)一個應(yīng)用程序希望用新的XML組件擴(kuò)展XML架構(gòu),諸如復(fù)雜的類型定義和頂級元素聲明,這些新的架構(gòu)組件可以被添加到BOOK-V1 架構(gòu)中,并不要求重新驗(yàn)證xCol列中已存在的XML數(shù)據(jù)。

假設(shè)在稍后時候,這個應(yīng)用程序希望提供一個XML架構(gòu)的新版本,目標(biāo)命名空間為BOOK-V2,這個XML架構(gòu)可以被添加到C,XML列可以同時存儲BOOK-V1BOOK-V2,XML列上的查詢和數(shù)據(jù)修改要和這些命名空間相一致。

用法                                                              

裝載xml數(shù)據(jù)

SQL Server 2000傳輸XML數(shù)據(jù)到SQL Server 2005

你可以用多種方法傳輸XML數(shù)據(jù)到SQL Server 2005,下面這一段落我們將作些討論。

·如果在你的SQL Server 2000數(shù)據(jù)庫中數(shù)據(jù)是在[n]text 或 image列,你可以使用DTS把表導(dǎo)入SQL Server 2005數(shù)據(jù)庫中,再使用ALTER TABLE命令把列的類型改為XML。

·你可以使用bcp out從SQL Server 2000中大容量拷貝數(shù)據(jù)出來,再用bcp in大容量插入到SQL Server 2005數(shù)據(jù)庫中。

·如果數(shù)據(jù)在SQL Server 2000中的關(guān)系型列中,那么創(chuàng)建一個帶ntext列的新表,也可以為該表增加一個主鍵列用于行標(biāo)識。使用客戶端程序檢索由服務(wù)器通過FOR XML生成的XML數(shù)據(jù),再把它寫到ntext列中,接著可以使用上面提到的技術(shù)傳輸數(shù)據(jù)到SQL Server 2005中。你也可以選擇直接寫XML數(shù)據(jù)到SQL Server 2005的XML列中。

例:把列類型改為XML

假設(shè)你希望把表R的XYZ列的類型由[n]text 或image改為無類型的XML,你可以用下面的命令:

ALTER TABLE R ALTER COLUMN XYZ XML

如果需要,你可以指定一個XML架構(gòu)集把類型改為有類型的XML。

大容量裝載(bulk loadXML數(shù)據(jù)

你可以使用SQL Server中大容量裝載功能把XML數(shù)據(jù)大容量裝載到服務(wù)器中,諸如使用bcp命令。OPENROWSET命令允許你從文件中裝載數(shù)據(jù)到XML列中,下面是一些相關(guān)的例子:

例:從文件裝載XML

這個例子說明了如何往表T中插入一行,該行的值來自文件C:\\yukon\\xmlfile.xml,假設(shè)整型列的值為10:

INSERT INTO T

SELECT 10, xCol

FROM    (SELECT *    

    FROM OPENROWSET (BULK \‘C:\\Yukon\\xmlfile.xml\‘, SINGLE_CLOB) 

 AS xCol) AS R(xCol)

文本編碼

SQL Server 2005以Unicode(UTF-16)類型存儲XML數(shù)據(jù),從服務(wù)器被檢索的XML數(shù)據(jù)被編碼為UTF-16。如果你希望不同的編碼,你需要對檢索數(shù)據(jù)執(zhí)行必要的轉(zhuǎn)換。有時,你的XML數(shù)據(jù)可能有不同的編碼,那么在數(shù)據(jù)裝載時要小心:

·如果你的文本XML是Unicode (UCS-2, UTF-16)編碼,可以直接分配給XML列,變量,參數(shù),不會有問題。

·如果編碼不是Unicode,并且是隱含的(和源代碼頁有關(guān)),數(shù)據(jù)庫中的字符串代碼頁應(yīng)該和你希望裝載的代碼(如有必要,使用COLLATE)相同或兼容,如果不存在這樣的服務(wù)器代碼頁,你應(yīng)該用適當(dāng)?shù)木幋a添加一個顯式的XML聲明。

·使用顯式的編碼,或者使用varbinary()類型(它和代碼頁無關(guān)),或者使用適當(dāng)?shù)拇a頁的字符串類型,再分配數(shù)據(jù)到XML列,變量和參數(shù)。

例:顯式地指定編碼

假設(shè)你有一個XML文檔(vcdoc)被作為varchar(max)存儲,并沒有一個顯式的XML聲明。下面的語句用編碼"iso8859-1"增加一個 XML聲明,連接XML文檔,轉(zhuǎn)換結(jié)果為varbinary(max),以便字節(jié)表示被保留,最終被轉(zhuǎn)換為XML。這將使XML處理器根據(jù)指定的編碼"iso8859-1"解析數(shù)據(jù),并為其生成對應(yīng)的UTF-16表示值。

SELECT CAST( 

CAST ((\‘<?xml version="1.0" encoding="iso8859-1"?>\‘+ vcdoc) 

AS VARBINARY (MAX)) 

 AS XML)

Xquery和類型推論(type inference

Xquery(http://www.w3.org/TR/xquery/)被嵌入T-SQL語言中以支持對XML數(shù)據(jù)類型的查詢。該語言正由W3C和一些主要的包括微軟在內(nèi)的數(shù)據(jù)庫廠商共同制定和發(fā)展,它包含XPath 2.0并把它作為導(dǎo)航語言,用于修改XML數(shù)據(jù)的語言結(jié)構(gòu)也已經(jīng)可用了。此外,你還可以查看SQL Server 2005的聯(lián)機(jī)幫助獲得關(guān)于Xquery結(jié)構(gòu),函數(shù)和操作的信息。


--  作者:admin
--  發(fā)布時間:2005-10-21 21:36:49

--  

錯誤模型

Xquery表達(dá)式和XML DML語句的語法錯誤將返回編譯錯誤。編譯階段檢查XQuery表達(dá)式和DML語句的靜態(tài)類型正確性,并且對有類型XML使用XML架構(gòu)用于類型推論。如果一個表達(dá)式由于類型安全違反而導(dǎo)致運(yùn)行時失敗,它將引發(fā)靜態(tài)類型錯誤。一個這樣的例子是:增加字符串值到整型數(shù)據(jù)列中,或者查詢類型數(shù)據(jù)中的一個不存在的節(jié)點(diǎn)。

和W3C標(biāo)準(zhǔn)不同的是,XQuery 運(yùn)行錯誤被轉(zhuǎn)換為空序列,根據(jù)調(diào)用情況的不同它可被作為空XML或NULL傳播到查詢結(jié)果。

顯式轉(zhuǎn)換到正確的類型將使用戶避免靜態(tài)錯誤,雖然運(yùn)行錯誤將被轉(zhuǎn)換為空序列。

下面的子段落將詳細(xì)的討論類型檢查。

單態(tài)(singleton)檢查

如果編譯器不能確定在運(yùn)行時是否能保證一個單態(tài),那么諸如位置步驟、函數(shù)參數(shù)、操作符(例如eq)這些要求單態(tài)的都回返回一個錯誤。這種問題經(jīng)常是由無類型的數(shù)據(jù)而引起。例如,查詢一個attribute要求一個單態(tài)雙親元素,一個雙親節(jié)點(diǎn)的順序選擇就夠了。將node()-value()結(jié)合以提取attribute值可能并不要求順序的指定,就像下面的例子所示。

例:一個已知的單態(tài)在這個例子中,nodes()方法為每個<book>元素生成分離的行。value()方法對<book>節(jié)點(diǎn)求值,提取@genre的值,而@genre作為一個屬性,是一個單態(tài)。
SELECT nref.value(\‘\‘@genre\‘\‘, \‘\‘varchar(max)\‘\‘) LastName
FROM   T CROSS APPLY xCol.nodes(\‘\‘//book\‘\‘) AS R(nref)
XML架構(gòu)對有類型XML的類型檢查有用。如果一個節(jié)點(diǎn)被指定作為XML架構(gòu)中的單態(tài),編譯器將獲悉這個信息,不報(bào)錯,否則,將需要依次的挑選一個單獨(dú)的節(jié)點(diǎn)。特別地,后代軸或者自身軸(//),如/book//title,對<title>元素遺失了單態(tài)集推論,即使對其指定了XML架構(gòu)??蓪⑺貙憺?/font>(/book//title)[1]。

要注意,在類型檢查時,確保//first-name[1](//first-name)[1]的區(qū)別非常重要。前者返回一個<first-name>節(jié)點(diǎn)的序列,每個節(jié)點(diǎn)都是它同胞節(jié)點(diǎn)的最左邊<first-name>節(jié)點(diǎn),后者返回XML實(shí)例中的在文檔順序里的第一個單態(tài)<first-name>節(jié)點(diǎn)。

例:使用value()
下面在一個無類型的XML列上的查詢將導(dǎo)致一個靜態(tài)、編譯錯誤,因?yàn)?/font>value()期望一個單態(tài)節(jié)點(diǎn)作為第一個參數(shù),編譯器不能決定是否只有一個<last-name> 節(jié)點(diǎn)在運(yùn)行中發(fā)生:

SELECT xCol.value(\‘\‘//author/last-name\‘\‘, \‘\‘nvarchar(50)\‘\‘) LastName

FROM   T

下面這個修正看起來不錯:

SELECT xCol.value(\‘\‘//author/last-name[1]\‘\‘, \‘\‘nvarchar(50)\‘\‘) LastName

FROM   T

然而,因?yàn)樵诿恳粋€XML實(shí)例中可能會有多個<author>節(jié)點(diǎn),其實(shí)它并沒有修正錯誤。下面的代碼是正確的:

SELECT xCol.value(\‘\‘(//author/last-name)[1]\‘\‘, \‘\‘nvarchar(50)\‘\‘) LastName

FROM   T

該查詢返回每個XML實(shí)例中第一個<last-name>元素的值

雙親軸

如果一個節(jié)點(diǎn)的類型不能被確定,它便成為anyType,它不能被隱式的轉(zhuǎn)換到任何別的類型。這在使用雙親軸導(dǎo)航時最有可能發(fā)生(如xCol.query(\‘\‘/book/@genre/../price\‘\‘)),雙親節(jié)點(diǎn)類型被確定為anyType。一個元素也可能被定義為anyType。在這些情況中,更多精確類型信息的遺失常導(dǎo)致靜態(tài)類型錯誤,并要求顯式的轉(zhuǎn)換原子值到它們的明確的類型。

Data(),Text(), and String() Accessors

XQuery有函數(shù)fn:data()可以從節(jié)點(diǎn)中提取標(biāo)量的,類型化的值,對節(jié)點(diǎn)用text()返回文本節(jié)點(diǎn),函數(shù)fn:string()返回節(jié)點(diǎn)的字符串值。它們的用法有時會造成混淆,SQL Server 2005中對它們的使用指南如下,讓我們考慮有XML實(shí)例<age>12</age>:
·無類型XML:路徑表達(dá)式/age/text()返回文本節(jié)點(diǎn)12”。函數(shù)fn:data(/age)返回字符串值12”,就像fn:string(/age)一樣。·有類型XML:對任何簡單的有類型<age>元素,表達(dá)式/age/text()返回靜態(tài)錯誤。在另一方面,fn:data(/age)返回整型12,而fn:string(/age)返回字符串12”。

聯(lián)合類型的函數(shù)和操作符由于類型檢查的原因,聯(lián)合類型需要仔細(xì)的處理,下面的例子演示了兩個問題。

例:聯(lián)合類型的函數(shù)考慮一個聯(lián)合類型<r>的元素定義

<xs:element name="r">

<xs:simpleType>

   <xs:union memberTypes="xs:int xs:float xs:double"/>

</xs:simpleType>

</xs:element>
XQuery上下文中,"average"函數(shù)fn:avg (//r)返回一個靜態(tài)錯誤,因?yàn)?/font>XQuery編譯不能對<r>元素的不同的類型求和(xs:int, xs:float, or xs:double),為了解決它,重寫函數(shù)fn:avg(for $r in //r return $r cast as xs:double ?)

例:聯(lián)合類型的操作符

加操作符\‘\‘+\‘\‘要求精確的操作數(shù)類型,所以表達(dá)式(//r)[1] + 1將返回一個靜態(tài)錯誤,重寫它來解決這個問題:(//r)[1] cast as xs:int? +1,這里"?"預(yù)示是0或者1SQL Server 2005要求"cast as" "?",因?yàn)橛捎谶\(yùn)行時錯誤,任何類型轉(zhuǎn)換都能導(dǎo)致空序列。

Value(), Nodes() OpenXML()

你可以在一個SELECT子句中對XML數(shù)據(jù)類型使用多個value()方法,從而提取值生成一個行集。nodes()方法呢,它可以生成一個對每個被選擇的節(jié)點(diǎn)的內(nèi)部引用,這個可以被將來的查詢所用。將nodes()value()結(jié)合起來可以更有效的生成行集,尤其是在有多列,且可能使用了路徑表達(dá)式的情況下。

nodes()方法生成一個指定的XML數(shù)據(jù)類型的多個實(shí)例,它們中的每一個都有自己的上下文設(shè)置到不同的被選擇的節(jié)點(diǎn),象這樣的一個XML實(shí)例支持query(), value(), nodes(), exist()方法,并可被用于count(*)聚集,所有別的用法將會出錯。

例:nodes()的使用

假設(shè)你希望提取作者的first name last name,且first name不是“David”,行集是由firstnamelastname兩列構(gòu)成,通過使用nodes() and value()方法,你可以實(shí)現(xiàn)它,如下所示:

SELECT nref.value(\‘\‘first-name[1]\‘\‘, \‘\‘nvarchar(50)\‘\‘) FirstName,

       nref.value(\‘\‘last-name[1]\‘\‘, \‘\‘nvarchar(50)\‘\‘) LastName

FROM   T CROSS APPLY xCol.nodes(\‘\‘//author\‘\‘) AS R(nref)

WHERE  nref.exist(\‘\‘.[first-name != "David"]\‘\‘) = 1

在這個例子中,對每一個XML實(shí)例,nodes(\‘\‘//author\‘\‘)生成一個引用<author>元素的行集,作者的firstlast名字通過value()方法關(guān)系到這些引用來獲得。

SQL Server 2000 提供了一個方法用于從一個XML實(shí)例中生成行集:OpenXml()。你可以為行集指定一個關(guān)系型的架構(gòu),這樣XML實(shí)例中的值被映射到行集中的列上。

--  作者:admin
--  發(fā)布時間:2005-10-21 21:37:48

--  
例:對XML數(shù)據(jù)類型使用OpenXml()

我們可以用OpenXml()重寫上面那個查詢,通過創(chuàng)建一個游標(biāo),將每個XML實(shí)例讀到XML變量中,再對其應(yīng)用OpenXml()。

DECLARE name_cursor CURSOR
FOR

   SELECT xCol 

   FROM   T

OPEN name_cursor

DECLARE @xmlVal XML

DECLARE @idoc int

FETCH NEXT FROM name_cursor INTO @xmlVal

WHILE (@@FETCH_STATUS = 0)

BEGIN

   EXEC sp_xml_preparedocument @idoc OUTPUT, @xmlVal

   SELECT   *

   FROM   OPENXML (@idoc, \‘\‘//author\‘\‘)

          WITH (FirstName  varchar(50) \‘\‘first-name\‘\‘,

                LastName   varchar(50) \‘\‘last-name\‘\‘) R

   WHERE  R.FirstName != \‘\‘David\‘\‘

   EXEC sp_xml_removedocument @idoc

   FETCH NEXT FROM name_cursor INTO @xmlVal

END

CLOSE name_cursor

DEALLOCATE name_cursor 

OpenXml()創(chuàng)建了一個內(nèi)存中的表述,并使用工作表來代替查詢處理器。它MSXML 3.0XPath 1.0而不是XQuery引擎。工作表并不在對OpenXml()的多個調(diào)用間共享,即便是在同一個XML實(shí)例上,這樣限制了它的可擴(kuò)展性。OpenXml()允許你訪問邊緣表格式的XML數(shù)據(jù)(在不指定WITH子句時),它還允許你使用在一個分離的,"overflow"列中的剩余的XML值。

nodes()  value()功能結(jié)合起來能更有效的使用XML索引。這樣,這種結(jié)合要比OpenXml具有更大的擴(kuò)展性。

從行集中使用 FOR XML生成XML

你可以通過使用帶TYPE指示的FOR XML從行集中生成一個XML數(shù)據(jù)類型實(shí)例。

結(jié)果可以被分配給一個XM數(shù)據(jù)類型列,變量或者是參數(shù),而且,FOR XML還能夠嵌套使用生成任何層次結(jié)構(gòu)。這使得嵌套的FOR XMLFOR XML EXPLICIT要更方便書寫,但是它可能對深度層次性能不是很好。FOR XML也引入了一個新的PATH節(jié)點(diǎn),該節(jié)點(diǎn)指出了列的值在XML樹中的路徑。

新的FOR XML TYPE指示可以被用來定義在關(guān)系型數(shù)據(jù)上的只讀的XML視圖,該視圖可以用SQL 語句和嵌入的XQuery來查詢,如下面的例子所示。例如,你可以在存儲過程中采用這樣的視圖。

例:返回XML數(shù)據(jù)類型的SQL視圖

下面的SQL視圖定義創(chuàng)建了一個XML視圖,它基于一個關(guān)系型列(pk)和從一個XML列中檢索的作者:

CREATE VIEW V (xmlVal) AS

SELECT pk, xCol.query(\‘\‘/book/author\‘\‘)

FROM   T

FOR XML AUTO, TYPE

視圖V包含一個單XML類型列xmlVal,它可以象規(guī)則的XML數(shù)據(jù)類型實(shí)例那樣被查詢,例如,下面的查詢返回first name為“David”的作者:

SELECT xmlVal.query(\‘\‘//author[first-name = "David"]\‘\‘)

FROM   V

SQL視圖定義有點(diǎn)類似于采用帶注解的架構(gòu)創(chuàng)建的XML視圖,然而,它們之間存在重大的差別。SQL視圖定義是只讀的,并且必須用嵌入式XQuery來操作,這點(diǎn)和采用帶注解的架構(gòu)創(chuàng)建的XML視圖差別很大,此外,SQL視圖在應(yīng)用XQuery表達(dá)式之前物化(materializesXML結(jié)果,而在XML視圖上的XPath查詢則估計(jì)為基表上的SQL查詢。

增加商業(yè)邏輯

可以用下面幾種方法增加商業(yè)邏輯到XML數(shù)據(jù)中:

·你可以通過寫行、列約束來實(shí)現(xiàn)在插入和修改XML數(shù)據(jù)時的指定域的約束。

·你可以在XML列上寫觸發(fā)器,該觸發(fā)器在你插入和修改列值時激活,觸發(fā)器中可以包含指定域的驗(yàn)證規(guī)則或填充屬性表。

·你可以在你傳遞XML值的托管代碼中寫SQLCLR函數(shù),并使用System.Xml命名空間提供的XML處理能力。例如,可以對XML數(shù)據(jù)應(yīng)用XSL轉(zhuǎn)換,象下面例子所示??晒┻x擇的方法還有反序列化XML到一個或多個托管類中,并且使用托管代碼操作它。

·你可以根據(jù)商業(yè)需要寫T-SQL存儲過程和函數(shù)來調(diào)用對XML列的處理操作。

例:XSL轉(zhuǎn)換的應(yīng)用

考慮一下這個CLR函數(shù)TransformXml(),它接受一個XML數(shù)據(jù)類型實(shí)例和一個存儲在文件中的的XSL轉(zhuǎn)換,應(yīng)用這個轉(zhuǎn)換到XML數(shù)據(jù),并且返回被轉(zhuǎn)換過的XML,該函數(shù)的主干如下(使用C#編寫):

public static SqlXml TransformXml (SqlXml XmlData, string xslPath) {

   // Load XSL transformation

   XslTransform xform = new XslTransform();

   XPathDocument xslDoc = new XPathDocument (xslPath);

   xform.Load (xslDoc.CreateNavigator(),null);

   // Load XML data 

   XPathDocument xDoc = new XPathDocument (XmlData.CreateReader());

   XPathNavigator nav = xDoc.CreateNavigator ();

   // Return the transformed value

   SqlXml retSqlXml = new SqlXml (xform.Transform(nav, null));

   return (retSqlXml);

} 

一旦這個裝配件被注冊,再創(chuàng)建一個和TransformXml()相應(yīng)的用戶自定義T-SQL函數(shù)SqlXslTransform(),那么我們可以從T-SQL中調(diào)用該函數(shù):

SELECT SqlXslTransform (xCol, \‘C:\\yukon\\xsltransform.xsl\‘)

FROM    T

WHERE  xCol.exist(\‘/book/title/text()[contains(.,"custom")]\‘) =1

這個查詢結(jié)果包含一個被轉(zhuǎn)換的XML的行集。

SQLCLR給我們提供了全新的方法,它可以被用來分解XML數(shù)據(jù)到表或用于屬性提升,也可以使用在System.Xml命名空間中的托管類查詢XML數(shù)據(jù)。更多信息可以在SQL Server 2005Microsoft Visual Studio “Whidbey”聯(lián)機(jī)幫助中發(fā)現(xiàn)。


--  作者:admin
--  發(fā)布時間:2005-10-21 21:38:42

--  
交叉域查詢
當(dāng)你的數(shù)據(jù)既有關(guān)系型列也有XML數(shù)據(jù)類型列時,你可能想寫的查詢既能處理關(guān)系型也能處理XML數(shù)據(jù)。例如,你可以使用FOR XML轉(zhuǎn)換關(guān)系型數(shù)據(jù)和XML列數(shù)據(jù)到一個XML數(shù)據(jù)類型實(shí)例,再使用XQuery查詢它?;蛘叻催^來,你可以從XML值生成行集,再用T-SQL查詢它。

一個更方便有效的方法是寫交叉域查詢,它在XQuery或者XML DML表達(dá)式中使用SQL 變量或列的值:

·你可以用sql:variable()在你的XQueryXML DML表達(dá)式中使用SQL 變量的值。

·你可以用sql:column()在你的XQueryXML DML表達(dá)式中使用關(guān)系型列的值。

· 這種方法允許應(yīng)用程序參數(shù)化查詢,如下面例子所示。然而,sql:variable()sql:column()并不允許XML和用戶自定義類型。

例:使用sql:variable()的交叉域查詢

下面的查詢是例子:Example: queries on a computed column based on XML data type methods.的修改版,在這個版本中,所感興趣的ISBN通過SQL變量@isbn來傳遞,用sql:variable()來替換常量,該查詢可以被用來查找任何ISBN,而不僅僅是ISBN: 0-7356-1588-2。

DECLARE @isbn varchar(20)

SET     @isbn = \‘0-7356-1588-2\‘

SELECT  xCol

FROM    T

WHERE   xCol.exist (\‘/book[@ISBN = sql:variable("@isbn")]\‘) = 1

可以用類似的方法使用Sql:column(),且能提供額外的好處:基于代價的查詢優(yōu)化器決定讓列上的索引使查詢更有效,此外,如在A computed column based on an XML data type.討論的那樣,計(jì)算列可以存儲提升的屬性。

原生XML支持的編目視圖

編目視圖用于提供關(guān)于XML使用的元數(shù)據(jù)信息,下面將討論它的一些特性。

XML索引

在編目視圖sys.indexes中的XML索引項(xiàng)的”type”列為3,”name”列則包含了XML索引的名字。

XML索引也記錄在編目視圖sys.xml_indexes中,它包含所有的sys.indexes列,并有一些專門用于XML索引的意義,在列”secondary_type”NULL指明這是個主XML索引,值”P”,”R”,”V”分別代表二級索引的PATH,PROPERTYVALUE。

XML索引的空間占用可以用表值函數(shù)sys.fn_indexinfo( )查看,它提供了一些信息諸如:磁盤空間占用量,平均每行占多少字節(jié),記錄數(shù),和一些所有索引類型都有的其他信息,包括XML索引。這些信息對每個數(shù)據(jù)庫分區(qū)都可用。XML索引和基表使用同樣的分區(qū)架構(gòu)和分區(qū)功能。

例:XML索引的空間使用SELECT sum(Pages)

FROM    sys.fn_indexinfo (\‘T\‘, \‘idx_xCol_Path\‘ , DEFAULT, \‘DETAILED\‘)

它將生成表T上的XML索引index idx_xCol_Path在所有分區(qū)的磁盤占用數(shù),如果不用sum(),將返回每個分區(qū)的磁盤占用情況。

檢索XML架構(gòu)集

XML架構(gòu)集被存儲在編目視圖sys.xml_schema_collections中,XML架構(gòu)集”sys”由系統(tǒng)定義,它包含預(yù)定義的命名空間可被用于所有用戶自定義的XML架構(gòu)集中,無須顯式的裝載它們。它包含的命名空間有:xml, xs, xsi, fn, xdt。另外兩個值得提及的編目視圖是:sys.xml_schema_namespaces,它列舉了每個XML架構(gòu)集的所有命名空間;sys.xml_components,它列舉了每個XML架構(gòu)的組件。

系統(tǒng)內(nèi)建的函數(shù)XML_SCHEMA_NAMESPACE (schemaName, XmlSchemacollectionName, namespace-uri)生成一個XML數(shù)據(jù)類型實(shí)例,它包含XML架構(gòu)集中的XML架構(gòu)片斷,除了預(yù)定義的XML架構(gòu)。

你可以列出用下面的方法列出XML架構(gòu)集的內(nèi)容:·對合時的XML架構(gòu)集的編目視圖寫T-SQL查詢。·使用內(nèi)建的函數(shù)XML_SCHEMA_NAMESPACE()。你可以在這個函數(shù)的輸出上應(yīng)用XML數(shù)據(jù)類型方法,但你不能修改基XML架構(gòu)。·下面有一些示例:

例:列出一個XML架構(gòu)集中的命名空間XML架構(gòu)集”myCollection”使用下面的查詢:

SELECT XSN.name

FROM    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架構(gòu)集的內(nèi)容下面的語句列出和架構(gòu)dbo有關(guān)的XML架構(gòu)集”myCollection”的內(nèi)容

SELECT XML_SCHEMA_NAMESPACE (N\‘dbo\‘, N\‘myCollection\‘)                      1

通過指定目標(biāo)命名空間給XML_SCHEMA_NAMESPACE()的第三個參數(shù),架構(gòu)集中的單個XML架構(gòu)可以被作為XML數(shù)據(jù)類型實(shí)例來獲得,如下所示:

例:從一個XML架構(gòu)集中輸出指定的架構(gòu)下面的語句從XML架構(gòu)集"myCollection"中輸出目標(biāo)命名空間為“http://www.microsoft.com/booksXML架構(gòu)。

SELECT XML_SCHEMA_NAMESPACE (N\‘dbo\‘, N\‘myCollection\‘, 

N\‘http://www.microsoft.com/books\‘)
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
DB2和Oracle區(qū)別
培訓(xùn)公司/機(jī)構(gòu)-供應(yīng)SQL SERVER2005數(shù)據(jù)庫系統(tǒng)管理與開發(fā)培訓(xùn) 盡在慧聰網(wǎng)
SQL Server索引語法 <第四篇>
XML 架構(gòu)設(shè)計(jì)器(XML 設(shè)計(jì)器)
SQL面試須看
SQL Server十大熱門技巧
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服