[英]How to update xml column node value with another column new value at same update query?
I want to change the value of 2 columns in one table.我想更改一张表中 2 列的值。 One column is varchar and the other is XML.
一列是 varchar,另一列是 XML。 First of all, I want to replace the value of the RECIPIENT column with the new value and replace the node value named as RecipientNo in the XML column with the new value of RecipientNo.
首先,我想将 RECIPIENT 列的值替换为新值,并将 XML 列中名为 RecipientNo 的节点值替换为 RecipientNo 的新值。 How can I do these two operations in the same update function?
如何在同一个更新函数中执行这两个操作? The query below works.
下面的查询有效。 Secondly, DATARECORD table includes too many records.
其次,DATARECORD 表包含的记录太多。 Does modify function take too much time to update the records?
修改功能是否需要太多时间来更新记录? If so, how can I increase the performance of modify function or can you suggest another alternative solution?
如果是这样,我如何提高修改功能的性能,或者您能否提出另一种替代解决方案? By the way, I cannot add index to DATARECORD table.
顺便说一下,我无法向 DATARECORD 表添加索引。 Thanks.
谢谢。
Here is the sample row;这是示例行;
ID RECIPIENT RECORDDETAILS
1 1 <?xml version="1.0"?>
<MetaTag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/XMLSchema">
<Code>123</Code>
<RecipientNo>123</RecipientNo>
<Name>xyz</Name>
</MetaTag>'
CREATE TABLE #TEMPTABLE(
ID bigint,
RECIPIENT nvarchar(max),
RECORDDETAILS xml
)
INSERT INTO #TEMPTABLE
SELECT ID,RECIPIENT,RECORDDETAILS
FROM DATARECORD WITH (NOLOCK)
WHERE cast(RECORDDETAILS as varchar(max)) LIKE '%<Code>123</Code>%' and cast(RECORDDETAILS as varchar(max)) LIKE '%MetaTag%'
UPDATE #TEMPTABLE SET RECIPIENT = CONCAT('["queryType|1","recipientNoIDENTIFICATION|',RECIPIENT,']')
UPDATE #TEMPTABLE SET RECORDDETAILS.modify('replace value of (MetaTag/RecipientNo/text())[1] with sql:column("RECIPIENT")')
UPDATE d
SET d.RECORDDETAILS =Concat('<?xml version="1.0"?>', CAST(t.RECORDDETAILS AS VARCHAR(max))),
d.RECIPIENT = t.RECIPIENT
FROM dbo.DATARECORD as d
Join #TEMPTABLE as t
ON t.ID = d.ID
It's certainly possible to update an SQL column and an XML node in the same update statement, eg:当然可以在同一个更新语句中更新 SQL 列和 XML 节点,例如:
create table DataRecord (
ID bigint not null primary key,
Recipient nvarchar(max) not null,
RecordDetails xml not null
);
insert DataRecord values
(1, N'1', N'<?xml version="1.0"?>
<MetaTag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/XMLSchema">
<Code>123</Code>
<RecipientNo>123</RecipientNo>
<Name>xyz</Name>
</MetaTag>');
create table #TempTable (
ID bigint not null primary key,
Recipient nvarchar(max) not null,
RecordDetails xml not null
);
insert #TempTable
select ID, Recipient, RecordDetails
from DataRecord with (nolock)
where cast(RecordDetails as varchar(max)) like '%<Code>123</Code>%' and cast(RecordDetails as varchar(max)) like '%MetaTag%'
-- Change an SQL value and an XML node in the one update statement...
update tt set
Recipient = NewRecipient,
RecordDetails.modify('replace value of (/MetaTag/RecipientNo/text())[1] with sql:column("NewRecipient")')
from #TempTable tt
outer apply (
select NewRecipient = concat('["queryType|1","recipientNoIDENTIFICATION|', Recipient, '"]')
) Calc
select * from #TempTable
Which yields:其中产生:
ID Recipient RecordDetails
1 ["queryType|1","recipientNoIDENTIFICATION|1"] <MetaTag
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/XMLSchema">
<Code>123</Code>
<RecipientNo>["queryType|1","recipientNoIDENTIFICATION|1"]</RecipientNo>
<Name>xyz</Name>
</MetaTag>
There are a couple of things contributing to your performance problem:有几件事会导致您的性能问题:
like
matches on the XML (converted to varchar) will be causing TABLE SCAN operations, converting and testing every row in your table.like
匹配(转换为 varchar)将导致 TABLE SCAN 操作,转换和测试表中的每一行。 Some things to consider:需要考虑的一些事项:
RecordDetails
column and use something like WHERE RecordDetails.exists('/MetaTag/Code[.="123"])
to short list the rows to be updated.RecordDetails
列并使用类似WHERE RecordDetails.exists('/MetaTag/Code[.="123"])
来列出要更新的行。RecordDetails
, persist the value of /MetaTag/Code/text()
in a table column (eg: MetaTagCode
), and use something like WHERE MetaTagCode='123'
in your query.RecordDetails
,将/MetaTag/Code/text()
的值保留在表列中(例如: MetaTagCode
),并在您的查询中使用类似WHERE MetaTagCode='123'
的内容。 Adding an index to that column will allow SQL to do a much cheaper INDEX SCAN when searching for the desired value instead of a TABLE SCAN. Since you say you cannot add indexes you're basically going to have to tolerate TABLE SCANs and just wait it out.既然你说你不能添加索引,你基本上将不得不容忍 TABLE SCANs 并等待它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.