4

如何在不使用游标的情况下将一大堆行插入 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>
4

3 回答 3

2

这不是更简单吗?

set ErrorXML=(SELECT * from #MyTable FOR XML AUTO)
于 2010-06-27T07:59:42.707 回答
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 在“魔术”选择之后:

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

更新后的@errors:

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

是你要找的吗??:-)


(旧答案 - 不是 OP 正在寻找的......)

您需要查看.nodes()SQL XQuery 中的函数 - 这将根据 XPath 表达式将 XML 变量分解为 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)

更新:好的,所以你想做相反的事情 - 将关系数据转换为 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 变量中。

马克

于 2009-11-20T12:50:25.970 回答
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>
于 2010-01-06T15:20:13.617 回答