2011-06-16 51 views
1

有沒有辦法在SQL中將新子樹編寫到XML節點中,專門用於動態查詢?我知道可以使用insertdelete陳述的組合,但我正在尋找一些以相當隱含的方式工作的東西。 IE,我不想爲每個需要的特定案例編寫不同的查詢。因此,例如,說我有這樣的XML層次:在SQL中將新子樹編寫到XML節點

<root> 
    ... 
    <node> 
     <node1> 
      ... 
     </node1> 
     <node2> 
      ... 
     </node2> 
     ... 
    </node> 
    ... 
</root> 

如果我想更換單個節點的值,我有這個疑問:

DECLARE @newVal varchar(max) 
DECLARE @XPath varchar(max) 
SELECT @newVal = 'newValue' 
SELECT @XPath = 'root/node/node1/text()' 

DECLARE @query varchar(max) 

SET @query = ' 
    UPDATE [dbo].[Users] 
    SET  [NewSettingsXml].modify('' 
     replace value of (' + @XPath + ')[1] 
     with "' + @newVal + '"'')' 
exec(@query) 

我希望,我也只是能夠執行諸如@newVal = '<newNode>foo</newNode>'之類的操作,其中新的XML將來自序列化的C#對象,但毫不奇怪,它將值編碼爲文本,並將其設置爲&lt;newNode&gt;foo&lt;/newNode&gt;。有沒有辦法以類似的方式做到這一點?

回答

0

嘗試使用FOR XML構造。這可能會給你想要的結果。

+0

除非我失去了一些東西,'因爲XML'是專門針對SELECT語句。由於我在做SET,所以我認爲這不適用於此。不過,如果我錯了,請糾正我。 :) – Chris 2011-06-16 20:29:30

1

我不認爲有可能用節點替換一個值。

這將字符串作爲一種價值,當然編碼的<>

replace value of (root/node/node1/text())[1] with "<newNode>foo</newNode>" 

你可能會不得不做這樣的事情

replace value of (root/node/node1/text())[1] with <newNode>foo</newNode> 

但是,給出了錯誤:

'替換值 '的'with'子句不能包含構造的XML

如果使用XML變量來代替:

DECLARE @newVal xml 
SELECT @newVal = '<newNode>foo</newNode>' 

UPDATE [dbo].[Users] 
SET  [SettingsXml].modify(' 
    replace value of (root/node/node1/text())[1] 
    with sql:variable("@newVal")') 

你得到

XML實例只支持爲 使用 SQL插入的直接源的錯誤:列/ SQL:變量。

所以我想你是堅持使用插入當你想插入節點。

3

你可以試試你的@newVal轉換爲一個nvarchar(最大),然後做你的mofify如下:

DECLARE @newVal xml 
SELECT @newVal = '<newNode>foo</newNode>' 

DECLARE @strNewVal nvarchar(max) 
SET @strNewVal = (Select (CONVERT(nvarchar(max), @newVal))) 

UPDATE [dbo].[Users] 
SET  [SettingsXml].modify(' 
    replace value of (root/node/node1/text())[1] 
    with sql:variable("@strNewVal")')