熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> SQL Server >> 正文

SQL Server 2000 XML之七種兵器的說明

2013-11-15 14:39:05  來源: SQL Server 

  XML已成為近來最熱門的Web技術它是SQL Server 中的重要部分本文將綜合七條SQL Server 中最重要的XML綜合特性組成XML之七種兵器
  兵器之一FOR XML
  
  在SQL Server 標准的TSQL SELECT語句包括FOR XML子句它以XML文檔形式返回一個查詢結果新的FOR XML子句有三種模式——RAWAUTO和EXPLICIT每個都能對XML文檔格式提供附加標准的控制
  
  下面首先介紹FOR XML的使用方法
  
  為了從SQL Server提取XML格式的數據TSQL中加入了一個FOR XML命令在查詢命令中使用FOR XML命令使得查詢結果以XML格式出現FOR XML命令有三種模式RAWAUTO和EXPLICIT所顯示的SQL命令訪問SQL Server提供的Pubs示例數據庫有關Pubs數據庫的更多信息請參見MSDN說明如果我們依次指定該SQL命令的模式為三種允許的模式之一就可以得到各種模式所支持的不同XML輸出
  
  SELECT storestor_id as Id stor_name as Name
  
  saleord_num as OrderNosaleqty as Qty
  
  FROM stores store inner join
  
  sales sale on storestor_id = salestor_id
  
  ORDER BY stor_name
  
  FOR XML <模式>
  
  該查詢命令所生成的結果包含所有銷售記錄及其對應的商店結果以商店名稱的字母升序排列查詢的最後加上了FOR XML命令以及具體的模式比如FOR XML RAW
  
  理想情況下SQL命令所生成的XML文檔應具有如下結構
  <Stores>
  
  <Store Id=&single;&single; Name=&single;&single;>
  
  </Sale OrderNo=&single;&single; Qty=&single;&single;>
  
  </Store>
  
  </Stores>
  
  下面我們來看看具體的處理方法
  
  RAW模式
  下面是指定RAW模式時結果XML文檔的一個片斷
  
  
 

  查詢結果集中每一個記錄包含唯一的元素<row>由於我們無法控制元素名字和文檔結構因此這種模式不是很有用RAW模式所生成的文檔結構與我們所希望的不符而且它的用途也非常有限
  
  AUTO模式
  下面是指定AUTO模式時結果文檔的一個片斷
  
  
 

  可以看到<Stroe>和<Sale>兩個元素是父子關系形成了我們所希望的層次結構這種節點關系由查詢中表的聲明次序決定後聲明的表成為前聲明表的孩子
  
  我們可以看出查詢命令所指定的別名決定了XML文檔中的名字根據這一點我們可以控制XML文檔元素屬性的名字使得這些名字符合我們所要求的命名慣例
  
  可見AUTO模式能夠創建出我們所需要的XML文檔不過它存在以下缺點
  
  雖然可以得到層次結構但這種層次結構是線性的即每個父節點只能有一個子節點反之亦然
  
  通過別名指定元素名字不太方便而且有時候會影響查詢命令本身的可讀性
  
  無法在文檔中同時生成元素和屬性要麼全部是元素(通過ELEMENTS關鍵詞指定)要麼全部是屬性(默認) EXPLICIT模式解決了上述不足
  
  EXPLICIT模式
  
  EXPLICIT模式比較復雜我們將用另外一種方法來表達所顯示的查詢這種方法使得我們能夠完全地控制查詢所生成的XML文檔首先我們將介紹如何改用EXPLICIT模式編寫圖所顯示的查詢然後看看這種方法如何賦予我們遠遠超過AUTO模式的能力
  
  商店數據
  SELECT as Tag
  NULL as Parent
  sstor_id as [store!!Id]
  sstor_name as [store!!Name]
  NULL as[sale!!OrderNo]
  NULL as [sale!!Qty]
  FROM stores s
  UNION ALL
   銷售數據
  SELECT
  sstor_id
  sstor_name
  saord_num
  saqty
  FROM stores s sales sa
  WHERE sstor_id = sastor_id
  ORDER BY [store!!name]
  FOR XML EXPLICIT
  
  這個查詢初看起來有點復雜其實它只是把不同的數據集(即這裡的Store和Sale)分解到了獨立的SELECT語句裡然後再用UNION ALL操作符連結成一個查詢
  
  我們之所以要把查詢寫成上面的形式是為了讓查詢結果不僅包含XML文檔所描述的數據而且還包含描述XML文檔結構的元數據上述查詢所生成的表稱為Universal表sqlxmldll生成XML文檔時需要這種格式Universal表對於編寫代碼的人來說是透明的但了解這個表還是很有意義的它將有助於代碼的開發和調試下面是Universal表的一個例子
  
  Tag Parent store!!id store!!name sale!!orderno sale!!qty
   NULL Barnum&single;s NULL NULL
   Barnum&single;s A
   Barnum&single;s QA
   NULL Bookbeat NULL NULL
   Bookbeat LL
  
  Universal表和EXPLICIT模式查詢的元數據部分都以紅色表示黑色表示數據比較查詢和表就可以找出sqlxmldll生成XML文檔所需要的元素我們來仔細地分析一下它們描述的是什麼
  
  Tag和Parent列是XML文檔層次結構方面的信息我們可以認為每個SELECT語句代表了一個XML節點而Tag和Parent列讓我們指定節點在文檔層次結構中的位置如果在第二個SELECT語句中指定Tag為指定Parent為就表示為這些數據加上了一個值為的標簽而這些數據的父親是那些標簽為的數據(即第一個SELECT語句)這就使得我們能夠構造出<Store>和<Sale>之間的父子關系而且正如你可能猜想到的它使得我們可以生成任意合法的XML文檔結構注意第一個SELECT命令的parent列設置成了NULL這表示<Store>元素處於最頂層的位置
  
  以黑色表示的數據將成為節點的屬性或元素例如Store_ID就通過列名提供了這方面的信息列名字中的!是分隔符總共可分成四項(四個參數)其中第四個參數是可選的這些參數描述的是
  
  第一個參數描述該列所屬元素的名字在這裡是<Store>元素
  
  第二個是標簽編號它指定了該列信息在XML樹形結構中所處位置
  
  第三個參數指定XML文檔內的屬性或元素名字在這裡名字指定為id
  
  數據列默認被創建為參數所指定節點的屬性即id將成為<Store>節點的屬性如果要指定id是<Store>的一個子元素我們可以使用第四個可選的參數這個參數的一個作用就是讓我們把該項指定為元素例如store!!id!element
  
  由於使用了UNION ALL操作符來連結SELECT語句為了保證SQL查詢的合法性所有SELECT語句的選擇結果必須具有相同數量的列我們使用NULL關鍵詞來補足SELECT語句從而避免了重復數據
  
  通過EXPLICIT模式查詢所生成的XML文檔和通過AUTO模式生成的完全相同那麼為什麼要創建EXPLICIT模式查詢呢?
  
  假設現在有人要求在XML文檔中包含商店的打折信息查看Pubs數據庫我們得知每個商店都可以有到n范圍內的折扣率因此一種合理的方法是在<Store>元素下面加上子元素<Discount>這樣我們就得到如下XML文檔結構
  
  <STORES>
  <STORE Id=&single;&single; Name=&single;&single;>
  <DISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;>
  <AMOUNT></AMOUNT>
  </DISCOUNT>
  <SALE OrdNo=&single;&single; Qty=&single;&single;>
  </SALE>
  </STORE>
  </STORES>
  
  這裡的改動包括
  
  要在<Sale>元素所在的層次增加一個XML元素<Discount>即<Discount>是<Stroe>的子元素
  
  Amount嵌套在<Discount>裡面但不應該是<Discount>元素的屬性
  
  在AUTO模式中是不可能實現這些改動的
  
  下面是創建這個新XML文檔的EXPLICIT模式查詢
  
  SELECT as Tag NULL as Parent
  sstor_id as [Store!!id]
  sstor_name as [Store!!name]
  NULL as [Sale!!orderno]
  NULL as [Sale!!ty]
  NULL as [Discount!!type]
  NULL as [Discount!!lowqty]
  NULL as [Discount!!highqty]
  NULL as [Discount!!amount!element]
  FROM stores s
  UNION ALL
  SELECT
  sstor_id
  sstor_name
  saord_num
  saqty
  NULL
  NULL
  NULL
  NULL
  FROM stores s sales sa
  WHERE sstor_id = sastor_id
  UNION ALL
  SELECT
  NULL
  sstor_name
  NULL
  NULL
  ddiscounttype
  dlowqty
  dhighqty
  ddiscount
  FROM stores s discounts d
  WHERE sstor_id = dstor_id
  ORDER BY [store!!name]
  For XML EXPLICIT
  
  為了創建圖A所顯示的EXPLICIT模式查詢我們對圖的查詢進行了如下修改
  
  增加了第三個子查詢提取折扣數據通過Tag列聲明這些數據的標簽值為
  
  通過指定Parent列為將折扣數據設置成<Store>元素的子元素 From:http://tw.wingwit.com/Article/program/SQLServer/201311/22115.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.