如何在插入之前检查记录是否存在以防止重复?

gra*_*ace 11 sql sql-server sql-server-2008

我想选择CustomerID,OrderTypeIDLoanNumber,tblOrder并插入一个新的OrderTypeID但相同的CustomerIDLoanNumber.我的查询执行此操作但它复制了值,每次执行查询时它都会复制行.

insert into tblOrder (CustomerID, OrderTypeID, LoanNumber)
Select o.CustomerID,3, o.LoanNumber
from tblOrder as o
where o.OrderTypeID = 1;
Run Code Online (Sandbox Code Playgroud)

这是查询的作用:

OrderID 9 - 12是重复的或OrderID 5 - 8.查询执行了2次,因此记录重复.

理想的结果应该是:

Sol*_*zky 23

这里的第一个也是最重要的问题不是您的查询插入重复项; 这是你的桌子允许它首先发生.因此,您首先需要在这3个字段上创建一个UNIQUE INDEX以禁止重复.

第二个问题是如何处理操作尝试插入重复的情况.您有两个主要选择:

  1. 您可以先检查记录是否存在,如果找到则跳过INSERT,或者

  2. 您可以将UNIQUE INDEX设置为"忽略"重复项,在这种情况下,您不需要先检查,因为操作将无提示失败,只是警告未插入重复项.


如果选择选项#1(先检查),则:

CREATE UNIQUE NONCLUSTERED INDEX [UIX_tblOrder_CustomerID_OrderTypeID_LoanNumber]
    ON [tblOrder]
    ( [CustomerID] ASC, [OrderTypeID] ASC, [LoanNumber] ASC );
Run Code Online (Sandbox Code Playgroud)

然后:

INSERT INTO tblOrder (CustomerID, OrderTypeID, LoanNumber)
  SELECT o.CustomerID, 3, o.LoanNumber
  FROM   tblOrder as o
  WHERE  o.OrderTypeID = 1
  AND    NOT EXISTS (SELECT *
                     FROM tblOrder tmp
                     WHERE tmp.CustomerID = o.CustomerID
                     AND   tmp.OrderTypeID = 3
                     AND   tmp.LoanNumber = o.LoanNumber);
Run Code Online (Sandbox Code Playgroud)

如果选择选项#2(不检查),则:

CREATE UNIQUE NONCLUSTERED INDEX [UIX_tblOrder_CustomerID_OrderTypeID_LoanNumber]
    ON [tblOrder]
    ( [CustomerID] ASC, [OrderTypeID] ASC, [LoanNumber] ASC )
    WITH (IGNORE_DUP_KEY = ON);
Run Code Online (Sandbox Code Playgroud)

然后:

INSERT INTO tblOrder (CustomerID, OrderTypeID, LoanNumber)
  SELECT o.CustomerID, 3, o.LoanNumber
  FROM   tblOrder as o
  WHERE  o.OrderTypeID = 1;
Run Code Online (Sandbox Code Playgroud)

IGNORE_DUP_KEY行为示例:

CREATE TABLE #IgnoreDuplicateTest (Col1 INT);
CREATE UNIQUE NONCLUSTERED INDEX [UIX_#IgnoreDuplicateTest_Col1]
    ON #IgnoreDuplicateTest
    ( [Col1] ASC )
    WITH (IGNORE_DUP_KEY = ON);

INSERT INTO #IgnoreDuplicateTest (Col1) VALUES (1);
-- (1 row(s) affected)

INSERT INTO #IgnoreDuplicateTest (Col1) VALUES (1);
-- Duplicate key was ignored.
-- (0 row(s) affected)

INSERT INTO #IgnoreDuplicateTest (Col1)
 SELECT tmp.val
 FROM (VALUES (1),(2)) AS tmp(val);
-- Duplicate key was ignored.
-- (1 row(s) affected)

SELECT * FROM #IgnoreDuplicateTest;

-- Col1
--    1
--    2
Run Code Online (Sandbox Code Playgroud)

  • 这就是我想要的,谢谢! (2认同)

kou*_*nda 6

这可能对您有帮助

在这里,我正在检查表中是否存在当前值(变量中的值),如果存在则不插入

 Declare @claimid int, @subscriber int, @qualifyinginformation int
set @claimid = '1000008'
set @subscriber = '1'
set @qualifyinginformation = '1'

If Exists (Select * from test1 where claimid = @claimid and subscriber=@subscriber and qualifyinginformation=@qualifyinginformation )
begin
     print ('The Value already Exist')
 end
else
 begin
   Insert into test1 (claimid,subscriber,qualifyinginformation) values (@claimid,@subscriber,@qualifyinginformation)
select * from test1
end
Run Code Online (Sandbox Code Playgroud)