触发以防止插入两列的重复数据

时间:2013-08-29 05:18:23

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

我正在处理SQL Server 2008R2,我正在使用以下表格

ID     Name     date
 1     XYZ      2010
 2     ABC      2011
 3     VBL      2010

现在我想阻止插入,如果我有一个数据虽然ID不同但数据存在

 ID    Name     date
  4    ABC      2011

请指导我如何编写此触发器。

6 个答案:

答案 0 :(得分:20)

这样的事情:

CREATE TRIGGER MyTrigger ON dbo.MyTable
AFTER INSERT
AS

if exists ( select * from table t 
    inner join inserted i on i.name=t.name and i.date=t.date and i.id <> t.id)
begin
    rollback
    RAISERROR ('Duplicate Data', 16, 1);
end
go

这只是插入,你可能也想考虑更新。

<强>更新

更简单的方法是在表上创建一个唯一约束,这也将强制执行更新,并消除对触发器的需要。只是做:

ALTER TABLE [dbo].[TableName]    
ADD CONSTRAINT [UQ_ID_Name_Date] UNIQUE NONCLUSTERED
(
    [Name], [Date]
)

然后你就会开展业务。

答案 1 :(得分:3)

如果您使用将数据插入表中的存储过程,则实际上不需要触发器。首先检查组合是否存在,然后不插入。

CREATE PROCEDURE usp_InsertData
@Name varchar(50),
@Date DateTime
AS
BEGIN

IF (SELECT COUNT(*) FROM tblData WHERE Name = @Name AND Date=@Date) = 0
    BEGIN
        INSERT INTO tblData
                    ( Name, Date)
             VALUES (@Name, @Date)
        Print 'Data now added.'
     END
ELSE
    BEGIN
        Print 'Dah! already exists';
    END
END

如果您没有通过商店程序插入数据,则可以使用以下触发器。

CREATE TRIGGER checkDuplicate ON tblData
AFTER INSERT
AS

IF EXISTS ( SELECT * FROM tblData A 
INNER JOIN inserted B ON B.name=A.name and A.Date=B.Date)
BEGIN
    RAISERROR ('Dah! already exists', 16, 1);
END
GO  

答案 2 :(得分:0)

你真的不需要触发器。只需为多列设置唯一约束。

ALTER TABLE [dbo].[TableName]    
ADD CONSTRAINT [UQ_ID_Name_Date] UNIQUE NONCLUSTERED
(
    [ID], [Name], [Date]
)

答案 3 :(得分:0)

另一种选择,改为使用插入触发器。

CREATE TRIGGER MyTrigger ON dbo.MyTable
INSTEAD OF INSERT
AS

if not exists (
    select *
    from MyTable t 
    inner join inserted i
       on i.name=t.name
       and i.date=t.date and i.id <> t.id )
begin
    Insert into MyTable (Name, Date) Select Name, Date from inserted
end
go

这是如何以及何时使用它们的好方法discussion

答案 4 :(得分:0)

<块引用>

这个答案的灵感来自于 20 年 4 月 13 日 18:34 的答案。

CREATE TRIGGER MyTrigger ON dbo.MyTable  
INSTEAD OF INSERT  
AS  

if not exists (  
    select * from MyTable t   
    inner join inserted i
    on i.name=t.name and i.date=t.date and i.id <> t.id )  
begin  
    Insert into MyTable (Name, Date) Select Name, Date from inserted  
end  
else  
    THROW 51000, 'Statement terminated because a duplicate was found for the object', 1;      
go  

答案 5 :(得分:-3)

试试这个

 CREATE TRIGGER trg ON TableName
 AFTER INSERT 
 AS
  Begin
  Declare @id int,@name varchar(10),@date DateTime
  Declare @cnt1 int,@cnt2 int,@cnt3 int

  INSERT INTO TableName(ID, Name, Date) VALUES(4,'ABC',2011)
  select @id=ID,@name=Name,@date=Date from inserted

  select @cnt2=Count(*) from TableName where Name=@name
  select @cnt3=Count(*) from TableName where Date=@date

  if(@cnt2>1 or @cnt3>1)
    Rollback
  else 
    Commit

  end