【问题标题】:How to update an XML column with value from T-SQL built-in function?如何使用 T-SQL 内置函数的值更新 XML 列?
【发布时间】:2011-09-22 12:18:46
【问题描述】:

我有一个 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)
)

问题是我想将字符串函数的结果插入到 xml 中,大约有 140 条记录。我尝试将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函数的结果。)

【问题讨论】:

  • 你能展示一些类似于你正在尝试做的事情吗?现在它非常抽象。您还可以指定 SQL Server 的版本,以及该列是否真的是不推荐使用的类型 TEXT 或者您的意思是像 VARCHAR/NVARCHAR 这样的字符串列...
  • 我已经编辑了我的问题。现在应该更清楚了。

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


【解决方案1】:

不确定你想在这里做什么。您提到了一个 TSQL 函数,如果那是替换 & 到 & 则没有必要。它由 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>

【讨论】:

  • 但是如果需要,可以替换为:UPDATE A SET rest.modify('insert link{sql:column(" idstr_new")} 到 (/root)[1]') FROM (SELECT B.rest,REPLACE(B.idstr,'&','&') idstr_new FROM @Art B WHERE idstr LIKE '%&%' --AND parent = 160 ) A'
  • 好吧。它看起来有效。毕竟我的问题是微不足道的。不过,我想要一个适用于更复杂 TSQL 表达式的解决方案。
  • @Michas - 用更“复杂”的表达方式更新了答案。
【解决方案2】:

假设你的表有一个键:

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;

【讨论】:

  • 它看起来有效。但是,我想避免从字符串执行 TSQL。
猜你喜欢
  • 1970-01-01
  • 2017-02-12
  • 2011-07-17
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2012-03-03
相关资源
最近更新 更多