Как сделать триггер, чтобы проверить, что время, которое пользователь выбрал, пусто или нет? - PullRequest
0 голосов
/ 06 октября 2019
ALTER TRIGGER [dbo].[Check_time] on [dbo].[Schedule] after insert
AS 

if exists ((select * from Schedule as S Join inserted as i on S.DDate=i.DDate AND S.ST_TIME=i.ST_TIME AND S.END_TIME=i.END_TIME))
BEGIN 
print('INVALID TIME')
ROLLBACK TRANSACTION 
return
END 

image

* но есть еще одна проблема: пользователь может вставить время до того, как закончится время окончания предыдущего пользователя, как я могу его решить? ***

Ответы [ 3 ]

1 голос
/ 06 октября 2019

Поскольку вы использовали Trigger, я отвечу в формате Trigger. Используйте INSTEAD OF вместо вставки. В этом случае вы проверяете таблицу перед установкой записи. Используйте 2 в качестве предложения

ALTER TRIGGER [dbo].[Check_time]
   ON  [dbo].[Schedule]
   INSTEAD OF INSERT
AS 
BEGIN
    DECLARE @Count INT = 0
    SELECT @Count = COUNT(*) 
    FROM Schedule AS S 
    INNER JOIN inserted AS i ON S.DDate=i.DDate AND S.ST_TIME=i.ST_TIME AND S.END_TIME=i.END_TIME

    IF ISNULL(@Count , 0) = 0
    BEGIN 
        INSERT INTO [dbo].[Schedule] ([MID], [SID], [ST_TIME], [END_TIME], [DDate], [ST_ID])
        select [MID], [SID], [ST_TIME], [END_TIME], [DDate], [ST_ID] FROM inserted
    END 

END
0 голосов
/ 06 октября 2019

1. Уточнение проблемы

После разъяснений ОП в комментариях становится ясно, что основной целью является проверка перекрывающихся периодов времени.

Например,

  • комбинация периодов (01:00:00- 02:00:00, 02:01:00-03:00:00) - разрешено в тот же день
  • (01:00:00 - 05:00:00, 02:01:00-03:00:00) или (01:00:00 - 03:00:00, 02:00:00-04:00:00) -не разрешены

(Надеюсь, я правильно понял)

Проверка на перекрывающиеся периоды - типичная задача, и я даже нашел существующий ответ по SO: Ограничение проверки на перекрытие диапазона дат

2. Предлагаемое решение

С небольшой модификацией я могу предложить это решение: http://sqlfiddle.com/#!18/e2146/2

CREATE TABLE Schedule (
  ID BIGINT IDENTITY PRIMARY KEY,
  DDate date,
  ST_TIME time,
  END_TIME time
);

-- UNIQUE CONSTRAINT
CREATE UNIQUE INDEX UI_DDATE_ST_TIME_END_TIME ON Schedule(DDATE, ST_TIME, END_TIME);

-- CONSTRAINT FOR OVERLAPPING PERIODS
CREATE FUNCTION [dbo].[fn_chkOverlapping]
(
  @DDate AS DATE,
  @ST_TIME AS TIME,
  @END_TIME time
)
RETURNS BIT
AS 
BEGIN
 RETURN (
  SELECT 
  CASE
     WHEN @ST_TIME>@END_TIME THEN 0
     WHEN EXISTS(
          SELECT 1 FROM [dbo].[Schedule]
            WHERE
                @DDATE = DDATE
                AND @END_TIME >= ST_TIME
                AND END_TIME >= @ST_TIME
     ) THEN 0
     ELSE 1
  END
 )
END;

ALTER TABLE [dbo].[Schedule]  WITH CHECK ADD CONSTRAINT [CK_Overlapping] CHECK  ([dbo].[fn_chkOverlapping]([DDate],[ST_TIME],[END_TIME])=0);

3. Альтернативы

Совершенно возможно сделать это с помощью триггеров.

Я сам предпочитаю определять ограничения на CREATE CONSTRAINT, чем на других типах объектов.

Это вопрос вкуса, а ненеобходимость.

0 голосов
/ 06 октября 2019

Ваш триггер просто проверяет наличие дублированных значений. Вам лучше с ограничением unique:

alter table Schedule add constraint unq_schedule_ddate_st_time_end_time
    unique (ddate, st_time, end_time);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...