2009-11-20 211 views
4

如何在不使用遊標的情況下將大量行插入到XML變量中? 我知道我可以做SQL Server將表中的數據插入到XML變量中

SET @errors.modify('insert <error>{ sql:variable("@text") }</error> as last into /errors[1]') 

插入變量的值,但我想基本上做

SET @errors.modify(SELECT 'insert <error>{ sql:column("text") }</error>' FROM table) 

其中,當然,是不合法的語法。

編輯:顯然我的問題不清楚。我想是能夠做到這樣的:

CREATE TABLE my_table(text nvarchar(50)) 
INSERT INTO my_table VALUES('Message 2') 
INSERT INTO my_table VALUES('Message 3') 

DECLARE @errors xml 
SET @errors = '<errors><error>Message 1</error></errors>' 

SET @errors.modify('INSERT EVERYTHING FROM my_table MAGIC STATEMENT') 

並運行此代碼後@errors應該包含

<errors> 
    <error>Message 1</error> 
    <error>Message 2</error> 
    <error>Message 3</error> 
</errors> 

回答

0

基於馬克的答案,這裏是一個爲SQL Server 2005的有效的解決方案:

CREATE TABLE #my_table(text nvarchar(50)) 
INSERT INTO #my_table VALUES('Message 2') 
INSERT INTO #my_table VALUES('Message 3') 

DECLARE @errors xml 
SET @errors = '<errors><error>Message 1</error></errors>' 

SELECT @errors = CAST(@errors AS nvarchar(max)) + '<new>' + (SELECT text AS 'error' FROM #my_table FOR XML PATH(''), ELEMENTS) + '</new>' 

SET @errors = CAST(@errors AS nvarchar(max)) + '<new>' + @newErrors + '</new>' 
SET @errors.modify('insert (/new/*) as last into (/errors)[1]') 
SET @errors.modify('delete (/new)') 

SELECT @errors 

DROP TABLE #my_table 

將返回

<errors> 
    <error>Message 1</error> 
    <error>Message 2</error> 
    <error>Message 3</error> 
</errors> 
1

最後更新:

OK,現在的問題是,更清楚,他是解決方案 - 希望!

DECLARE @errors xml 
SET @errors = '<errors><error>Message 1</error></errors>' 

DECLARE @newErrors XML 

SELECT @newErrors = (SELECT text AS 'error' 
FROM dbo.my_table 
FOR XML PATH(''), ELEMENTS) 

SELECT @errors, @newErrors 

SET @errors.modify('insert sql:variable("@newErrors") as last into (/errors)[1]') 

SELECT @errors 

這給了我一開始

@errors後

<errors><error>Message 1</error></errors> 

@newError 「魔術師」 選擇:

<error>Message 2</error><error>Message 3</error> 

@errors的更新後:

<errors> 
    <error>Message 1</error> 
    <error>Message 2</error> 
    <error>Message 3</error> 
</errors> 

那個你在找什麼? :-)


(舊的答案 - 不是什麼OP是尋找.....)

你需要看看SQL的XQuery的.nodes()功能 - 這將打破一個XML 根據XPath表達式(引用XML中的某個點,您可能擁有相同結構的節點的枚舉),將其變爲XML節點列表,併爲其提供「虛擬」表和列名稱。

基於該「Table.Column」元素,您可以從該XML節點中選擇單個值 - 屬性或子元素 - 並將其返回爲「原子」值。作爲INT,VARCHAR(x),無論你需要什麼。這些數值可以被插入到表:

INSERT dbo.YourTable(col1, col2, col3, ..., colN) 
    SELECT 
    Error.Column.value('@attr1[1]', 'varchar(20)'), 
    Error.Column.value('subitem[1]', 'int'), 
    ..... 
    Error.Column.value('subitemN[1]', 'DateTime') 
    FROM 
    @xmldata.nodes('/error') AS Error(Column) 

UPDATE:好了,你想要做的恰恰相反 - 把關係型數據轉換成XML - 這甚至:-)

DECLARE @NewXmlContent XML 

SELECT @NewXmlContent = 
     (SELECT 
      col1 as '@ID', 
      col2 as 'SomeElement', 
      ..... 
      colN as 'LastElement' 
     FROM 
      dbo.YourTable 
     WHERE 
      .... 
     FOR XML PATH('element'), ROOT('root') 
     ) 

UPDATE YourOtherTable 
SET XmlField.modify('insert sql:variable("@NewXmlContent") 
        as last into (/XPath)[1]') 
WHERE (some condition) 

這更容易會給你@NewXmlContent是這樣的:

<root> 
    <element ID="(value of col1)"> 
     <SomeElement>(value of col2)</SomeElement> 
     ..... 
     <LastElement>(value of colN)</LastElement> 
    </element> 
</root> 

和UPDATE語句與.modify()通話將實際插入次在內容中添加到數據庫中的現有XML字段中。這是將XML內容轉換爲現有XML列的唯一方法 - 無法直接引用正在插入的XML片段中的另一個XML列......

新的「FOR XML PATH」語法非常強大,靈活,並允許你做任何事情。

當然,您可以輕鬆地將其存儲到XML變量中。

馬克

+0

是的,但我想做相反的事情:用表中的數據填充xml變量。 – erikkallen 2009-11-21 13:35:29

+0

我知道FOR XML語法,但你能告訴我如何使用它來追加到現有的變量,而不是完全替換值。 – erikkallen 2009-11-21 15:03:26

+0

好的 - 從你的原始問題中不清楚 - 答案再次更新 – 2009-11-21 15:37:32

1

這難道不更簡單?

set ErrorXML=(SELECT * from #MyTable FOR XML AUTO) 
+0

這很簡單,但它會替換變量的內容而不是附加到它。 – erikkallen 2010-06-27 10:02:45

相關問題