exist方法
這個(gè)exist方法用于決定是否一個(gè)查詢能夠產(chǎn)生任何結(jié)果。這個(gè)exist方法的語(yǔ)法形式如下:
exist(XQuery)
當(dāng)你使用這個(gè)exist方法時(shí),它計(jì)算這個(gè)XQuery查詢,并且如果該查詢產(chǎn)生任何結(jié)果的話返回值1。例如,下面語(yǔ)句查詢小組表行中是否TeamDoc域中存有Starter投手:
--下面是簡(jiǎn)單的Exist語(yǔ)句:
SELECT Count(*)
FROM Team
WHERE TeamDoc.exist(
'/Team/Players/Pitcher[@role="Starter"]') = 1
value方法
當(dāng)你不想解釋整個(gè)查詢的結(jié)果而只想得到一個(gè)標(biāo)量值時(shí),這個(gè)value方法是很有幫助的。這個(gè)value方法用于查詢XML并且返回一個(gè)原子值。這個(gè)value方法的語(yǔ)法如下:
value(XQuery,datatype)
借助于value方法,你可以從XML中得到單個(gè)標(biāo)量值。為此,你必須指定XQuery語(yǔ)句和你想要它返回的數(shù)據(jù)類型,并且你可以返回除了XML數(shù)據(jù)類型外的任何數(shù)據(jù)類型。例如,如果你想得到每一個(gè)小組中的第一個(gè)投球手的名字,你可以編寫如下形式的查詢語(yǔ)句:
--進(jìn)行一次查詢以得到單個(gè)值
SELECT TeamDoc.value(
'(/Team/Players/Pitcher/@name)[1]',
'nvarchar(max)')
AS FirstPitcher
FROM Team
在每一個(gè)小組的第一個(gè)投球手的標(biāo)量值中的這個(gè)查詢結(jié)果返回值如下:
FirstPitcher
------------------------------
John Smoltz
(1 row(s) affected)
注意,query和value方法之間的不同在于,query方法返回一個(gè)XML數(shù)據(jù)類型-它包含查詢的結(jié)果;而value方法返回一個(gè)帶有查詢結(jié)果的非XML數(shù)據(jù)類型。另外,value方法僅能返回單個(gè)值(或標(biāo)量值)。如果你試圖創(chuàng)建一個(gè)使用value方法返回多于一個(gè)值的XQuery表達(dá)式,你將得到一個(gè)錯(cuò)誤。
modify方法
盡管XQuery標(biāo)準(zhǔn)并沒(méi)有提供一種更新XML的機(jī)制,但是SQL Server 2005提供了一種方法用于即時(shí)地修改一個(gè)XML對(duì)象的一部分。這意味著,你不必僅為了修改而檢索一個(gè)完整的XML文檔。為了即時(shí)修改一個(gè)文檔,你可以采用一種結(jié)合方式-Modify方法和SQL Server 2005的新的XML數(shù)據(jù)修改語(yǔ)言(XML DML)。
Modify方法的語(yǔ)法是:
modify(<XMLDML>)
該方法僅使用一個(gè)參數(shù):XML DML語(yǔ)句。XML DML也類似于SQL的insert,update和delete語(yǔ)法,但是并不一樣。例如,你可以通過(guò)使用insert DML語(yǔ)句來(lái)修改XML:
SET @doc.modify('
insert <Pitcher name="Jaret Wright"/> as last
into (/Team/Players)[1]
')
另外,你還可以通過(guò)調(diào)用一個(gè)UPDATE語(yǔ)句并修改一個(gè)XML列來(lái)實(shí)現(xiàn)同樣目的:
--修改一個(gè)XML文檔而不完全替換它:
UPDATE Team
SET TeamDoc.modify('
insert <Pitcher name="Jaret Wright"/> as last
into (/Team/Players)[1]
')
WHERE TeamDoc.exist('/Team[@name="Braves"]') = 1
注意,在這個(gè)UPDATE語(yǔ)句中的SET子句并不遵循你過(guò)去編寫SQL時(shí)所使用的SET x = y 模式。該語(yǔ)法假定,你能夠提供一個(gè)完全新的值來(lái)代替舊值-這在XML情況下意味著要使用一個(gè)完全新的文檔來(lái)代替舊文檔。當(dāng)使用XML類型時(shí),Modify方法可以即時(shí)修改原始文檔。也就是說(shuō),對(duì)于SQL Server來(lái)說(shuō),不必要對(duì)每一次修改都試圖替換整個(gè)文檔。在本例中的SET語(yǔ)法反映了一種即時(shí)修改一個(gè)文檔的更為有效的方式。
共有三種XML DML語(yǔ)句:insert,update和delete。這三個(gè)語(yǔ)句分別用于插入,更新和刪除一個(gè)XML對(duì)象的部分。每一個(gè)方法的語(yǔ)法類似于SQL,但是也有一些明顯的差別。
下面是相應(yīng)于insert語(yǔ)句的語(yǔ)法:
insert
InsertExpression (
{{as first | as last}
into | after | before} LocationExpression
)
緊跟著這個(gè)insert語(yǔ)句的是你想要插入的XML(InsertExpression)。接下來(lái),你需要指定你想怎樣插入該XML。你的選擇是into,after或before。其中,before和after子句指令數(shù)據(jù)庫(kù)把InsertExpression作為L(zhǎng)ocationExpression的一個(gè)兄弟(sibling)插入。before或after則指定是在LocationExpression的前面還是后面插入它:
SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
before (/Team/Players/Pitcher)[1]
')
這個(gè)into子句把InsertExpression作為L(zhǎng)ocationExpression的一個(gè)孩子結(jié)點(diǎn)插入??蛇x子句as first和as last用于指定在該孩子結(jié)點(diǎn)中插入的位置:
--在小組內(nèi)進(jìn)行插入
SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
into (/Team/Players)[1]
')
--在小組內(nèi)進(jìn)行插入,指定它應(yīng)該
--作為最后一個(gè)元素插入
SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
as last into (/Team/Players)[1]
')
delete語(yǔ)句的語(yǔ)法很直接:
delete LocationExpression
這個(gè)LocationExpression指定要從XML數(shù)據(jù)中刪除什么內(nèi)容。例如,要?jiǎng)h除所有的投球手:
SET @doc.modify('delete/Team/Player/Pitcher')
因?yàn)椴樵冎付ㄋ械耐肚蚴衷兀运鼈儗⒈蝗縿h除。如果你想僅刪除一個(gè)元素,那么你可以指定標(biāo)識(shí)屬性。例如,為了僅刪除投球手John Smoltz,你可以編寫如下的delete語(yǔ)句:
SET @doc.modify('
delete /Team/Players/Pitcher[@name="John Smoltz"]
')
你可以使delete語(yǔ)句刪除單個(gè)屬性。例如,為了刪除針對(duì)投球手John Smoltz的role屬性,相應(yīng)的XML DML看上去如下所示:
SET @doc.modify('
delete /Team/Players/Pitcher[
@name="John Smoltz"]/@role')
最后,replace value語(yǔ)句描述了對(duì)XML數(shù)據(jù)的修改。這個(gè)replace value語(yǔ)句的語(yǔ)法如下:
replace value of
OriginalExpression
with
ReplacementValue | if
這個(gè)replace value語(yǔ)句用來(lái)修改在XML中的值。可能的值是一個(gè)標(biāo)簽的內(nèi)容或一個(gè)屬性的值。這個(gè)OriginalExpression必須解析為單個(gè)結(jié)點(diǎn)或?qū)傩?。這個(gè)ReplacementValue通常是一個(gè)要代替的值。代替一個(gè)結(jié)點(diǎn)的內(nèi)容要求使用text()函數(shù)的XQuery表達(dá)式來(lái)指定你想代替一個(gè)結(jié)點(diǎn)的文本。例如,為了替換一個(gè)投球手的內(nèi)部文本(inner text),你可以編寫類似如下的Modify語(yǔ)句:
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表達(dá)式來(lái)解析單個(gè)屬性。例如,為了使用"Starter"替換投球手John Smoltz的role屬性的值,你可以編寫如下的語(yǔ)句:
SET @doc.modify('
replace value of (/Team/Players/Pitcher[
@name="John Smoltz"]/@role)[1]
with "Starter"
')
replace value語(yǔ)法也支持條件替換,這可以通過(guò)在replace value語(yǔ)句的with子句內(nèi)使用if…then…else語(yǔ)法實(shí)現(xiàn)。例如,如果John Smoltz是一個(gè)Closer的話,把他的role替換為Starter;但是如果他不是一個(gè)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"
這個(gè)exist方法用于決定是否一個(gè)查詢能夠產(chǎn)生任何結(jié)果。這個(gè)exist方法的語(yǔ)法形式如下:
exist(XQuery)
當(dāng)你使用這個(gè)exist方法時(shí),它計(jì)算這個(gè)XQuery查詢,并且如果該查詢產(chǎn)生任何結(jié)果的話返回值1。例如,下面語(yǔ)句查詢小組表行中是否TeamDoc域中存有Starter投手:
--下面是簡(jiǎn)單的Exist語(yǔ)句:
SELECT Count(*)
FROM Team
WHERE TeamDoc.exist(
'/Team/Players/Pitcher[@role="Starter"]') = 1
value方法
當(dāng)你不想解釋整個(gè)查詢的結(jié)果而只想得到一個(gè)標(biāo)量值時(shí),這個(gè)value方法是很有幫助的。這個(gè)value方法用于查詢XML并且返回一個(gè)原子值。這個(gè)value方法的語(yǔ)法如下:
value(XQuery,datatype)
借助于value方法,你可以從XML中得到單個(gè)標(biāo)量值。為此,你必須指定XQuery語(yǔ)句和你想要它返回的數(shù)據(jù)類型,并且你可以返回除了XML數(shù)據(jù)類型外的任何數(shù)據(jù)類型。例如,如果你想得到每一個(gè)小組中的第一個(gè)投球手的名字,你可以編寫如下形式的查詢語(yǔ)句:
--進(jìn)行一次查詢以得到單個(gè)值
SELECT TeamDoc.value(
'(/Team/Players/Pitcher/@name)[1]',
'nvarchar(max)')
AS FirstPitcher
FROM Team
在每一個(gè)小組的第一個(gè)投球手的標(biāo)量值中的這個(gè)查詢結(jié)果返回值如下:
FirstPitcher
------------------------------
John Smoltz
(1 row(s) affected)
注意,query和value方法之間的不同在于,query方法返回一個(gè)XML數(shù)據(jù)類型-它包含查詢的結(jié)果;而value方法返回一個(gè)帶有查詢結(jié)果的非XML數(shù)據(jù)類型。另外,value方法僅能返回單個(gè)值(或標(biāo)量值)。如果你試圖創(chuàng)建一個(gè)使用value方法返回多于一個(gè)值的XQuery表達(dá)式,你將得到一個(gè)錯(cuò)誤。
modify方法
盡管XQuery標(biāo)準(zhǔn)并沒(méi)有提供一種更新XML的機(jī)制,但是SQL Server 2005提供了一種方法用于即時(shí)地修改一個(gè)XML對(duì)象的一部分。這意味著,你不必僅為了修改而檢索一個(gè)完整的XML文檔。為了即時(shí)修改一個(gè)文檔,你可以采用一種結(jié)合方式-Modify方法和SQL Server 2005的新的XML數(shù)據(jù)修改語(yǔ)言(XML DML)。
Modify方法的語(yǔ)法是:
modify(<XMLDML>)
該方法僅使用一個(gè)參數(shù):XML DML語(yǔ)句。XML DML也類似于SQL的insert,update和delete語(yǔ)法,但是并不一樣。例如,你可以通過(guò)使用insert DML語(yǔ)句來(lái)修改XML:
SET @doc.modify('
insert <Pitcher name="Jaret Wright"/> as last
into (/Team/Players)[1]
')
另外,你還可以通過(guò)調(diào)用一個(gè)UPDATE語(yǔ)句并修改一個(gè)XML列來(lái)實(shí)現(xiàn)同樣目的:
--修改一個(gè)XML文檔而不完全替換它:
UPDATE Team
SET TeamDoc.modify('
insert <Pitcher name="Jaret Wright"/> as last
into (/Team/Players)[1]
')
WHERE TeamDoc.exist('/Team[@name="Braves"]') = 1
注意,在這個(gè)UPDATE語(yǔ)句中的SET子句并不遵循你過(guò)去編寫SQL時(shí)所使用的SET x = y 模式。該語(yǔ)法假定,你能夠提供一個(gè)完全新的值來(lái)代替舊值-這在XML情況下意味著要使用一個(gè)完全新的文檔來(lái)代替舊文檔。當(dāng)使用XML類型時(shí),Modify方法可以即時(shí)修改原始文檔。也就是說(shuō),對(duì)于SQL Server來(lái)說(shuō),不必要對(duì)每一次修改都試圖替換整個(gè)文檔。在本例中的SET語(yǔ)法反映了一種即時(shí)修改一個(gè)文檔的更為有效的方式。
共有三種XML DML語(yǔ)句:insert,update和delete。這三個(gè)語(yǔ)句分別用于插入,更新和刪除一個(gè)XML對(duì)象的部分。每一個(gè)方法的語(yǔ)法類似于SQL,但是也有一些明顯的差別。
下面是相應(yīng)于insert語(yǔ)句的語(yǔ)法:
insert
InsertExpression (
{{as first | as last}
into | after | before} LocationExpression
)
緊跟著這個(gè)insert語(yǔ)句的是你想要插入的XML(InsertExpression)。接下來(lái),你需要指定你想怎樣插入該XML。你的選擇是into,after或before。其中,before和after子句指令數(shù)據(jù)庫(kù)把InsertExpression作為L(zhǎng)ocationExpression的一個(gè)兄弟(sibling)插入。before或after則指定是在LocationExpression的前面還是后面插入它:
SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
before (/Team/Players/Pitcher)[1]
')
這個(gè)into子句把InsertExpression作為L(zhǎng)ocationExpression的一個(gè)孩子結(jié)點(diǎn)插入??蛇x子句as first和as last用于指定在該孩子結(jié)點(diǎn)中插入的位置:
--在小組內(nèi)進(jìn)行插入
SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
into (/Team/Players)[1]
')
--在小組內(nèi)進(jìn)行插入,指定它應(yīng)該
--作為最后一個(gè)元素插入
SET @doc.modify('
insert <Pitcher role="Starter"
name="Jaret Wright"/>
as last into (/Team/Players)[1]
')
delete語(yǔ)句的語(yǔ)法很直接:
delete LocationExpression
這個(gè)LocationExpression指定要從XML數(shù)據(jù)中刪除什么內(nèi)容。例如,要?jiǎng)h除所有的投球手:
SET @doc.modify('delete/Team/Player/Pitcher')
因?yàn)椴樵冎付ㄋ械耐肚蚴衷兀运鼈儗⒈蝗縿h除。如果你想僅刪除一個(gè)元素,那么你可以指定標(biāo)識(shí)屬性。例如,為了僅刪除投球手John Smoltz,你可以編寫如下的delete語(yǔ)句:
SET @doc.modify('
delete /Team/Players/Pitcher[@name="John Smoltz"]
')
你可以使delete語(yǔ)句刪除單個(gè)屬性。例如,為了刪除針對(duì)投球手John Smoltz的role屬性,相應(yīng)的XML DML看上去如下所示:
SET @doc.modify('
delete /Team/Players/Pitcher[
@name="John Smoltz"]/@role')
最后,replace value語(yǔ)句描述了對(duì)XML數(shù)據(jù)的修改。這個(gè)replace value語(yǔ)句的語(yǔ)法如下:
replace value of
OriginalExpression
with
ReplacementValue | if
這個(gè)replace value語(yǔ)句用來(lái)修改在XML中的值。可能的值是一個(gè)標(biāo)簽的內(nèi)容或一個(gè)屬性的值。這個(gè)OriginalExpression必須解析為單個(gè)結(jié)點(diǎn)或?qū)傩?。這個(gè)ReplacementValue通常是一個(gè)要代替的值。代替一個(gè)結(jié)點(diǎn)的內(nèi)容要求使用text()函數(shù)的XQuery表達(dá)式來(lái)指定你想代替一個(gè)結(jié)點(diǎn)的文本。例如,為了替換一個(gè)投球手的內(nèi)部文本(inner text),你可以編寫類似如下的Modify語(yǔ)句:
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表達(dá)式來(lái)解析單個(gè)屬性。例如,為了使用"Starter"替換投球手John Smoltz的role屬性的值,你可以編寫如下的語(yǔ)句:
SET @doc.modify('
replace value of (/Team/Players/Pitcher[
@name="John Smoltz"]/@role)[1]
with "Starter"
')
replace value語(yǔ)法也支持條件替換,這可以通過(guò)在replace value語(yǔ)句的with子句內(nèi)使用if…then…else語(yǔ)法實(shí)現(xiàn)。例如,如果John Smoltz是一個(gè)Closer的話,把他的role替換為Starter;但是如果他不是一個(gè)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"