學習之路十二:SQL Server操作XML以及遇到的問題


  這幾天項目業務需求需要對數據庫中的一段XML進行操作,雖然以前看過幾眼但是都忘記了,沒印象了,所以這幾天簡簡單單的學習了一下,於是把感悟與大家分享一下!

  先吐槽一下,我總是對“create”和“declare”搞亂,昨天寫存儲過程直接寫成“declare procedure P_GetInfo”這樣的語句,結果執行報錯了,找了有半個小時了還沒有搞定,結果找Leader過來一看說你看看你定義存儲過程的語法對不對,我愣了一下,慚愧了,人品弱爆了,以后不能粗心大意了,教訓,不多說了,Let's go!

  我XML的格式如下

 1 <Canvas name="" designWidth="640" designHeigh = "100" >
 2   <Button name="1" width="5" height="2"  />
 3   <Button name="2" width="5" height="2"  />
 4   <Button name="3" width="5" height="2"  />
 5   <Button name="4" width="3" height="2"  />
 6   <Button name="5" width="5" height="2"  />
 7   <Button name="6" width="3" height="2"  />
 8   <Button name="7" width="3" height="2"  />
 9   <Button name="8" width="4" height="2"  />
10   <Button name="9" width="3" height="2"  />
11   <Button name="10" width="4" height="2"  />
12   <Button name="11" width="3" height="2"  />
13   <Button name="12" width="5" height="2"  />
14   <Button name="13" width="5" height="2"  />
15   <Button name="14" width="5" height="2"  />
16   <Button name="15" width="3" height="2"  />
17   <Button name="16" width="3" height="2"  />
18   <Button name="17" width="5" height="2"  />
19 </Canvas >

  1.查詢

    ①query(xquery) 

       有篩選和查詢功能,最主要的還是篩選功能!

       查找Button節點中屬性“name”的值為15的需求:

1 --查找節點中的屬性
2 --語法 → '路徑(應該是絕對路徑)[屬性名 = "屬性值"]' 等於 '/Canvas/Button[@name="45"]'
3 --注意單引號和雙引號的使用,注意“[]”的使用,應該是一種語法把!
4 --Note:這樣的方式只能查出當前節點中屬性是否滿足條件,不會返回所有
5 --應用場景:如果只是查找xml內部的話建議使用“query”進行查詢
6 SELECT Configuration.query('Canvas/Button[@name="15"]') FROM devDTTSConfig  //devDTTSConfig是我存儲xml的數據表

        注意“@”符號的使用,以及把你用於過濾屬性的值用雙引號括起來(建議都要加上,如果是int型的可以不要加),這些都是個語法規則!

      查詢的結果為:

1 <Button name="15" width="3" height="2"  />

      last:查找Button最后一個節點,相當於xml上面的第十七個節點!

1 SELECT Configuration.query('Canvas/Button[last()]') FROM devDTTSConfig       

    

    ②value(xquery)

      有獲取屬性值和獲取節點值的功能!

      ★:獲取節點中屬性的值:

1 --查詢xml中我所指定的屬性值
3 --如果對節點中屬性值的長度沒有很好的把握的話,建議使用 → NVARCHAR(max)
4 SELECT Configuration.value('(Canvas/Button/@name)[1]','NVARCHAR(4)') FROM devDTTSConfig 
5 SELECT Configuration.value('(Canvas/Button/@width)[1]','NVARCHAR(max)') FROM devDTTSConfig 
6 SELECT Configuration.value('(Canvas/Button/@height)[1]','NVARCHAR(max)') FROM devDTTSConfig 

      這樣就能把查詢XML第一個節點中的屬性值!

      Note:說明一下“[]”的作用,相當於索引器,不過它是從“1”開始的,如果我把“name”后面中括號填“1”(以上面的數據為例),查出來的值就為“1”,如果填“2”,值就為“2”,以此類推!

      ★:對節點中的屬性值進行篩選 

1 --如果要對xml中的數據進行篩選,可以先獲取屬性值再進行篩選
2 --應用場景:如果是通過xml條件查找其它數據可以實現“value”進行查詢
3 SELECT * FROM devDTTSConfig WHERE Configuration.value('(Canvas/Button/@width)[1]','NVARCHAR(max)') = 5  //只會篩選xml中Button節點中的第一個節點
4 SELECT * FROM devDTTSConfig WHERE Configuration.value('(Canvas/Button/@name)[1]','NVARCHAR(max)') LIKE '%1%'
5 SELECT * FROM devDTTSConfig WHERE Configuration.value('(Canvas/Button/@height)[1]','NVARCHAR(max)') > 211

      總結:對於“value”查詢,雖然比較靈活,但局限性比較大,它只能對某一個節點進行篩選,而不是在xml下所有相同節點的篩選,所以在大多數的情況下使用“query”進行篩選是一個很好的選擇

 

    ③exist

       語法跟query類似,返回值為“1”或“0”,返回“1” → 存在,反之不存在!

1 SELECT Configuration.exist('Canvas/Button[@height=2]') FROM devDTTSConfig

 

  2.遇到的問題

     項目需要對xml中節點的屬性值進行過濾,而這些屬性值都是動態指定的,一開始就采用下面的這種方式如:

1 SELECT Configuration.query('Canvas/Button[@height="'+@height+'"]') FROM devDTTSConfig

    采用的是嵌入參數的方式,但是一直報錯,說必須輸入的為一個“string”類型的字符串!

    第一種方法:一種比較簡單的方式,使用 → sql:variable("參數名"),但這種很少人知道,所以基本不會用,詳細請看:SQL 中操作XML類型數據 

1 SELECT Configuration.exist('Canvas/Button[@height= sql:variable("@height") ]') FROM devDTTSConfig

    第二種方法:最后還是使用拼接字符串的方式搞定的(leader教我的,o(︶︿︶)o )!

    所以說拼接字符串在很大程度上解決了很多難題,不過拼接字符串比較頭疼是單引號處理的問題,不懂的人要搞的累死才能寫對,哎,我就是屬於這種人! 

 1 CREATE PROC [dbo].[sp_GetTsConfig]
 2 (
 3     @buttonTypeNo        NVARCHAR(10),
 4     @objectNo            NVARCHAR(10)
 5 )
 6 AS
 7     EXECUTE 
 8     ('
 9     SELECT devDTTSConfig.ID,
10            devDTTSConfig.TSConfigNumber,
11            devDTTSConfig.ScreenName,
12            devDTTSConfig.TSType,
13            devDTTSConfig.[Template],
14            devDTTSConfig.ViewAs,
15            devDTTSConfig.[Language],
16            devDTTSConfig.[Status],
17            devDTTSConfig.UpUser,
18            devDTTSConfig.UpDT,
19            devDTTSConfig.Calc_No,
20            T.configuration
21     FROM   (
22                SELECT ButtonTable.TSConfigNumber,
23                       ButtonTable.ButtonType AS configuration
24                FROM   (
25                           SELECT TSConfigNumber,
26                                  Configuration.query(''(/Canvas/Button[@buttonType="'+@buttonTypeNo+'"])'') AS ButtonType,
27                                  Configuration.query(''(/Canvas/Button[@objectNo="'+@objectNo+'"])'') AS ButtonNumber
28                           FROM   devDTTSConfig
29                       ) AS ButtonTable
30                WHERE  ButtonTable.ButtonType IS NOT NULL
31                       AND ButtonTable.ButtonNumber IS NOT NULL
32                       AND ButtonTable.ButtonType.value(''(/Button/@objectNo)[1]'', ''nvarchar(max)'') IS NOT NULL
33                       AND ButtonTable.ButtonNumber.value(''(/Button/@buttonType)[1]'', ''nvarchar(max)'') IS NOT NULL
34            ) AS T
35            INNER JOIN devDTTSConfig ON  devDTTSConfig.TSConfigNumber = T.TSConfigNumber 
36     Order by devDTTSConfig.UpDT desc
37     ')

        

關於XML的添加刪除修改可以參考以下文章:

http://www.cnblogs.com/guopeng/archive/2009/12/11/1621527.html

http://www.cnblogs.com/wuhong/archive/2011/04/15/2017281.html

http://www.cnblogs.com/gcb999/archive/2012/04/05/2433498.html

http://www.cnblogs.com/kingwangzhen/archive/2012/01/05/2313495.html 

以同步至 → 程序猿個人文章目錄索引 (一直更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM