1.契子 以往,使用關聯式資料庫系統儲存XML文件的方式可區分為兩種方式。 第一種是在關聯式資料庫系統中,將XML文件以文字(text)或二進位(binary)資料的格式存入表格的一個大型欄位(large object,LOB),在存取XML文件時只須對此欄位進行資料的輸入、輸出即可。此方式雖然具有設計簡單,不需複雜的表格拆解動作即可處理結構複雜的XML文件等優點,十分適合應用於以整份XML文件作為輸入、輸出的應用,並可直接套用在既有的關聯式資料庫系統之上。但此方式無法在資料庫中直接存取XML中的特定元素(Element)或屬性(Attribute)資料,此時必需輸出整份XML文件,再進行資料剖析(parsing),才能處理XML文件所需要的資料。 第二種方式是透過事先定義好的對應規則,將XML文件拆解成多個部份存放在不同的表格(Table)。當要取回原本的XML文件時,則透過SQL查詢語言取得各表格的資料,再組合成XML文件。此方式的優點是可快速的處理結構固定的XML文件,並可直接套用在關聯式資料庫系統之上。但當XML文件結構很複雜時,此方法將產生大量的表格。若要將分散在各表格中的資料組合成完整的XML文件,必需透過複雜的資料結合(join)才能達成。此外,一旦對應規則訂定後,若因資料需求的改變而造成XML文件結構需要更動時,則可能需重新定義對應規則。因此,在處理不同結構的XML文件時較無彈性。 在SQL Server 2005的版本中,新增加了XML的資料型態來儲存XML文件,並可使用XQuery快速的存取XML文件中的資料,等於結合的上述兩種方式的優點,以下筆者簡單介紹XQuery與SQL Server 2005對XML的支援。 2. XQuery 為了制定XML的查詢方式,因此W3C於2000年的1月首先提出了XML Query Requiremets,討論對XML資料做查詢時的需求。於2001年6月W3C以Jonathan Robie (Software AG)、Don Chamberlin (IBM Almaden Research Center)及Daniela Florescu (INRIA)三人共同開發的Quilt語言為基礎定義XQuery,此後XQuery便為XML查詢語言的標準,目前最新版本已於2006年6月8日出版,。 XQuery是針對各類XML資料所設計,不論其儲存為文件或是在關聯式資料庫中。XQuery其資料模型( data model )視一個XML文件為一棵標記樹( label tree ),並考慮標記樹中每個節點及所有值之順序關係。其特性是路徑表示法的使用,使用者可以利用路徑表示法在XML資料中尋找任意長度路徑的資料。因此透過XQuery的執行,便可取得XML文件中符合路徑表示法的資料序列,其順序是依照文件中各個元素之間的順序關係而定。另外使用者也可以從資料中取得關於XML文件schema的資訊。 2.1 XQuery Expressions 一個XQuery的敘述式為一組FLWOR (發音同“flower”)表示法,是由For、Let、Where、Order by及Return子句等結構而成,並以特定的順序組合而成. FOR讓變數可以遞迴取得( iterate over )一個路徑表示法的結果, 而LET則是將變數直接與某一個的路徑表示法結合( binding ),WHERE則允許對變數做條件的限制,ORDER BY可依據條件重新排序FOR語法的元素進而影響接下來RETURN的輸出,RETURN則可以根據原有的、或是建構新的XML元素為查詢的輸出。SQL Server 2005目前僅支援FOR、WHERE、ORDER BY及RETURN四個語法。 3. Using XQuery in SQL Server 2005 3.1 xml Data Type 在Microsoft R SQL ServerR 2005以前的版本雖然可以透過「FOR XML」以及「OPEN XML」來處理XML型態的資料,但其主要的工作環境仍舊拘泥在關聯式的架構,無法直接存取XML型態裡面的元素以及屬性的資料。2005這個版本中新增XML資料型態與相關的方法以及函數,大幅提高其對XML的支援。 「xml Datatype」是一個原生的資料類型可以用來定義欄位、變數與參數的資料型態,它儲存的XML資料必須符合Well-formed的規定,所以在儲存資料的同時它會自動檢查該資料是否符合Well-formed格式。在存取方面可以使用XQuery對XML資料的內容進行查詢,也可以使用XML-DML修改XML資料格式與內容。在效能方面可以對xml資料類型建立索引機制(Indexing),以提高查詢效率。 建立xml資料型態的欄位 | CREATE TABLE T1(Col1 int primary key, Col2 xml) | 建立一的xml資料型態的變數 | |
在SQL Server 2005中XML以BLOB型態存在,最大可到2GB,而儲存的編碼格式是UTF-16,對於XML中文或多語系亂碼的問題也降低發生的可能,另外還可以針對XML資料欄位建立索引,提高XML資料的查詢效率。 3.2方法(Method) SQL Server® 2005針對xml資料類型提供有query()、value()、exist()、modify()以及nodes()等五個方法(Methods)進行資料的存取與維護: 3.2.1 query():針對xml資料類型的執行個體指定XQuery。結果為xml類型。該方法會傳回不具類型的XML執行個體。 3.2.2 value():對XML執行XQuery並傳回SQL類型的值,此方法會傳回純量值而非集合。可以使用此方法,從儲存在XML Datatype的欄位資料、參數或變數中的XML資料擷取值,可以指定「SELECT」查詢來結合或比較XML資料與非XML資料行的資料。 3.2.3 exist():用來確認一個查詢陳述式是否有結果。傳回值為1、0或是NULL:1代表True,即查詢中的XQuery運算式傳回非空的結果,也就是,它至少會傳回一個XML節點;0代表False,即查詢傳回空的結果;如果查詢所執行的xml資料類型執行個體包含NULL,則會傳回NULL。 3.2.4 modify():此方法使用XML-DML陳述式來來修改XML類型變數或欄位的內容,如插入、更新或刪除XML資料的節點。modify()這個方法只能用在「UPDATE」陳述式的「SET」子句中。 3.2.5 nodes():可以將XML資料切割成多個資料列,以便將部份XML文件傳播成資料列集,就如同關聯式資料。每個xml資料類型執行個體都有隱含提供的內容節點。針對儲存在資料行或變數中的XML執行個體,這是指文件節點。文件節點是位在每個xml資料類型執行個體最上方的隱含節點。nodes()方法的結果,會是一個包含原始XML執行個體之邏輯副本的資料列集。在這些邏輯副本中,每個資料列執行個體的內容節點,都會設成可用查詢運算式來識別的節點之一,讓後續的查詢能夠比對這些內容節點來進行導覽。 3.3函數(Functions) SQL Server 2005針對XQuery所提供的函數依其用途可分為個12種類,以下分別介紹這些函數與其用法。 3.3.1 數值函數(Functions on Numeric Values):可以對數值資料進行無條件進位、無條件捨去以及四捨五入運算,其函數說明如表3-1所示。 表3-1 SQL Server 2005的XQuery數值函數 函數名稱 | 說明 | ceiling ($argas numeric) | 傳回不含小數的最小數字,不小於其引數的值。如果引數是空的序列,它會傳回空的序列。 | floor ($argas numeric) | 傳回不含小數、不大於其引數值的最大數字。如果引數是空的序列,它會傳回空的序列。 | round($argas numeric) | 傳回最接近引數且去掉小數部份的數字。如果這樣的數字不止一個,則傳回最接近正無限數的那一個。 |
其用法如下: Example: | declare@xxml set@x=' <root> <item price="13.5">a</item> <item price="15.4">b</item> </root>' select@x.query('for $i in //item return <item price="{$i/@price}"> <name>{data($i) }</name> <ceiling>{ceiling($i/@price) }</ceiling> <floor>{floor($i/@price) }</floor> <round>{round($i/@price) }</round> </item> ') | Result: | <itemprice="13.5"> <name>a</name> <ceiling>14</ceiling> <floor>13</floor> <round>14</round> </item> <itemprice="15.4"> <name>b</name> <ceiling>16</ceiling> <floor>15</floor> <round>15</round> </item> |
3.3.2字串值相關函數(Functions on String Values):對於字串資料可以進行字串連接、字串比較、取得部份字串以及取得字串長度等運算,其函數說明如表3-2所示。 表3-2 SQL Server 2005的XQuery字串值相關函數 函數名稱 | 說明 | concat ($stringas xs:string,$stringas xs:string [, ...]) | 接受零或更多的字串以做為引數,並傳回串連每個引數的值所建立的字串。 | contains ($arg1as xs:string,$argas xs:string) | 傳回xs:boolean類型的值,指出$arg1的值是否包含$arg2指定的字串值。 | Substring($sourceString) as xs:string,$startingLocas xs:decimal [,$lengthas xs:decimal]) | 傳回$sourceString值的一部份,從$startingLoc,值所指示的位置開始,一直到$length值所指示的字元數為止。 | string-length($arg as xs:string) | 傳回字元的字串長度。 |
其用法如下: Example: | declare@xxml set@x=' <root> <item price="13.5">MP5</item> <item price="15.4">G36C</item> </root>' select@xasxinto#t selectx.query('for $i in //item return <item price="{$i/@price}"> <name>{data($i) }</name> <concat>{concat("price:", $i/@price, "; ceiling:", string(ceiling($i/@price))) }</concat> <substring>{substring(data($i) ,2,2) }</substring> <string-length>{string-length(data($i)) }</string-length> </item> ') from#t wherex.value('contains((//item/text()) [1],"MP5") ','bit') =1 | Result: | <itemprice="13.5"> <name>MP5</name> <concat>price:13.5; ceiling:14</concat> <substring>P5</substring> <string-length>3</string-length> </item> <itemprice="15.4"> <name>G36C</name> <concat>price:15.4; ceiling:16</concat> <substring>36</substring> <string-length>4</string-length> </item> |
3.3.3布林值相關函數(Functions on Boolean Values):用來檢查陳述式的結果是否不成立,其函數說明如表3-3所示。 表3-3 SQL Server 2005的XQuery布林值相關函數 函數名稱 | 說明 | not($argas item() *) | 如果$arg的有效布林值為false,就會傳回TRUE,而如果$arg的有效布林值為true,就會傳回FALSE。 |
其用法如下: Example: | declare@xxml set@x=' <root> <item price="13.5">MP5</item> <item price="15.4">G36C</item> </root>' select@x.query('for $i in //item[not(@price="13.5") ] return $i') | Result: | <itemprice="15.4">G36C</item> |
3.3.4節點相關函數(Functions on Nodes):此類函數可以取得XQuery陳述式所指出的節點的資料值、名稱或是URI等資料,其函數說明如表3-4所示。 表3-4 SQL Server 2005的XQuery節點相關函數 函數名稱 | 說明 | number | 傳回$arg所指出的節點數值。 | local-name函數(XQuery) | 以xs:string傳回$arg名稱的本機部份,它有可能是零長度的字串或是將會有xs:NCName的語彙格式。如果沒有提供引數,預設值是內容節點。 | namespace-uri函數(XQuery) | 傳回在$arg中指定為xs:string的QName命名空間URI。 |
|