2013-08-29 2 views
9

Я работаю на SQL Server 2008R2, я имею следующую таблицуTrigger для предотвращения вставки для дублирования данных двух столбцов

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

Теперь я хочу, чтобы предотвратить вставку, если у меня есть данные, хотя ID разные, но данные имеется

ID Name  date 
    4 ABC  2011 

Просьба направлять меня, как мне написать этот триггер.

+1

Действительно ли вам нужен спусковой крючок? Вы пробовали уникальный индекс или ограничение? – Elmer

+0

и как применять, когда мой первичный ключ ID? – WiXXeY

+2

CREATE UNIQUE NONCLUSTERED INDEX XXTable_Unq ON xxTable (имя ASC, [дата] ASC) – Elmer

ответ

16

Что-то вроде этого:

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 

Это просто для вставки, вы можете рассмотреть вопрос обновления тоже.

Update

Более простой способ будет просто создать уникальное ограничение на столе, это будет также применять его для обновления слишком и устранить необходимость триггера. Просто выполните:

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

а затем вы будете в бизнесе.

+1

Простое уникальное ограничение было бы лучше. – Namphibian

+0

хотя это поднимет ошибку, но не может остановить вставку, моя проблема все еще там – WiXXeY

+0

О, да, это потому, что я пропустил линию ROLLBACK - так что добавьте этот, как у меня. Но взгляните на ответ Джеймса, возможно, уникальное ограничение - это то, что вам нужно. – Rocklan

2

Если вы используете процедуру хранения, вставляя данные в таблицу, вам действительно не нужен триггер. Сначала проверьте, существует ли комбинация, и не вставляйте ее.

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

IF (SELECT COUNT(*) FROM tblData WHERE Name = @Name AND [email protected]) = 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 
+1

триггер может поднять ошибку, но данные все еще вставляются в таблицу, как прекратить вставлять данные. – WiXXeY

-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 [email protected] 
    select @cnt3=Count(*) from TableName where [email protected] 

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

    end 
+0

Это полно ошибок и не будет работать. У вашего оператора вставки есть жестко закодированные значения, плюс он не позволит использовать данные с повторяющимися именами или датами или даже идентификаторами. – Rocklan

+0

Требование не допускать дублирования даже другого идентификатора, верно? – Kalyan

0

Вы действительно не нужен триггер для этого. Просто настройте уникальное ограничение для нескольких столбцов.

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

Не следует ли ограничивать только столбцы Name и Date? – Rocklan

Смежные вопросы