我在SQL Server 2008的“表”中有一个名为“Details”的XML类型列。此列的值为:
<output xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Request>
<header>
<message-id>300_500</message-id>
<userid>eray</userid>
<timestamp>2012-01-01T12:00:0.000</timestamp>
<currentstatus>COMPLETED</currentstatus>
</header>
...
</Request>
</output>
我想要做的是使用update语句将Table的xml列(详细信息)中的timestamp值替换为Table2中的另一个时间戳值。这就是我想要的:
update t
set t.Details.modify('replace value of
(/output/Request/header/timestamp/text())[1] with
("'+t2.MessageTimestamp+'")')
from Table t
inner join Table2 t2 on t2.apptId = t1.apptId
然而,它无效并给我错误:
'modify'
附近的语法不正确
我尝试通过在线阅读很多文章来修复它一段时间,但是看不出这里有什么问题。任何帮助将不胜感激。
答案 0 :(得分:1)
我认为你正在寻找
DECLARE @mockupT1 TABLE(ID INT,apptId INT,Details XML);
INSERT INTO @mockupT1 VALUES
(1,1,N'<output xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Request>
<header>
<message-id>300_500</message-id>
<userid>eray</userid>
<timestamp>2012-01-01T12:00:0.000</timestamp>
<currentstatus>COMPLETED</currentstatus>
</header>
...
</Request>
</output>');
DECLARE @mockupT2 TABLE(apptId INT,MessageTimeStamp DATETIME);
INSERT INTO @mockupT2 VALUES(1,GETDATE());
update t1
set Details.modify('replace value of
(/output/Request/header/timestamp/text())[1] with sql:column("t2.MessageTimeStamp")')
from @mockupT1 AS t1
inner join @mockupT2 t2 on t2.apptId = t1.apptId;
SELECT * FROM @mockupT1;
在XQuery
范围内,只允许使用文字。但是T-SQL
已将sql:variable()
和sql:column()
添加到XQuery
。这允许使用声明的变量的值或列的值。
答案 1 :(得分:1)
问题是,当您尝试通过完整路径(如'tableAlias.XMLfield.modify')寻址到字段时,'XMLfield.modify'不起作用。导致相同的错误:'modify'附近的语法不正确。
这里有一个简短的示例来演示它(第二次更新失败,但是第一次成功)
if OBJECT_ID('tempdb..#a') is not null drop table #a
create table #a(a xml,b nvarchar(max))
insert into #a(a,b) values('<a/>','123')
update t set a.modify('insert (<b>{sql:column("b")}</b>) as last into (//a)[1]') from #a t
select * from #a
update t set t.a.modify('insert (<b>{sql:column("b")}</b>) as last into (//a)[1]') from #a t
答案 2 :(得分:0)
我将代码更改为下面的代码,现在工作正常。我找不到直接使用另一个表的值的方法,所以我将值保存到@timestamp变量并在替换为sql:variable("@timestamp")
时使用它。
declare @timestamp varchar(50)
set @timestamp = (
select cast(t2.MessageTimeStamp as varchar(50))
from Table t
inner join Table2 t2 on t2.apptId = t1.apptId
where t.Id = @Id
)
update t
set Details.modify('replace value of
(/output/Request/header/timestamp/text())[1] with
sql:variable("@timestamp")')
from Table t
where Id = @Id