Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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 合并问题SQL Server_Sql Server_Merge_Unique Key - Fatal编程技术网

Sql server 合并问题SQL Server

Sql server 合并问题SQL Server,sql-server,merge,unique-key,Sql Server,Merge,Unique Key,我正在尝试创建一个过程,该过程将从临时表中获取值,并将它们加载到另一个表中。第二个表在其三列(不包括主键)上有一个复合唯一约束。我正在使用merge语句尝试处理上载,并不断收到一个错误消息 味精2627,第14级,状态1,第13行 违反唯一键约束“IX_表”。 无法在对象“dbo.table”中插入重复键。重复的键值是(aaa,aaa,aaa) 我真的很困惑,因为我使用merge语句的全部原因就是为了防止这种情况发生。以下是过程的相关部分(名称已更改,临时表的插入已更改) 我真的很困惑,为什么这

我正在尝试创建一个过程,该过程将从临时表中获取值,并将它们加载到另一个表中。第二个表在其三列(不包括主键)上有一个复合唯一约束。我正在使用merge语句尝试处理上载,并不断收到一个错误消息

味精2627,第14级,状态1,第13行
违反唯一键约束“IX_表”。
无法在对象“dbo.table”中插入重复键。重复的键值是(aaa,aaa,aaa)

我真的很困惑,因为我使用merge语句的全部原因就是为了防止这种情况发生。以下是过程的相关部分(名称已更改,临时表的插入已更改)

我真的很困惑,为什么这不是检测重复,有什么想法吗


提前感谢

您正在同一语句中多次更新同一行。了解DML是基于集合的。这些行不会一行接一行地应用。这将迫使执行计划效率低下,不符合SQL的精神

我不确定SQL Server中如何定义重复更新。我相信SQL Server定义了至少发生一次重复更新。目前还不清楚哪一个能通过


这里,我们处理的是插入。您将插入同一行两次。在执行任何写入操作之前,将完全计算写入操作。这就是为什么两个插入被“排队”的原因。

在USING语句之后,您的条件不能被满足。因此,它将继续插入,然后尝试插入一个副本。合并不是逐个记录处理的,而是作为一个集合处理的。在操作开始时,有一个目标表的快照,用于与源记录进行比较。如果源数据中有重复的键(如此处所示),则它们都将落入“不匹配”中。这不像一行导致插入,然后第二行导致更新。如果您不知道源数据,并且可能存在重复数据,请在源数据查询中使用SELECT DISTINCT。更新没有意义。它会更新为相同的值。@当然是凯文!我真蠢。谢谢,效果很好,希望我能投更多的票
create table #TempTable(Id int
                        , str1 varchar(3)
                        , str2 varchar(15)
                        , str3 varchar(10))

INSERT INTO #TempTable
           (str1 
           ,str2 
           ,str3)
     VALUES
           ('aaa','aaa','aaa'), ('bbb', 'bbb', 'bbb'), ('aaa','aaa','aaa')

MERGE dbo.table AS t
    USING #TempTable AS s
    ON (t.str1 = s.str1
    AND t.str2 = s.str2
    AND t.str3 = s.str3)
    WHEN MATCHED THEN 
        UPDATE SET t.str1 = s.str1
    WHEN NOT MATCHED THEN
        INSERT (str1, str2, str3)
        VALUES (s.str1, s.str2, s.str3);

drop table #TempTable