Sql server 当条件匹配新插入的记录时,T-Sql合并语句更新
这是我拥有的XML:Sql server 当条件匹配新插入的记录时,T-Sql合并语句更新,sql-server,tsql,sqlxml,sql-merge,Sql Server,Tsql,Sqlxml,Sql Merge,这是我拥有的XML: <?xml version="1.0" encoding="UTF-8"?> <Data> <Record> <ServerId>1</ServerId> <CompanyId>1</CompanyId> <InstanceId>2</InstanceId> <TemplateId>23</Tem
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Record>
<ServerId>1</ServerId>
<CompanyId>1</CompanyId>
<InstanceId>2</InstanceId>
<TemplateId>23</TemplateId>
<ContactId>11052</ContactId>
<RecordId>11462</RecordId>
<TaskId>677</TaskId>
<EntryDate>2016-04-21 14:17:02:813</EntryDate>
<EntryKey>key_test_1</EntryKey>
<EntryValue>value_test_1</EntryValue>
</Record>
<Record>
<ServerId>1</ServerId>
<CompanyId>1</CompanyId>
<InstanceId>2</InstanceId>
<TemplateId>23</TemplateId>
<ContactId>11052</ContactId>
<RecordId>11462</RecordId>
<TaskId>677</TaskId>
<EntryDate>2016-04-21 14:17:02:873</EntryDate>
<EntryKey>key_test_2</EntryKey>
<EntryValue>value_test_2</EntryValue>
</Record>
<Record>
<ServerId>1</ServerId>
<CompanyId>1</CompanyId>
<InstanceId>2</InstanceId>
<TemplateId>23</TemplateId>
<ContactId>11052</ContactId>
<RecordId>11462</RecordId>
<TaskId>677</TaskId>
<EntryDate>2016-04-21 14:17:02:935</EntryDate>
<EntryKey>key_test_1</EntryKey>
<EntryValue>value_test_3</EntryValue>
</Record>
</Data>
当表中没有记录时,我所期望的是插入第一条xml记录,插入第二条xml记录,第三条xml记录将更新第一条符合条件的表记录。实际上,我得到了3次插入,而不是2次插入和1次更新
结果截图:
有没有办法在每次插入或更新后强制MERGE语句执行COMMIT或其他操作?我不想对xml记录进行分组或选择最大/最后一个记录
更新:
我使用了一个类似于第一个的合并操作。唯一的区别是,这一个包含值
when MATCHED then update set
rep.TaskId = dat.TaskId,
rep.EntryDate = dat.EntryDate,
rep.EntryValue = case len(isnull(rep.EntryValue, '')) when 0 then dat.EntryValue else rep.EntryValue + ';' + dat.EntryValue end
预期结果应该是:
key_test_1 | value_test_1;value_test_3
key_test_2 | value_test_2
你可以试试这个:
使用ROW\u NUMBER
查找XML中最新的记录,只需忽略旧的记录,它将被覆盖
WITH shreddedXML AS
(
select
entity.value('ServerId[1]', 'int') as ServerId,
entity.value('CompanyId[1]', 'int') as CompanyId,
entity.value('InstanceId[1]', 'int') as InstanceId,
entity.value('TemplateId[1]', 'int') as TemplateId,
entity.value('ContactId[1]', 'bigint') as ContactId,
entity.value('RecordId[1]', 'bigint') as RecordId,
entity.value('TaskId[1]', 'bigint') as TaskId,
entity.value('EntryDate[1]', 'datetime') as EntryDate,
entity.value('EntryKey[1]', 'varchar(max)') as EntryKey,
entity.value('EntryValue[1]', 'varchar(max)') as EntryValue
from @xmlInsertOrReplace.nodes('/Data/Record') as T(entity)
)
,SearchForMostActualRows AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY ServerId,CompanyId,InstanceId,TemplateId,ContactId,RecordId,EntryKey ORDER BY EntryDate DESC) AS Nr
,*
FROM shreddedXML
)
SELECT *
FROM SearchForMostActualRows
WHERE Nr=1
现在用这个…否执行
MERGE
。MERGE是一条语句。如果您想先进行插入,然后进行更新,则需要使用两个单独的语句。@Sean Lange是正确的。MERGE语句将现有表中的数据与解析的XML数据中的数据进行比较。“我不想对XML记录进行分组或选择最大/最后一个记录。”-为什么不?这似乎是一个解决方案,如果所有字段都将被第三条记录覆盖,为什么还要插入第一条记录呢。@GarethD:因为我还有一条merge语句执行相同的操作,但它将值与现有的值关联起来。所以,相同的xml数据,insert,inser,update(将第三个xml记录值转换为新插入的第一个表记录)。这可以同时从同一台机器内的多个应用程序中完成…顺便说一句,您是否知道(尝试这样做会返回错误)?在进行合并之前,您需要对源行进行分组/连接。问题是我不能忽略任何记录。我会用原因更新我的问题。@HABJAN我刚刚读了原因。只需将我的查询更改为SELECT*到#tentable
。在下一步中,您使用SELECT*FROM#tentable WHERE Nr=1
执行MERGE
,然后使用SELECT*FROM#tentable WHERE Nr>1
执行任何您想要的操作,即使这并不能解决我的问题,它也为我指明了正确的方向。谢谢
WITH shreddedXML AS
(
select
entity.value('ServerId[1]', 'int') as ServerId,
entity.value('CompanyId[1]', 'int') as CompanyId,
entity.value('InstanceId[1]', 'int') as InstanceId,
entity.value('TemplateId[1]', 'int') as TemplateId,
entity.value('ContactId[1]', 'bigint') as ContactId,
entity.value('RecordId[1]', 'bigint') as RecordId,
entity.value('TaskId[1]', 'bigint') as TaskId,
entity.value('EntryDate[1]', 'datetime') as EntryDate,
entity.value('EntryKey[1]', 'varchar(max)') as EntryKey,
entity.value('EntryValue[1]', 'varchar(max)') as EntryValue
from @xmlInsertOrReplace.nodes('/Data/Record') as T(entity)
)
,SearchForMostActualRows AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY ServerId,CompanyId,InstanceId,TemplateId,ContactId,RecordId,EntryKey ORDER BY EntryDate DESC) AS Nr
,*
FROM shreddedXML
)
SELECT *
FROM SearchForMostActualRows
WHERE Nr=1