使用SQL Server 2008防止插入重复的行

时间:2012-08-16 10:33:35

标签: sql sql-server-2008 tsql

我正在尝试将一个表中的一些数据插入到另一个表中,但我想阻止插入重复的行。我目前有以下查询:

INSERT INTO Table1
(
    Table1Col1,
    Table1Col2,
    Table1Col3,
    Table1Col4,
    Table1Col5
)
SELECT
    Table2Col1,
    Table2Col2 = constant1,
    Table2Col3 = constant2,
    Table2Col4 = constant3,
    Table2Col5 = constant4
FROM Table2
WHERE
    Condition1 = constant5
AND
    Condition2 = constant6
AND
    Condition3 = constant7
AND
    Condition4 LIKE '%constant8%'

我不知道的是,我试图从Table2插入Table1的行可能已经存在,我想防止这种可能的重复发生并跳过插入,然后继续插入下一个唯一的行。

我已经看到我可以使用WHERE NOT EXISTS子句并使用INTERSECT关键字,但我并不完全理解如何将它应用于我的特定查询,因为我只想使用Table2中的一些选定数据然后一些常量值插入表1中。

编辑:

我应该补充一点,TableCol2到TableCol5的列实际上并不存在于结果集中,我只是将这些列与返回的Table2Col1一起填充。

3 个答案:

答案 0 :(得分:3)

由于您使用的是SQL Server 2008,因此可以使用merge语句。

您可以根据键

轻松检查是否存在行

类似的东西:

merge TableMain  AS target
using TableA as source 
ON <join tables here>
WHEN MATCHED THEN <update>
WHEN NOT MATCHED BY TARGET <Insert>
WHEN NOT MATCHED BY SOURCE <delete>

答案 1 :(得分:1)

Intersect(在Sql Server的术语中减去)是不可能的,因为它比较整行。其他两个选项是not in/not exists/left joinmergeNot In仅适用于单列原始密钥,因此在此实例中不可用。 In/Exists/Left join在Sql Server中的性能应该相同,所以我只使用exists:

INSERT INTO Table1
(
    Table1Col1,
    Table1Col2,
    Table1Col3,
    Table1Col4,
    Table1Col5
)
SELECT
    Table2Col1,
    Table2Col2 = constant1,
    Table2Col3 = constant2,
    Table2Col4 = constant3,
    Table2Col5 = constant4
FROM Table2
WHERE
    Condition1 = constant5
AND
    Condition2 = constant6
AND
    Condition3 = constant7
AND
    Condition4 LIKE '%constant8%'
AND NOT EXISTS
    (
       SELECT *
         FROM Table1 target
        WHERE target.Table1Col1 = Table2.Table2Col1
          AND target.Table1Col2 = Table2.Table2Col2
          AND target.Table1Col3 = Table2.Table2Col3
    )

Merge用于同步两个表;它能够插入,更新和删除target table中的记录。

merge into table1 as target
using table2 as source
   on target.Table1Col1 = source.Table2Col1
  AND target.Table1Col2 = source.Table2Col2
  AND target.Table1Col3 = source.Table2Col3
when not matched by target then
  insert (Table1Col1,
          Table1Col2,
          Table1Col3,
          Table1Col4,
          Table1Col5)
  values (Table2Col1,
          Table2Col2,
          Table2Col3,
          Table2Col4,
          Table2Col5);

如果在传输过程中计算了table2中的列,则在not exists()情况下,您可以使用派生表代替table2,这同样适用于merge示例 - 只需将查询放在引用的位置即可表2。

答案 2 :(得分:1)

我们在表格中检查数据是否已存在。为此,我们必须使用If condition to avoid the duplicate insertion