2009-11-20 3 views
4

Как я могу вставить целую кучу строк в переменную XML без использования курсора? Я знаю, что могу сделатьSQL-сервер вставляет данные из таблицы в переменную 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

На основании ответа MARC, вот это решение, которое работает для 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

последнее обновление:

ОК, теперь, когда речь идет гораздо яснее, он решение - надеюсь!

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 после "магии" SELECT:

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

@errors после UPDATE:

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

THAT Что вы ищете? :-)


(старые ответы - не то, что ОП искал .....)

Вы должны смотреть на .nodes() функции в SQL XQuery - это будет разбивать XML переменную в список узлов XML, основанную на выражении XPath (которое ссылается на какой-то пункт в вашем XML, где вы, вероятно, будете перечислять узлы той же структуры) и дает им «виртуальное» имя таблицы и столбца.

Основываясь на этом элементе «Таблица. Столбец», вы можете выбрать отдельные значения из этого узла 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

+0

Я знаю синтаксис FOR XML, но можете ли вы рассказать мне, как использовать его для добавления к существующей переменной, а не полностью заменить значение. – erikkallen

+0

Ah ok - это непонятно из вашего исходного вопроса - ответ снова обновлен –

1

Разве это не проще?

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

Это проще, но вместо этого будет заменено содержимое переменной, а не добавлено к ней. – erikkallen

 Смежные вопросы

  • Нет связанных вопросов^_^