2016-11-16 10 views
0

У меня есть база данных полетов с несколькими таблицами. Я пытаюсь сделать триггер, чтобы отрицать вставку или обновление в полете, у которого есть запрос на обслуживание. Если самолет запрошен для обслуживания, не должно быть полетов между этими временами. Я получаю сообщение об ошибке просто отлично, но, похоже, я всегда получаю его. Как так? Спасибо заранее, я всегда ценю помощь.Триггер с двумя столами

alter trigger DateMaintenanceTrigger 
on Flight 
after update, insert 
as 
    select 
     m.StartDate, m.TargetEndDate, f.DepartureDateID 
    from 
     Maintenance.MaintenanceRequest as m 
    inner join 
     Flight as f on f.PlaneID = m.PlaneID 
    where 
     f.DepartureDateID < m.TargetEndDate 
     and f.DepartureDateID > m.StartDate 

    begin 
     raiserror ('Flight cannot take place on this maintentance date, plane not ready.', 16,1); 
     rollback transaction; 
     return 
    end; 
    go 


insert into Flight 
values (304, 3, 1, 200192, 1, '20160916 09:00:00 AM'); 
+0

Какие значения f.DepartureDateID, m.TargetEndDate и m.StartDate, является f.DepartureDateID действительно дата в том же формате, что и другие? – grom

+0

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

+0

2016-09-16 08: 30: 00.000 Начало - 2016-09-17 09: 30: 00.000 Конец. Дата запроса на обслуживание. Если я использую эту вставку на дату, все равно получите сообщение об ошибке. '20200916 09:00:00 AM' – th30d0rab1e

ответ

0

выше проблема происходит потому, что вам не хватает условие IF, а также вы присоединяетесь с полной таблицей полета, то есть, если atlease один рейс соответствует Вашим критериям вы будете получать сообщение об ошибке. для правильного применения необходимо присоединиться к inserted.PlaneID вместо как я показал ниже

alter trigger DateMaintenanceTrigger on Flight 
after update, insert 
as 
IF EXISTS (
select m.StartDate, m.TargetEndDate, f.DepartureDateID 
from Maintenance.MaintenanceRequest as m 
JOIN inserted as i 
ON i.PlaneID = m.PlaneID 
and i.DepartureDateID < m.TargetEndDate and i.DepartureDateID > m.StartDate 
) 
    begin 
     raiserror ('Flight cannot take place on this maintentance date, plane not ready.', 16,1); 
     rollback transaction; 
     return 
    end; 
    go 



insert into Flight values (304, 3, 1, 200192, 1, '20160916 09:00:00 AM'); 
+0

Вставить в значения полета (304, 3, 1, 200192, 1, '20200916 09:00:00 AM'); Я пробовал использовать год 2020 в полете, и я все еще получаю ошибку, все мои запросы на обслуживание находятся в 2016 году. – th30d0rab1e

+0

вставлен.PlaneID отредактирован, а theres two where clauses. разве у меня не было бы двух «и»? – th30d0rab1e

+0

Мне нужно присоединиться к вставленной таблице, добавив это сейчас. – Surendra

0

Я надеюсь, что вы решили его сейчас, но если я не могу попробовать помочь. Попробуйте сделать это так, я попробовал его локально только с истинным/ложным запросом, и он должен работать до тех пор, пока ваш запрос в порядке, я не уверен, где наиболее корректно откладывать откат кстати, теперь я поместите его в функцию catch, но, возможно, это лучше перед raiserror().

alter trigger DateMaintenanceTrigger 
on Flight 
after update, insert 
as 

BEGIN TRY 
    IF EXISTS(
     select 
      m.StartDate, m.TargetEndDate, f.DepartureDateID 
     from 
      Maintenance.MaintenanceRequest as m 
     inner join 
      Flight as f on f.PlaneID = m.PlaneID 
     where 
      f.DepartureDateID < m.TargetEndDate 
      and f.DepartureDateID > m.StartDate 
    ) 
    BEGIN 
     raiserror ('Flight cannot take place on this maintentance date, plane not ready.', 16,1); 
    END 
    ELSE 
    BEGIN 
     insert into Flight values (304, 3, 1, 200192, 1, '20160916 09:00:00 AM'); 
    END 
END TRY 
BEGIN CATCH 
    DECLARE @ErrorMessage NVARCHAR(4000); 
    DECLARE @ErrorSeverity INT; 
    DECLARE @ErrorState INT; 

    SET @ErrorMessage = ERROR_MESSAGE(); 
    SET @ErrorSeverity = ERROR_SEVERITY(); 
    SET @ErrorState = ERROR_STATE(); 

    rollback transaction; 

    RAISERROR (@ErrorMessage, 
       @ErrorSeverity, 
       @ErrorState 
       ); 
END CATCH;