2013-02-22 5 views
1

У меня есть таблица под названием tblReservations с follwing столбцами:Триггер SQL Server 2008 не работает, почему?

reserv_ID (int), aptID (int), client_ID (int), 
start_date (datetime), end_date (datetime), 
details (nvarchar(max)), confirmation (bit) 

Что триггер, чтобы сравнить две даты start_date новых отелей и end_date существующих в резервации tblReservation для конкретного aptID.

Если start_date < end_date триггер должен предотвратить внесение нового бронирования для этого aptID.

Я написал этот триггер:

CREATE TRIGGER NewReservation 
    on tblReservations 
    after insert 
    as 
    begin 
     declare @aptID int 
     declare @start_date datetime 
     declare @end_date datetime 

     select @aptID=aptID, @start_date=start_date from inserted 
     select @end_date=end_date from tblReservations 
     where [email protected] 

     if @end_date>@start_date 
     BEGIN 
      ROLLBACK TRANSACTION 
     END 
    end 

Почему этот триггер не работает?

пожалуйста, помогите

+2

Не можете ли вы использовать контрольное ограничение 'CHECK (start_date <= end_date)'? –

+0

любой триггер wirtten, где вы устанавливаете значения из вставленных или удаленных в скалярные переменные, неверен. Он не будет корректно обрабатывать многострочные вставки, обновления или удаления. Вы никогда не можете предположить, что этого не произойдет. – HLGEM

+0

Помимо многострочной проблемы, вы, вероятно, не считаете, что в tblReservations имеется много строк для определенного идентификатора apt. – HLGEM

ответ

0

Первая проблема, которую я вижу это вы предполагая, что вставляется в один ряд.

Try:

Select top 1 @aptID=bb.aptID, @start_date=start_date 
from inserted as aa 
join 
(
    select Max(start_date) as Start_Date from inserted 
) as bb 
on aa.Start_Date =bb.Start_Date 

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

+0

+1 точно - триггер может вызываться один раз для нескольких 'INSERT', и поэтому' Inserted' будет содержать несколько строк ... –

+1

Это будет работать неправильно для многострочных вставок. Если вы когда-либо присваиваете скалярные переменные из 'вставленного' внутри триггера, это, вероятно, нарушено. –

1

Помимо многоуровневой проблемы, которую другие подняли, вы, вероятно, не считаете, что в tblReservations имеется много строк для определенного идентификатора apt.

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

CREATE TRIGGER NewReservation 
    ON tblReservations 
    INSTEAD OF INSERT 
    AS 
    BEGIN 

     INSERT tblReservations (<put field list here>) 
     SELECT <put field list here> 
     FROM inserted i 
     JOIN (SELECT aptid, MAX(reservationid)AS reservationid FROM tblReservations GROUP BY aptid) maxid 
      ON i.aptid = r.aptid 
     JOIN tblReservations r 
      ON r.reservationid = maxid.reservationid 
     WHERE r.enddate<i.startdate 


    END 
+0

ok, но теперь я получаю эту ошибку: Msg 4104, уровень 16, состояние 1, процедура NewReservation, строка 15 Идентификатор с несколькими частями «r.aptid» не может быть связан. – user2099269

+0

Это потому, что я сменил псевдоним, когда писал, и пропустил ссылку. r.aptid должен быть maxid.aptid – HLGEM

+0

спасибо, он работает сейчас, вы отлично – user2099269

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