2016-01-20 2 views
1

У меня есть таблица EmployeeLeaves, имеющие столбцы:Как предотвратить ни одного совпадения дат в SQL Server 2012

EmployeeID int, 
LeaveTypeID int, 
LeaveDate datetime2, 
IsHalfDay bit, 
DateCreated datetime2, 
Createdby varchar 

Я прошу вас помочь мне с триггером, предотвращающие же дату в столбце «LeaveDate». В таблице нет диапазонов дат, таких как «Todate» и «FromDate».

Заранее спасибо.

+0

Где эти конфликтующие записи должны идти? Hav вы посмотрели вместо триггера вставки – knkarthick24

+1

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

+0

Кажется, что ограничение должно включать не только столбец «LeaveDate». Должно ли более одного сотрудника разрешаться покидать работу каждый день? – Brad

ответ

3

Пожалуйста, обратитесь образец демо,

CREATE TABLE EmployeeLeaves 
    (
    EmployeeID INT, 
    LeaveTypeID INT, 
    LeaveDate DATETIME2, 
    IsHalfDay BIT, 
    DateCreated DATETIME2, 
    Createdby VARCHAR(50) 
) 

insert into EmployeeLeaves 
values (1,1,'2016-01-01',0,getdate(),'Admin'), 
(2,1,'2016-01-01',0,getdate(),'Admin'), 
(3,1,'2016-01-01',0,getdate(),'Admin'), 
(4,1,'2016-01-01',0,getdate(),'Admin'), 
(5,1,'2016-01-01',0,getdate(),'Admin') 

SELECT * 
FROM EmployeeLeaves 

СПОСОБ-1 с использованием уникального ограничения

--Introduce the unique constraint 
    ALTER TABLE EmployeeLeaves 
     ADD CONSTRAINT uq_employeeid_leavedate UNIQUE (EmployeeId, LeaveDate) 
    --Try to create overlap 
    insert into EmployeeLeaves 
    values (1,1,'2016-01-01',0,getdate(),'Admin') 
    --You will get the following error 
    --Msg 2627, Level 14, State 1, Line 1 
    --Violation of UNIQUE KEY constraint 'uq_employeeid_leavedate'. Cannot insert duplicate key in object 'dbo.EmployeeLeaves'. The duplicate key value is (1, 2016-01-01 00:00:00.0000000). 
    --The statement has been terminated. 
    --Insert proper date 
    insert into EmployeeLeaves 
    values (1,1,'2016-01-02',0,getdate(),'Admin') 
    --Check the result 
    SELECT * 
    FROM EmployeeLeaves 

СПОСОБ-2, используя вместо триггера

ALTER TRIGGER Trigger_Test 
ON EmployeeLeaves 
INSTEAD OF INSERT 
AS 
    BEGIN 
     IF EXISTS(SELECT TOP 1 1 
       FROM inserted I 
         INNER JOIN EmployeeLeaves e 
           ON i.EmployeeID = e.EmployeeID 
            AND i.LeaveDate = e.LeaveDate) 
     BEGIN 
      RAISERROR (N'Overlapping range.',16,1); 

      ROLLBACK TRANSACTION; 
     END 
     ELSE 
     BEGIN 
      INSERT INTO EmployeeLeaves 
      SELECT * 
      FROM inserted 
     END; 
    END 
+0

Спасибо. Как мы можем реализовать его с помощью вместо триггера insert? –

+0

пожалуйста, обращайтесь метод 2 в моем ответе. – StackUser

0

Вы можете добавить уникальное ограничение в поле даты отпуска или вы можете проверить и повысить исключение, используя

if exist(select top 1 EmployeeID from table where EmployeeID = @emploeeid and datediff(day,leavedate,@applydate)=0 and leavetypeid= @leavetypeid) begin raise_error('leave already exist',1,1) end

+0

Привет. Сожалею, что вышеуказанный код не работает. Дублированные записи по-прежнему вставляются, даже если сообщение появляется «Leave Already Exist». –

+0

Да, чтобы избежать вставки, вы должны использовать возврат сразу после повышения ошибки. SQL SERVER не останавливает выполнение, даже если исключение поднято .. вы должны вернуть modificaiton = begin raise_error ('leave already exist', 1,1) return end –

+0

Модифицированная версия если есть (выберите вверху 1 EmployeeID из таблицы где EmployeeID = @emploeeid и dateiff (день, leavedate, @ applydate) = 0 и leavetypeid = @leavetypeid) begin raise_error ('leave already exist', 1,1) Возврат конец INsert Statement ЗДЕСЬ –