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

时间:2015-01-20 03:58:44

标签: sql sql-server sql-server-2008

我想从CustomerID中选择OrderTypeIDLoanNumbertblOrder,然后将其插入新的OrderTypeID但同一CustomerIDLoanNumber。 我的查询会这样做,但它会重复这些值,每次执行查询时它都会复制行。

insert into tblOrder (CustomerID, OrderTypeID, LoanNumber)
Select o.CustomerID,3, o.LoanNumber
from tblOrder as o
where o.OrderTypeID = 1;

这是查询的作用:

订单ID 9 - 12是重复项或订单ID 5 - 8.查询执行了2次,因此记录重复。

理想的结果应该是:

6 个答案:

答案 0 :(得分:20)

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

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

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

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


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

    CREATE UNIQUE NONCLUSTERED INDEX [UIX_tblOrder_CustomerID_OrderTypeID_LoanNumber]
        ON [tblOrder]
        ( [CustomerID] ASC, [OrderTypeID] ASC, [LoanNumber] ASC );
    

    然后:

    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);
    

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

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

    然后:

    INSERT INTO tblOrder (CustomerID, OrderTypeID, LoanNumber)
      SELECT o.CustomerID, 3, o.LoanNumber
      FROM   tblOrder as o
      WHERE  o.OrderTypeID = 1;
    

    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
    

答案 1 :(得分:5)

这可能有助于你

这里我正在检查存在的值(在变量中)是否存在于表中,如果存在则留下其他插入

 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

答案 2 :(得分:2)

这是你想要的吗?

CREATE TABLE tblOrder(
    OrderID     INT IDENTITY(1, 1),
    CustomerID  INT,
    OrderTypeID INT,
    LoanNumber  INT
)
INSERT INTO tblOrder VALUES
(1, 1, 45584565),
(1, 1, 45566856),
(1, 1, 45565584),
(1, 1, 45588545)

INSERT INTO tblOrder( CustomerID, OrderTypeID, LoanNumber)
SELECT
    o.CustomerID,
    3,
    o.LoanNumber
FROM tblOrder o
WHERE NOT EXISTS(
    SELECT 1
    FROM tblOrder
    WHERE
        CustomerID = o.CustomerID
        AND OrderTypeID = 3
        AND LoanNumber = o.LoanNumber
)

答案 3 :(得分:0)

这是你要找的吗?确保

Create table #temp(OrderID int, CustomerID int,  OrderTypeID int, LoanNumber int)
INsert into #temp values(1  , 1  , 1  , 45584565)
INsert into #temp values(2 ,  1 ,  1 ,  45566856)
INsert into #temp values(3  , 1  , 1 ,  45565584)
INsert into #temp values(4  , 1  , 1  , 45588545)

select * from #temp



UPDATE TE
SET  CustomerID=tab.CustomerID,OrderTypeID=3,LoanNumber=tab.LoanNumber
FROM #temp TE inner join
(Select o.OrderID,o.CustomerID,3 tt, o.LoanNumber
from #temp as o
where o.OrderTypeID = 1)tab

ON TE.OrderID = tab.OrderID

select * from #temp
drop table #temp

答案 4 :(得分:0)

ALTER PROCEDURE [dbo].[InsertName] (
    @empname varchar(25),
    @email varchar(25)
)
AS
IF EXISTS (
        SELECT
            'True'
        FROM
            Employee
        WHERE      
            EmployeeName = @empname
    )
    BEGIN
        SELECT 'This record already exists!'
    END
ELSE
    BEGIN
        INSERT into Employee(EmployeeName, EmailId) VALUES(@empname,@email)    
    END

EXEC [InsertName]   
   'Darshil','darshil@gmail'

答案 5 :(得分:0)

在某些列名称上设置主键后,它将检查 该列名称上的重复条目,如果找到则只需忽略 重复数据。

INSERT IGNORE INTO db_name.table_name(col1, col2, col3) VALUES (%s,%s,%s)