【问题标题】:Merge script between 2 tables and not working在 2 个表之间合并脚本并且不起作用
【发布时间】:2016-12-28 12:19:46
【问题描述】:

我有一个代码,我仍然想知道为什么它不应该工作,我想合并这两个表并查看下面的代码和生成错误的表。请这些表刚刚被提取,并且比下面粘贴的行多。只是样品

MERGE INTO [server1].[DATABASE].[dbo].[MD_ToolsMaintDate] WITH (HOLDLOCK) AS TARGET 
USING (SELECT * from  [server2].[DATABASE].[dbo].[MD_ToolsMaintDate])    AS SOURCE 

   ON TARGET.MaintDate = SOURCE.MaintDate 
     AND  Target.MDToolID  = Source.MDToolID
   AND Target.SerialID = Source.SerialID

  WHEN MATCHED AND
    (

      OR Target.ComponentID   <> Source.ComponentID
      OR Target.Notes        <> Source.Notes 
    )        

 THEN 
 UPDATE SET 

 , TARGET.ComponentID = SOURCE.ComponentID  
 , TARGET.Notes = SOURCE.Notes 

WHEN NOT MATCHED THEN
    INSERT  ( SerialID,MDToolID,MaintDate,ComponentID,Notes)
    VALUES ( SOURCE.SerialID, SOURCE.MDToolID, SOURCE.MaintDate,SOURCE.ComponentID, SOURCE.Notes);

         SELECT * FROM [server1].[DATABASE].[dbo].[MD_ToolsMaintDate]

错误:MERGE 语句多次尝试更新或删除同一行。当目标行匹配多个源行时会发生这种情况。 MERGE 语句不能多次 UPDATE/DELETE 目标表的同一行。优化 ON 子句以确保目标行最多匹配一个源行,或使用 GROUP BY 子句对源行进行分组。

   -----server 1 table :

  MaintenanceID SerialID    MDToolID    MaintDate   ComponentID     Notes

218       8          4     2016-05-26 01:00:00.0000000      NULL     pivot 
219      9           4     2016-08-06 21:15:00.0000000      NULL             
220      130         4     2016-08-09 00:00:00.0000000      NULL                  NULL        

    -----server 2 table :

MaintenanceID SerialID  MDToolID    MaintDate     ComponentID          Notes
45            130        4  2016-02-09 00:00:00.0000000  NULL          CHECK ME
49            131        5  2016-02-09 00:00:00.0000000  NULL          CHECK ME

我们将不胜感激任何更正和方法。两个表上的维护 ID 永远不会保持相同,因为这两个表甚至位于不同的位置

【问题讨论】:

    标签: sql sql-server tsql merge


    【解决方案1】:

    您的代码看起来不太好。通常,您正在更新其他列,而不是用于连接(声明源和目标对象)。在这种情况下,您正在更新与合并连接中使用的相同的列。其他问题:合并连接条件说,值必须相同。然后,当值相同时(“匹配时..”),您还说合并连接中使用的值(必须匹配)必须不匹配。剩下的部分也不清楚。 请在线阅读书籍以明确必须如何实施合并: https://msdn.microsoft.com/en-us/library/bb510625.aspx


    MERGE INTO [server1].[DATABASE].[dbo].[MD_ToolsMaintDate] WITH (HOLDLOCK) AS TARGET 
    USING
    (
        SELECT 
             [SerialID]
            ,[MDToolID]
            ,[MaintDate]
            ,[ComponentID]
            ,[Notes]
        FROM  
            [server2].[DATABASE].[dbo].[MD_ToolsMaintDate]
    )    AS SOURCE 
    (
             [SerialID]
            ,[MDToolID]
            ,[MaintDate]
            ,[ComponentID]
            ,[Notes]
    )
    ON 
            TARGET.[MaintDate]  = SOURCE.[MaintDate]
        AND TARGET.[MDToolID]   = SOURCE.[MDToolID]
        AND TARGET.[SerialID]   = SOURCE.[SerialID]
    WHEN MATCHED AND
    (
            TARGET.[ComponentID]    <> SOURCE.[ComponentID]
        OR  TARGET.[Notes]          <> SOURCE.[Notes] 
    )
    THEN UPDATE 
        SET 
             TARGET.[ComponentID]   = SOURCE.[ComponentID]
            ,TARGET.[Notes]         = SOURCE.[Notes] 
    WHEN NOT MATCHED THEN INSERT  
        ( 
             [SerialID]
            ,[MDToolID]
            ,[MaintDate]
            ,[ComponentID]
            ,[Notes]
        )
        VALUES
        (
             SOURCE.[SerialID]
            ,SOURCE.[MDToolID]
            ,SOURCE.[MaintDate]
            ,SOURCE.[ComponentID]
            ,SOURCE.[Notes]
        );
    

    【讨论】:

    • 我已经编辑过了。它只是重复的列名。
    • 我用新的查询更新了我的第一篇文章。可以试试吗?
    • 嗨 Juozas,我已经测试了脚本,它说 0 行受到影响。谢谢
    • 是你在server1、server2上的数据计划的结果吗?
    • 是的,UNION 消除了记录集 A 和 B 之间的所有重复项。其他方法是使用 UNION ALL,但按所有列分组最终结果:gist.github.com/runnerlt/142510f2ffcaa7019ccb88f26d9a126d
    【解决方案2】:

    示例查询:-

    <----- **USING MERGE** ----->
    
    merge into [#server1] as t1
    using(select * from [#server2]) as t2
    on t1.[maintenanceid]=t2.[maintenanceid]
    when matched then
    update set 
    t1.[serialid]=[t2.serialid],
    t1.[mdtoolid]=[t2.mdtoolid],
    t1.[maindate]=t2.[maindate],
    t1.[componentid]=t2.[componentid],
    t1.[note]=t2.[note]
    when not matched then
    insert values(t2.[maintenanceid],t2.[serialid],t2.[mdtoolid],t2.[maindate],t2.[componentid],t2.[note]);
    

    【讨论】:

    • 这仅在维护不是唯一的情况下才有效,维护 ID 将始终不同,并且不能将其用作度量。也许我可以使用 MaintDate、SerialID 和 MDToolId,因为那可能是解决方案。我将使用这些列尝试此代码并让您知道。谢谢
    • 感谢 Vinoth,正如我所说,maintenanceid 不可用,因为应用程序控制它并且不允许在该行中插入值。问题是,maintenanceid 在两台服务器上都不同,即使在没有 maintenanceid 的情况下插入它,它也会不断重复值,这不是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    相关资源
    最近更新 更多