SQL Server 2012:在检查重复项时将数据插入 table

SQL Server 2012 : insert data into table while checking for duplicates

我已经编写了一个查询,将数据从 Excel 插入 SQL 服务器 table,我需要添加以检查该信息是否已经在 table。当我添加一个 WHERE 子句来检查 table 以查看我要插入的数据是否实际上是新的时,它不会添加任何数据,即使它是新的。

这是我的代码:

CREATE TABLE #Master 
(
    BrNBr varchar(10),
    BranchName varchar(100),
    Region varchar(100),
    Marketplace varchar(100),
    Enumber varchar(120),
    Fname varchar(100),
    Lname varchar(100),
    SBSLFName varchar(100),
    SBL varchar(100),
    Title varchar(100),
    Status varchar(100),
    StartDate int
);

INSERT INTO #Master (BrNbr, BranchName, Region, Marketplace, Enumber, Fname, Lname, SBSLFName, SBL, Title, Status, StartDate)
VALUES ('TT000', 'Test1', 'Test2', 'Test3', 'T77777', 'Test4', 'Test5', 'Test6', 'Test7', 'SBS', 'A', '42005');

INSERT INTO dbo.tbSBSTest
  SELECT DISTINCT
     BrNbr,
     BranchName,
     Region,
     Marketplace,
     Enumber,
     Fname,
     Lname,
     SBSLFName,
     SBL,
     Title,
     Status,
     CONVERT(int, StartDate, 102) AS Startdate,
     NULL AS Termdate
  FROM 
     #Master
  WHERE 
     Enumber NOT IN (SELECT DISTINCT Enumber FROM dbo.tbSBSTest);

DROP TABLE #Master

SELECT *
FROM dbo.tbSBSTest
WHERE BranchName = 'Test1';

请原谅格式 - 它是由 Excel 编写的。唯一标识符是 Enumber。如果我注释掉 WHERE 子句,它将更新,但不会与正在使用的 WHERE 子句一起更新。

如有任何建议,我们将不胜感激。

尝试使用 exists 和条件,而不是:

SELECT DISTINCT M.BrNbr, M.BranchName, M.Region...
FROM #Master AS M
WHERE NOT EXISTS(SELECT T.Enumber FROM Database.dbo.tbSBSTest AS T WHERE T.Enumber = M.Enumber)

或者使用左外连接。如果 Enumber 不是唯一的,它将允许您加入多个列

CREATE TABLE #Master ( BrNBr VARCHAR (10) ,BranchName VARCHAR (100) ,
Region VARCHAR (100) ,Marketplace VARCHAR (100), 
Enumber VARCHAR (120) ,Fname VARCHAR (100) ,Lname VARCHAR (100) ,
SBSLFName VARCHAR (100) ,SBL VARCHAR (100) ,
Title VARCHAR (100) ,Status VARCHAR (100) ,StartDate INT)

INSERT INTO #Master  (BrNbr,BranchName,Region,Marketplace,Enumber,
Fname,Lname,SBSLFName,SBL,Title,Status,StartDate) 
VALUES('TT000','Test1','Test2','Test3','T77777',
'Test4','Test5','Test6','Test7','SBS','A','42005')

INSERT INTO Database.dbo.tbSBSTest
SELECT DISTINCT m.BrNbr,m.BranchName,m.Region,m.Marketplace,
m.Enumber,m.Fname,m.Lname,m.SBSLFName,m.SBL,m.Title,m.Status,
CONVERT(INT,m.StartDate,102) AS Startdate, NULL AS Termdate
FROM #Master m
LEFT OUTER JOIN Database.dbo.tbSBSTest t on t.Enumber = m.Enumber 
WHERE t.Enumber IS NULL

DROP TABLE #Master

SELECT * FROM Database.dbo.tbSBSTest
WHERE BranchName = 'Test1'

无需检查 WHERE,数据库引擎本身提供了检查重复项、UNIQUE 约束、索引和主键的机制。您需要在目标 table 上创建这样的约束,然后它会自动(并且更有效地)拒绝基于一组列的重复记录。您可以像这样将约束添加到现有 table:

ALTER TABLE [dbo].[tbSBSTest] ADD CONSTRAINT UQ_tbSBSTest_Enumber UNIQUE(Enumber) ;

这将导致任何包含重复的 enumber 列的任何 INSERT 被拒绝。这当然可以防止重复,但副作用是整个批次都被拒绝,而不仅仅是重复的批次。这种情况的另一种选择是使用鲜为人知的 ignore_dup_key 索引选项:

ALTER TABLE [dbo].[tbSBSTest] ADD CONSTRAINT UQ_tbSBSTest_Enumber UNIQUE(Enumber) WITH (IGNORE_DUP_KEY=ON) ;

这会导致 SQL 服务器静默地忽略那些具有已经存在的 enumber 值的行,但会愉快地接受所有其他行。这是一篇更详细地介绍这个想法的文章 http://web.archive.org/web/20180404165346/http://sqlblog.com:80/blogs/paul_white/archive/2013/02/01/a-creative-use-of-ignore-dup-key.aspx

请注意,它也并非没有副作用,也请看这里 Why would you NOT set IGNORE_DUP_KEY to ON?