1. 程式人生 > >SQL 2005 中的XML型別 .

SQL 2005 中的XML型別 .

SQL Server 2005的XmL資料型別之基礎篇
一、引言
如今,在SQL Server 2005中,XML成為第一流的資料型別。藉助於基於XML模式的強型別化支援和基於伺服器端的XML資料校驗功能,現在,開發者可以對儲存的XML文件進行輕鬆的遠端修改。
作為資料庫開發者,許多人都必須大量地涉及XML。

  如今,在SQL Server 2005中,你能以一種新的資料型別的形式把XML儲存在資料庫中。

  事實上,在SQL Server 2000中就已經包括了一些XML特徵。其中,最關鍵的特徵是使用FOR XML語句以XML形式返回結果。SQL Server 2005的功能則明顯不同。在SQL Server 2005中,XML是一種真正的資料型別;這意味著,你可以使用XML作為表和檢視中的列,XML可以用於T-SQL語句中或作為儲存過程的引數。現在,你可以直接在資料庫中儲存、查詢和管理XML檔案。

重要的是,現在你還能規定你的XML必須遵從的模式。

  在SQL Server 2005中,除了提供機制以校驗你的資料庫中的XML型別之外,它還允許你描述要被儲存的複雜資料型別並且提供一個引擎來強制施加這些規則。


二、 使用XML資料型別

  其實,XML資料型別與SQL Server中的其它資料型別並不存在根本的區別。你可以把它用在使用任何普通SQL資料型別的地方。例如,下列語句建立一個XML變數並用一個XML填充它:
      DECLARE @doc xml
      SELECT @doc = '<Team name="Braves" />'

另外,你還可以使用一個查詢和SQL Server的FOR XML語法來填充一個XML變數:
      SELECT @doc =
      (SELECT * FROM Person.Contact FOR XML AUTO)

XML資料型別不僅可以作為變數使用,也可以應用於表列中。你還能分配預設值並且支援NOT NULL約束:
      CREATE TABLE Team
      (
      TeamID int identity not null,
      TeamDoc xml DEFAULT '<Team />' NOT NULL
      )

注意:SQL Server 2005的XML功能與SQL Server 2000中具有明顯的不同。

把XML資料插入到表格中只需要用字串形式的XML指定即可。

下列示例插入一組記錄:
      INSERT INTO Team (TeamDoc)
      VALUES ('
      <Team name="Braves">
      <Players>
      <Pitcher name="John Smoltz"
      role="Closer"/>
      </Players>
      </Team>');
      INSERT INTO Team (TeamDoc)
      VALUES ('
      <Team name="Red Sox">
      <Players>
      <Pitcher name="Petro Martinez"
      role="Starter"/>
      </Players>
      </Team>');


當在SQL Server 2005中建立XML的例項時,唯一的轉換是從一個字串轉換成一個XML型別。同樣,沿著相反的方向,你只可以把XML型別轉換成一個字串型別。在text和ntext型別之間轉換是不允許的。


三、 XML資料型別的限制

  儘管在SQL Server 2005中XML資料型別就象許多其它資料型別一樣對待,但是還存在一些如何使用它的具體限制。這些限制是:

  · XML型別不能轉換成text或ntext資料型別。

  · 除了string型別,沒有其它資料型別能夠轉換成XML。

  · XML列不能應用於GROUP BY語句中。

  · 分散式區域性(partitioned)檢視不能包含XML資料型別。

  · sql_variant例項的使用不能把XML作為一種子型別。

  · XML列不能成為主鍵或外來鍵的一部分。

  · XML列不能指定為唯一的。

  · COLLATE子句不能被使用在XML列上。

  · XML列不能加入到規則中。

  · 唯一可應用於XML列的內建標量函式是ISNULL和COALESCE。沒有任何其它內建標量函式支援使用XML型別。

  · 表中最多隻能擁有32個XML列。

  · 具有XML列的表不能有一個超過15列的主鍵。

  · 具有XML列的表不能有一個timestamp資料型別作為它們的主鍵的一部分。

  · 儲存在資料庫中的XML僅支援128級的層次。


四、 XML型別方法

  到此為止,上面的示例已經展示了XML資料型別僅能用作一種blob型別資料,但是這正是XML資料型別顯示其自身力量的地方。XML資料型別支援使用UDT點(myXml.operation())語法進行呼叫的若干方法。下表1中列舉出所支援的方法。

  表格1:XML資料型別方法。
      方法名 描述
      query    執行一個XML查詢並且返回查詢的結果
      exists    執行一個XML查詢,並且如果有結果的話返回值1
      value    計算一個查詢以從XML中返回一個簡單的值
      modify    在XML文件的適當位置執行一個修改操作
      nodes    允許你把XML分解到一個表結構中

在下面幾節中,你要使用一個表Team,它的每一個行中包含一個小組的名字。在每一行中,有一個包含有關於該小組的XML資料的TeamDoc行:
      CREATE TABLE Team
      (
      TeamID int identity not null,
      TeamDoc xml DEFAULT '<Team />' NOT NULL
      )

在這些例子中,我們假定下面的XML文件存在於表中的Braves行中:
<Team name="Braves">
<Players>
<Pitcher name="John Smoltz" role="Closer"/>
<Pitcher name="Russ Ortiz" role="Starter" />
<ThirdBase name="Chipper Jones"
role="Starter" bats="switch"/>
</Players>
</Team>


 query方法

  注意:你可以在表和檢視列、T-SQL語句或儲存過程的引數中使用XML。

  這個方法允許你指定一個要計算的Xquery或XPath表示式,該方法的結果是一個XML資料型別物件。它的具體語法形式如下:

    query(XQuery)
第一個引數總是一個Xquery表示式。下面的例子使用一個查詢來返回一個XML文件-其中包含有關每一個小組的投球手的資訊:
      SELECT TeamDoc.query('/Team/Players/Pitcher')
      FROM Team

這個語句產生如下結果:

----------------------------------------------
      <Pitcher name="John Smoltz" role="Closer" />
      <Pitcher name="Russ Ortiz" role="Starter" />
      (1 row(s) affected)

這個query方法允許你查詢和返回與你指定的表示式相匹配的結點列表。該方法的真正威力來自於XQuery語法,我們將在本文後面再詳細討論。


exist方法

  這個exist方法用於決定是否一個查詢能夠產生任何結果。這個exist方法的語法形式如下:

exist(XQuery)

當你使用這個exist方法時,它計算這個XQuery查詢,並且如果該查詢產生任何結果的話返回值1。例如,下面語句查詢小組錶行中是否TeamDoc域中存有Starter投手:

--下面是簡單的Exist語句:

   SELECT Count(*)
   FROM Team
   WHERE TeamDoc.exist(
   '/Team/Players/Pitcher[@role="Starter"]') = 1

value方法

  當你不想解釋整個查詢的結果而只想得到一個標量值時,這個value方法是很有幫助的。這個value方法用於查詢XML並且返回一個原子值。這個value方法的語法如下:

value(XQuery,datatype)

  藉助於value方法,你可以從XML中得到單個標量值。為此,你必須指定XQuery語句和你想要它返回的資料型別,並且你可以返回除了XML資料型別外的任何資料型別。例如,如果你想得到每一個小組中的第一個投球手的名字,你可以編寫如下形式的查詢語句:

  --進行一次查詢以得到單個值

SELECT TeamDoc.value(
'(/Team/Players/Pitcher/@name)[1]'
'nvarchar(max)')
AS FirstPitcher
FROM Team


在每一個小組的第一個投球手的標量值中的這個查詢結果返回值如下:
FirstPitcher
------------------------------
John Smoltz
(1 row(s) affected)


注意,query和value方法之間的不同在於,query方法返回一個XML資料型別-它包含查詢的結果;而value方法返回一個帶有查詢結果的非XML資料型別。另外,value方法僅能返回單個值(或標量值)。如果你試圖建立一個使用value方法返回多於一個值的XQuery表示式,你將得到一個錯誤。


modify方法

  儘管XQuery標準並沒有提供一種更新XML的機制,但是SQL Server 2005提供了一種方法用於即時地修改一個XML物件的一部分。這意味著,你不必僅為了修改而檢索一個完整的XML文件。為了即時修改一個文件,你可以採用一種結合方式-Modify方法和SQL Server 2005的新的XML資料修改語言(XML DML)。

  Modify方法的語法是:

modify(<XMLDML>)

  該方法僅使用一個引數:XML DML語句。XML DML也類似於SQL的insert,update和delete語法,但是並不一樣。例如,你可以通過使用insert DML語句來修改XML:

SET @doc.modify('
insert <Pitcher name="Jaret Wright"/> as last
into (/Team/Players)[1]
')

  另外,你還可以通過呼叫一個UPDATE語句並修改一個XML列來實現同樣目的:

  --修改一個XML文件而不完全替換它:

UPDATE Team
SET TeamDoc.modify('
insert <Pitcher name="Jaret Wright"/> as last
into (/Team/Players)[1]
')
WHERE TeamDoc.exist('/Team[@name="Braves"]') = 1  

  注意,在這個UPDATE語句中的SET子句並不遵循你過去編寫SQL時所使用的SET x = y 模式。該語法假定,你能夠提供一個完全新的值來代替舊值-這在XML情況下意味著要使用一個完全新的文件來代替舊文件。當使用XML型別時,Modify方法可以即時修改原始文件。也就是說,對於SQL Server來說,不必要對每一次修改都試圖替換整個文件。在本例中的SET語法反映了一種即時修改一個文件的更為有效的方式。

  共有三種XML DML語句:insert,update和delete。這三個語句分別用於插入,更新和刪除一個XML物件的部分。每一個方法的語法類似於SQL,但是也有一些明顯的差別。

  下面是相應於insert語句的語法:

insert
InsertExpression (
{{as first | as last}
into | after | before} LocationExpression
)

  緊跟著這個insert語句的是你想要插入的XML(InsertExpression)。接下來,你需要指定你想怎樣插入該XML。你的選擇是into,after或before。其中,before和after子句指令資料庫把InsertExpression作為LocationExpression的一個兄弟(sibling)插入。before或after則指定是在LocationExpression的前面還是後面插入它:

SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
before (/Team/Players/Pitcher)[1]
')

  這個into子句把InsertExpression作為LocationExpression的一個孩子結點插入。可選子句as first和as last用於指定在該孩子結點中插入的位置:

  --在小組內進行插入

SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
into (/Team/Players)[1]
')

  --在小組內進行插入,指定它應該

  --作為最後一個元素插入

SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
as last into (/Team/Players)[1]
')

  delete語句的語法很直接:

delete LocationExpression

  這個LocationExpression指定要從XML資料中刪除什麼內容。例如,要刪除所有的投球手:

SET @doc.modify('delete/Team/Player/Pitcher')

  因為查詢指定所有的投球手元素,所以它們將被全部刪除。如果你想僅刪除一個元素,那麼你可以指定標識屬性。例如,為了僅刪除投球手John Smoltz,你可以編寫如下的delete語句:

SET @doc.modify('
delete /Team/Players/Pitcher[@name="John Smoltz"]
')

  你可以使delete語句刪除單個屬性。例如,為了刪除針對投球手John Smoltz的role屬性,相應的XML DML看上去如下所示:

SET @doc.modify('
delete /Team/Players/Pitcher[
@name="John Smoltz"]/@role')

  最後,replace value語句描述了對XML資料的修改。這個replace value語句的語法如下:

replace value of
OriginalExpression
with
ReplacementValue | if

  這個replace value語句用來修改在XML中的值。唯一可能的值是一個標籤的內容或一個屬性的值。這個OriginalExpression必須解析為單個結點或屬性。這個ReplacementValue通常是一個要代替的值。代替一個結點的內容要求使用text()函式的XQuery表示式來指定你想代替一個結點的文字。例如,為了替換一個投球手的內部文字(inner text),你可以編寫類似如下的Modify語句:

DECLARE @doc xml
SELECT @doc = '
<Team name="Braves">
<Players>
<Pitcher name="John Smoltz" role="Closer">
With team since 1989
</Pitcher>
</Players>
</Team>'
SET @doc.modify('
replace value of (/Team/Players/Pitcher[
@name="John Smoltz"]/text())[1]
with "May start in 2005"
')

  修改屬性是直接的:你只需要使用XQuery表示式來解析單個屬性。例如,為了使用"Starter"替換投球手John Smoltz的role屬性的值,你可以編寫如下的語句:

SET @doc.modify('
replace value of (/Team/Players/Pitcher[
@name="John Smoltz"]/@role)[1]
with "Starter"
')

  replace value語法也支援條件替換,這可以通過在replace value語句的with子句內使用if…then…else語法實現。例如,如果John Smoltz是一個Closer的話,把他的role替換為Starter;但是如果他不是一個Starter的話,則把role屬性修改為Closer;那麼,你可以編寫如下的程式碼:

SET @doc.modify('
replace value of (/Team/Players/Pitcher[
@name="John Smoltz"]/@role)[1]
with (
if (/Team/Players/Pitcher[
@name="John Smoltz"]/@role = "Closer") then
"Starter"
else
"Closer"
)
')


nodes方法

  nodes方法用於把一組由一個查詢返回的結點轉換成一個類似於結果集的表中的一組記錄行。該方法的語法如下:

nodes (XQuery) Table(Column)

  這裡,XQuery是選擇要暴露為一個結果集的結點的表示式。Table和Column用於指定結果集中的名字。注意,你僅可以操作一列並且它的自動型別為XML。例如,為了查詢並得到每一個投球手的資訊,你可以編寫如下的程式碼:

DECLARE @doc xml
SELECT @doc = '
<Team name="Braves">
<Players>
<Pitcher name="John Smoltz" role="Closer">
With team since 1989
</Pitcher>
</Players>
</Team>'
SELECT Team.player.query('.') as Pitcher
FROM @doc.nodes('/Team/Players/Pitcher')
Team(player)  

  這些在單個結果集中的結果包含相應於每一個投球手的元素的行資料:

Pitcher
--------------------------------------------
<Pitcher name="John Smoltz" role="Closer" />
<Pitcher name="Russ Ortiz" role="Starter" />
(2 row(s) affected)

  注意,上面你使用了query方法把這些結點返回到結果中。其原因在於,一個nodes方法的結果可能僅能為XML方法(查詢,修改,刪除和更新)或IS NULL和IS NOT NULL語句所參考。

  一般地,你可以使用nodes方法把XML分解為一組更為有用的結果。例如,你可以使用nodes方法得到運動員的結點,然後使用value方法檢索它們以便得到作為標量資料的單個值:

SELECT Team.player.value(
'./@name', 'nvarchar(10)') as Name,
Team.player.value('./@role', 'nvarchar(10)') as
PlayerRole
FROM @doc.nodes('/Team/Players/Pitcher')
Team(player)

  這會產生如下的結果:

Name PlayerRole
--------------- ---------------
John Smoltz Closer
Russ Ortiz Starter
(2 row(s) affected)

相關推薦

SQL 2005 XML型別 .

SQL Server 2005的XmL資料型別之基礎篇 一、引言 如今,在SQL Server 2005中,XML成為第一流的資料型別。藉助於基於XML模式的強型別化支援和基於伺服器端的XML資料校驗功能,現在,開發者可以對儲存的XML文件進行輕鬆的遠端修改。 作為資料庫開發者,許多人都必須大量地涉及XML

SQL SERVER強制型別轉換cast和convert的區別

selectCAST('123'asint)   -- 123selectCONVERT(int, '123')  -- 123selectCAST(123.4asint)   -- 123selectCONVERT(int, 123.4)  -- 123 selectCAST('123.4'asint)se

SQL資料庫資料型別ntext和text的區別

4、NCHAR、NVARCHAR、NTEXT。這三種從名字上看比前面三種多了個“N”。它表示儲存的是Unicode資料型別的字元。我們知道字元中,英文字元只需要一個位元組儲存就足夠了,但漢字眾多,需要兩個位元組儲存,英文與漢字同時存在時容易造成混亂,Unicode字符集就是為了解決字符集這種不相容的問題而產生

SQL SERVER強制型別轉換cast和convert

在SQL SERVER中,cast和convert函式都可用於型別轉換,其功能是類似,只是語法不同。 語法: cast ( expression as data_type [ (length ) ])convert ( data_type [ ( length ) ] ,

sql server字串型別的日期如何比較大小

日期資料在Sql Server資料庫中不都是以日期型別儲存的,如果資料庫中儲存日期欄位的資料型別為varchar,而你又需要對這個日期和另外一個日期進行比較,那麼該怎麼辦呢?總結有以下方法 (1)方法一 這個方法很容易想到,就是純粹地利用字串來比較大小,比如有一個欄位為a

2、SQL Server 2005使用XML資料型別

這一節將介紹如何用普通的T-SQL語句來操作XML資料。同時介紹了XML資料型別的一些特點。 < xmlnamespace prefix ="st1" ns ="urn:schemas-micr

無法在SQL 2005系統資料庫執行的T-SQL語句(XML處理)

表現:下面的程式碼, 在相容性級別90的所有使用者資料庫和tempdb庫中都能執行, 但無法在系統資料庫中執行, 執行會收到如下錯誤:Msg 4121, Level 16, State 1, Line 2Cannot find either column "dbo" or the user-defined

SQL Server 2005的分區表(五):添加一個分區

eat 查詢 sch 另一個 rom 原創 查看 copyto art 所謂天下大事,分久必合,合久必分,對於分區表而言也一樣。前面我們介紹過如何刪除(合並)分區表中的一個分區,下面我們介紹一下如何為分區表添加一個分區。 為分區表添加一個分區,這種情況是時常會

SQL Server 2005的分區表(三):將普通表轉換成分區表

成了 insert 刪掉 -- pri light part ide 新建 在設計數據庫時,經常沒有考慮到表分區的問題,往往在數據表承重的負擔越來越重時,才會考慮到分區方式,這時,就涉及到如何將普通表轉換成分區表的問題了。 那麽,如何將一個普通表轉換成一個分區表 呢

SQL Server 2005的分區表(一):什麽是分區表?為什麽要用分區表?如何創建分區表?

ima 查詢條件 出錯 數據的操作 之間 方便 如何 oar 意思 如果你的數據庫中某一個表中的數據滿足以下幾個條件,那麽你就要考慮創建分區表了。 1、數據庫中某個表中的數據很多。很多是什麽概念?一萬條?兩萬條?還是十萬條、一百萬條?這個,我覺得是仁者見仁、智者

深入理解SQL Server 2005 的 COLUMNS_UPDATED函數

clas arch size else 方式 它的 語句 存在 順序 原文:深入理解SQL Server 2005 中的 COLUMNS_UPDATED函數 概述 COLUMNS_UPDATED函數能夠出現在INSERT或UPDATE觸發器中AS關鍵字後的任何位置,用來

VS2010連接sql 2005連接問題microsoft.sqlserver.management.sdk.sfc

sql 未能加載 .com lin nbsp 官方 eight height VS2010 在VS2010中連接sql 2005時出現 無法添加數據連接。未能加載文件或程序集“microsoft.sqlserver.management.sdk.sfc,versio

複雜SQL語句的書寫(mybatisXML檔案的核心)

select sd.name as dptName, pro.`name` as provinceName, c.`name` as cityName, a.`name` as areaName, info.id, dpt.*, info.*, gd.*

寶書課程#1:Ada 2005的受限型別 --受限集合

寶書課程#1:Ada 2005中的受限型別 --受限集合 by Bob Duff—AdaCore Translator:Dongfeng.Gu 讓我們開始吧… 一個Ada我所喜歡的特徵是對於集合的“全覆蓋規則”。例如,假設我們有一個記錄型別:   &nbs

SQL server的資料型別總結

n的取值範圍為1~53,預設值為53,為用於儲存float型別書的維數的位數,當n取1~24時佔據4位元組儲存空間,25~53則佔據8位元組儲存空間,float取值範圍為-1.79E+308 ~ -2.23E-308,0,2.23E-308 ~ 1.79E+308

Sql Server 2005 Analysis Services無法連線

今天又吐血,用Sql Server Management Studio無法連線Sql Server 2005 中Analysis Services。 出現“重疊I/O操作在進行中”。 原來是與校園網連線的DrCOM有衝突。設了DrCOM開機登陸,所以重灌N次Sql Serve

SQL Server,Numric,Decimal,Money三種欄位型別的區別

SQL Server中,Numric,Decimal,Money三種欄位型別的區別 都是精確資料型別, 前兩個可以自己定義長度和小數位數, Money的定義相當於Numric(19,4) numeric(10,2)  表示最大可以放10位數,但這10位數裡有2位是小數如: 

SQL Server與IO相關的等待型別:IO_COMPLETION和PAGEIOLATCH_*

一個大的SQL語句操作,執行計劃中包含了一個merge join操作,觀察到SQL長時間處於IO_COMPLETION等待狀態,如果是讀取相關的表的資料,伺服器應該全力為其服務,但是伺服器的物理IO又遠遠沒有達到瓶頸。這個IO_COMPLETION到底是在做什麼?是表的資料頁IO請求還在其他操作?如果是,跟P

SQL Server的Image資料型別的操作

準備工作,在庫Im_Test中建立一張表Im_Info,此表中有兩個欄位,分別為Pr_Id (INT),Pr_Info (IMAGE),用來儲存圖形編號及圖形資訊。其語法如下: CREATE TEALE Im_Info ( Pr_Id INT NULL , Pr_Info IMAGE NULL

在2010連線sql 2005時出現的問題

在2010中連線sql 2005時出現以下問題   無法新增資料連線。未能載入檔案或程式集“microsoft.sqlserver.management.sdk.sfc,version=10.0.0.0,culture=neutral,publickeytokun=……”的