5

数据库是 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 之外,还有另一种更有效的方法来处理这个问题吗?

4

2 回答 2

3

据我所知,SQL Server 中没有INSERT IGNORE或没有办法。INSERT ON DUPLICATE KEY当然有MERGE,但不能解决您的问题,因为它的行为与您的 INSERT 相同,即它会引发异常。

还有另一种更有效的方法来处理这个问题吗?

在我看来,您的选择是:

  1. 尝试找到一种更具体的过滤/加入方式,以免产生重复。

  2. 'Slap' DISTINCT 在较早阶段的某个地方,以防止重复进入首先连接的任何一个表。

  3. 将主要负责产生重复的表转换为在本地应用 DISTINCT 的子选择。

如果您无法生成无重复的结果集,则必须(在性能方面)为消除可能的重复付费。不管它是什么,DISTINCT 或 GROUP BY,或者排名函数,它都会导致一些性能损失,你应该接受这个事实。

于 2011-06-18T13:30:25.577 回答
0

您需要在表变量的 id 列上创建键。

像这样声明它:

declare @MyTableVariable table(SomeID int identity(1,1) primary key)

此主键将防止重复插入

希望这可以帮助

于 2011-06-17T19:45:15.483 回答