如何使用T-SQL内置函数中的值更新XML列?

时间:2011-09-22 12:18:47

标签: sql-server xml tsql sql-server-2008-r2 xml-dml

我有一个MS SQL 2008 R2标准数据库。我有一个包含varchar(250)数据的列和一个包含xml的列。

CREATE TABLE [dbo].[art](
[id] [int] IDENTITY(1,1) NOT NULL,
[idstr] [varchar](250) NULL,
[rest] [xml] NOT NULL,
    CONSTRAINT [PK_art] PRIMARY KEY CLUSTERED ([id] ASC)
)

问题是我想在大约140条记录中将字符串函数的结果插入到xml中。我尝试将xml.modify用于动态生成的文本。

UPDATE [pwi_new].[dbo].[art]
SET rest.modify('insert <e><k>link</k><v>' 
      + my_string_function(idstr) + '</v></e> into (/root)[1]')
  WHERE parent = 160
  AND idstr LIKE '%&%'
GO

但是,我有这个错误:

The argument 1 of the XML data type method "modify" must be a string literal.

有什么想法吗?我想避免使用时态字段,外部语言和从生成的字符串执行TSQL? (我听说过sql:variablesql:column,但这是tsql函数的结果。)

2 个答案:

答案 0 :(得分:7)

不确定你想在这做什么。你提到了一个TSQL函数,如果那是替换&amp;到&amp;没有必要。它由SQL Server负责。

使用表变量@art的测试:

declare @art table(parent int, idstr varchar(250), rest xml)

insert into @art values
(160, '123&456', '<root></root>')

update @art 
set rest.modify('insert (<e><k>link</k><v>{sql:column("idstr")}</v></e>) into (/root)[1]') 
where parent = 160 and
      idstr like '%&%'

select rest
from @art 

结果:

<root>
  <e>
    <k>link</k>
    <v>123&amp;456</v>
  </e>
</root>

<强>更新

对于不那么微不足道的情况,您可以使用交叉申请将所需的值输入到列中。

declare @art table(parent int, idstr varchar(250), rest xml)

insert into @art values
(160, '123&456', '<root></root>')

update a
set rest.modify('insert (<e><k>link</k><v>{sql:column("T.X")}</v></e>) into (/root)[1]') 
from @art as a
  cross apply (select reverse(replace(idstr, '2', '8')+'NotSoTrivial')) as T(X)
where parent = 160 and
      idstr like '%&%'

select rest
from @art 

结果:

<root>
  <e>
    <k>link</k>
    <v>laivirToStoN654&amp;381</v>
  </e>
</root>

答案 1 :(得分:1)

假设你的桌子有一把钥匙:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += CHAR(13) + CHAR(10) + 'UPDATE [pwi_new].[dbo].[art] '
    + ' SET rest.modify(''insert <e><k>link</k><v>' 
    + REPLACE(idstr,'&','&amp;') 
    + '</v></e> into (/root)[1]'') WHERE key_column = ' 
    + CONVERT(VARCHAR(12), key_column) + ';'
FROM [pwi_new].[dbo].[art]
  WHERE parent = 160
  AND idstr LIKE '%&%';

PRINT @sql;
--EXEC sp_executesql @sql;