SQLServer2005的XML數(shù)據(jù)類型之基礎篇[2]

字號:

exist方法
    這個exist方法用于決定是否一個查詢能夠產(chǎn)生任何結果。這個exist方法的語法形式如下:
    exist(XQuery)
    當你使用這個exist方法時,它計算這個XQuery查詢,并且如果該查詢產(chǎn)生任何結果的話返回值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語句和你想要它返回的數(shù)據(jù)類型,并且你可以返回除了XML數(shù)據(jù)類型外的任何數(shù)據(jù)類型。例如,如果你想得到每一個小組中的第一個投球手的名字,你可以編寫如下形式的查詢語句:
    --進行一次查詢以得到單個值
    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數(shù)據(jù)類型-它包含查詢的結果;而value方法返回一個帶有查詢結果的非XML數(shù)據(jù)類型。另外,value方法僅能返回單個值(或標量值)。如果你試圖創(chuàng)建一個使用value方法返回多于一個值的XQuery表達式,你將得到一個錯誤。
    modify方法
    盡管XQuery標準并沒有提供一種更新XML的機制,但是SQL Server 2005提供了一種方法用于即時地修改一個XML對象的一部分。這意味著,你不必僅為了修改而檢索一個完整的XML文檔。為了即時修改一個文檔,你可以采用一種結合方式-Modify方法和SQL Server 2005的新的XML數(shù)據(jù)修改語言(XML DML)。
    Modify方法的語法是:
    modify(<XMLDML>)
    該方法僅使用一個參數(shù):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]
    ')
    另外,你還可以通過調(diào)用一個UPDATE語句并修改一個XML列來實現(xiàn)同樣目的:
    --修改一個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子句指令數(shù)據(jù)庫把InsertExpression作為LocationExpression的一個兄弟(sibling)插入。before或after則指定是在LocationExpression的前面還是后面插入它:
    SET @doc.modify('
    insert <Pitcher role="Starter"
    name="Jaret Wright"/>
    before (/Team/Players/Pitcher)[1]
    ')
    這個into子句把InsertExpression作為LocationExpression的一個孩子結點插入??蛇x子句as first和as last用于指定在該孩子結點中插入的位置:
    --在小組內(nèi)進行插入
    SET @doc.modify('
    insert <Pitcher role="Starter"
    name="Jaret Wright"/>
    into (/Team/Players)[1]
    ')
    --在小組內(nèi)進行插入,指定它應該
    --作為最后一個元素插入
    SET @doc.modify('
    insert <Pitcher role="Starter"
    name="Jaret Wright"/>
    as last into (/Team/Players)[1]
    ')
    delete語句的語法很直接:
    delete LocationExpression
    這個LocationExpression指定要從XML數(shù)據(jù)中刪除什么內(nèi)容。例如,要刪除所有的投球手:
    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數(shù)據(jù)的修改。這個replace value語句的語法如下:
    replace value of
    OriginalExpression
    with
    ReplacementValue | if
    這個replace value語句用來修改在XML中的值??赡艿闹凳且粋€標簽的內(nèi)容或一個屬性的值。這個OriginalExpression必須解析為單個結點或屬性。這個ReplacementValue通常是一個要代替的值。代替一個結點的內(nèi)容要求使用text()函數(shù)的XQuery表達式來指定你想代替一個結點的文本。例如,為了替換一個投球手的內(nèi)部文本(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子句內(nèi)使用if…then…else語法實現(xiàn)。例如,如果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"
    )
    ')