2010-10-15 31 views
0

我在xml數據類型的SQL Server表中存儲xml文件。現在我想獲取一些片段(使用xquery),然後用修改後的片段更新片段(使用xquery)。我需要一些建議。使用Xquery操縱sql服務器中的xml列

我有刪除節點的代碼,它如下所示,但刪除時,我需要將修改的節點插入到相同的位置。如何才能做到這一點?

--SET @doc.modify('delete (/DATA/SDACTS)') 

這工作,如果我想刪除一個大約在同一位置

下一步將修改後的節點的節點,但我想刪除其值將作爲查詢字符串,從而傳遞我必須建立節點字符串

像下面

DECLARE @x XML 

SET @x = ' 
<DATA> 
    <SDACTS> 
    <SDACT TYPE="Economy" COLOUR="0xff0000" /> 
    <SDACT TYPE="Environment" COLOUR="0x00ff00" /> 
    <SDACT TYPE="People" COLOUR="0x0000ff" /> 
    <SDACT TYPE="Society" COLOUR="0xff00ff" /> 
    </SDACTS> 
<LOCATIONS> 
    <CONTINENT TITLE="South America"> 
     <COUNTRY TITLE="Chile"> 
     <HEADOFFICE>Santiago</HEADOFFICE> 
     <ADDRESS> 
      &lt;p&gt;Pedro de Valdivia 291&lt;/p&gt;&lt;p&gt;Providencia&lt;/p&gt;&lt;p&gt;Santiago&lt;/p&gt; 
     </ADDRESS> 
     <LATITUDE>-33.426127</LATITUDE> 
     <LONGITUDE>-70.611469</LONGITUDE> 
     <BUSINESSUNITS>Copper</BUSINESSUNITS>   
     <EMPLOYEES /> 
     <NUMBEROFBUSINESS>1</NUMBEROFBUSINESS> 
     </COUNTRY> 
     <COUNTRY TITLE="Brazil"> 
     <HEADOFFICE>Brazil</HEADOFFICE> 
     <ADDRESS> 
      &lt;p&gt;Pedro de Valdivia 291&lt;/p&gt;&lt;p&gt;Providencia&lt;/p&gt;&lt;p&gt;Santiago&lt;/p&gt; 
     </ADDRESS> 
     <LATITUDE>-38.426127</LATITUDE> 
     <LONGITUDE>-60.611469</LONGITUDE> 
     <BUSINESSUNITS>Zinc</BUSINESSUNITS>   
     <EMPLOYEES /> 
     <NUMBEROFBUSINESS>2</NUMBEROFBUSINESS> 
     </COUNTRY> 
    </CONTINENT> 
</LOCATIONS> 
</DATA> 

我已經刪除了國家巴西,其位於大陸南美所以我必須把這些作爲參數必須與其他國家和大陸一樣動態。

declare @country varchar(50) 
declare @continent varchar(50) 
set @country = 'Brazil' 
set @continent = 'South America' 

declare @final varchar(100) 
set @final = '//CONTINENT[@TITLE="' + @continent + '"]/COUNTRY[@TITLE="' + @country + '"]' 
select @final 
--SELECT @doc.query('sql:variable("@final")') 'XmlDesc' This works for select statement but not for delete 
SET @doc.modify('delete (sql:variable("@final"))') This does not work and gives error. 
SELECT @doc 

我的要求:

基本上我做的.NET和jQuery樹中的XML編輯工具加載大型XML文件時,所以我存儲表中的巨大的XML文件並調用段掛起(子節點),然後將這些段加載到jquery樹中,然後用戶修改這些節點。我將修改過的段引導到數據庫,然後想要使用修改過的段進行更新。

回答

1

編輯2:它看起來像SLQ-Server是不是一個完全投訴的XQuery處理器...

所以,更「靜」的XQuery(至極是罰款是架構是衆所周知的) :

declare variable $continent external; 
declare variable $country external; 
declare variable $xml as item() external; 
element DATA { 
    /DATA/@*, 
    /DATA/*[not(self::LOCATIONS)], 
    element LOCATIONS { 
     /DATA/LOCATIONS/@*, 
     for $cont in /DATA/LOCATIONS/CONTINENT 
     return element CONTINENT { 
       $cont/@*, 
       for $count in $cont/COUNTRY 
       return if ($cont/@TITLE=$continent and 
          $count/@TITLE=$country) 
         then $xml 
         else $count 
      } 
    } 
} 

有了這個參數(SQL-Server,則也可以使用sql:variable()擴展功能):

continent="'South America'" 
country="'Brazil'" 
xml="<COUNTRY TITLE='Brazil'><UPDATE/></COUNTRY>" 

輸出:

<DATA> 
    <SDACTS> 
     <SDACT TYPE="Economy" COLOUR="0xff0000"/> 
     <SDACT TYPE="Environment" COLOUR="0x00ff00"/> 
     <SDACT TYPE="People" COLOUR="0x0000ff"/> 
     <SDACT TYPE="Society" COLOUR="0xff00ff"/> 
    </SDACTS> 
    <LOCATIONS> 
     <CONTINENT TITLE="South America"> 
      <COUNTRY TITLE="Chile"> 
       <HEADOFFICE>Santiago</HEADOFFICE> 
       <ADDRESS> 
      &lt;p&gt;Pedro de Valdivia 291&lt;/p&gt;&lt;p&gt;Providencia&lt;/p&gt;&lt;p&gt;Santiago&lt;/p&gt; 
       </ADDRESS> 
       <LATITUDE>-33.426127</LATITUDE> 
       <LONGITUDE>-70.611469</LONGITUDE> 
       <BUSINESSUNITS>Copper</BUSINESSUNITS> 
       <EMPLOYEES/> 
       <NUMBEROFBUSINESS>1</NUMBEROFBUSINESS> 
      </COUNTRY> 
      <COUNTRY TITLE="Brazil"> 
       <UPDATE/> 
      </COUNTRY> 
     </CONTINENT> 
    </LOCATIONS> 
</DATA> 

編輯3:我認爲,在評論你的查詢正確的語法是:

declare @continent varchar(100) 
declare @country varchar(100) 
declare @xml xml 
declare @count int 
declare @doc xml 
set @continent='South America' 
set @country='Brazil' 
set @xml='<COUNTRY TITLE="Brazil"><UPDATE/></COUNTRY>' 
set @count = 1 
select @doc = xmldesc from varunxmlanglo where idlanguage =1 and xmltype ='D' 
select @doc.query(' 
element DATA { 
    /DATA/@*, 
    /DATA/*[not(self::LOCATIONS)], 
    element LOCATIONS { 
     /DATA/LOCATIONS/@*, 
     for $continent in /DATA/LOCATIONS/CONTINENT 
     return element CONTINENT { 
       $continent/@*, 
       for $country in $continent/COUNTRY 
       return if ($continent/@TITLE=sql:variable("@continent") and              $country/@TITLE=sql:variable("@country")) 
         then sql:variable("@xml") 
         else $country 
      } 
    } 
} 
') 

注意:在XQuery中的變量引用有$前綴。

+0

@Alejandro:很好的答案,+1。 – 2010-10-15 20:17:22

+0

@Dimitre:謝謝!我開始喜歡回答有關XQuery的問題。 – 2010-10-15 20:23:23

+0

嗨亞歷杭德羅...謝謝你的回覆。我對xquery有點新,而我所做的就是將ur代碼粘貼到sql查詢窗口,發現它不起作用。你能讓我知道我到底需要放置這些代碼嗎? – Varun 2010-10-19 11:24:22