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?
我已经编写了一个查询,将数据从 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?