Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 当条件匹配新插入的记录时,T-Sql合并语句更新_Sql Server_Tsql_Sqlxml_Sql Merge - Fatal编程技术网

Sql server 当条件匹配新插入的记录时,T-Sql合并语句更新

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:

<?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