数据库是SQL Server 2008.我有一个查询从一个或多个表中提取行,然后尝试将它们插入到表变量中。
我想要一种有效的方法来防止重复插入,所以我想出的是:
INSERT INTO @MyTableVariable
SELECT SomeID
FROM SomeTable st
INNER JOIN SomeOtherTable sot ON sot.SomeID = st.SomeID
LEFT JOIN @MyTableVariable t ON t.SomeID = sot.SomeID
WHERE t.SomeID IS NULL
但是,在某些情况下,这似乎不会阻止重复插入。
似乎(如果您考虑并查看查询计划,这是有道理的)在左连接操作中仅使用@MyTableVariable的初始“状态”。换句话说,如果在运行此语句之前@MyTableVariable已经有SomeID,这将防止重复,但如果SomeTable / SomeOtherTalbe上的FROM / INNER JOIN导致重复的SomeID,则不会阻止重复。
除了简单地在SELECT语句上打一个DISTINCT之外,还有另一种更有效的方法来处理它吗?
答案 0 :(得分:3)
据我所知,SQL Server中无法INSERT IGNORE
或INSERT ON DUPLICATE KEY
。当然,是 MERGE,但它无法解决您的问题,因为它的行为与您的INSERT相同,即它会引发异常。
还有另一种更有效的方法来解决这个问题吗?
在我看来,您的选择是:
尝试找到更具体的过滤/加入方式,以免产生重复。
'Slap'DISTINCT在某个早期阶段,以防止重复进入首先加入的任何一个表。
将主要负责生成重复项的表格转换为在本地应用DISTINCT的子选择。
如果您无法生成无重复的结果集,则必须付费(性能方面)以消除可能的重复项。无论它是什么,DISTINCT,或GROUP BY,或者可能是排名函数,都会导致一些性能损失,你应该接受这个事实。
答案 1 :(得分:0)
您需要在表变量的id列上创建键。
声明如下:
declare @MyTableVariable table(SomeID int identity(1,1) primary key)
此主键将阻止重复插入
希望这有帮助