12

我正在研究SQL Server 2008R2,我有下表

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

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

 ID    Name     date
  4    ABC      2011

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

4

6 回答 6

22

像这样的东西:

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

然后你就会做生意。

于 2013-08-29T05:22:47.697 回答
4

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

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  
于 2013-08-29T05:47:58.817 回答
0

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

ALTER TABLE [dbo].[TableName]    
ADD CONSTRAINT [UQ_ID_Name_Date] UNIQUE NONCLUSTERED
(
    [ID], [Name], [Date]
)
于 2013-08-29T08:23:25.133 回答
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

这是关于如何以及何时使用它们的很好的讨论。

于 2020-04-13T18:34:40.787 回答
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  
于 2021-05-31T14:24:36.823 回答
-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
于 2013-08-29T06:09:16.737 回答