MySQL триггер / проверка INSERT на основе нескольких факторов (местоположение, дата и время) - PullRequest
0 голосов
/ 21 октября 2018

У меня есть планировщик сменного графика для различных складов.Я пытаюсь добавить несколько проверок на уровне БД.Если я использую составной ключ (удаляя shift_id ) для сопоставления персонала, местоположения, даты и времени, когда это работает, но это не решает проблему наложения смены (например, если я вставляюте же самые данные, что и shift_id 1 , но вместо 09:00 время начала - 09:01 будет принимать в качестве допустимого изменения).

Schema

В приведенном ниже примере INSERT должен завершиться ошибкой для shift_id 2 , поскольку время сдвига равноперекрывается для того же staff_id 1 в тот же день Следующая доступная смена для того же персонала (в тот же день и в том же месте или в другом) должна быть доступна после 13:00.Для shift_id 3 должен быть еще один сбой, поскольку staff_id 1 уже запланирован на ту же дату и те же часы в другом месте ( location_id 1 ).Тем не менее, * shift_id 4 * должно быть принято, поскольку не совпадает начало / конец смены для одного и того же идентификатора персонала.

Conditions

Я пытался добавить ограничение таблицы для сравнения shift_start и shift_end, но безуспешно:

 ADD CONSTRAINT NoDoubleShifts CHECK(
    NOT EXISTS (
            SELECT 1
            FROM Shift S1, Shift S2
            WHERE s1.shift_date + s1.shift_start < s2.shift_date + s2shift_start
            AND s1.shift_date + s1.shift_end > s2.shift_Date + s2shift_start)

MySQL выдает ошибки (IЯ предполагаю, что ограничение не отформатировано " Оператор был найден, но между CHECK не найдено разделителя между ними" ).

Второй попыткой было добавить триггер ДО ВСТАВКИ вразные комбинации, но тоже не работали.Подсчитывает время, но мешает мне добавить других сотрудников (с другим идентификатором) в течение этого временного интервала.

begin
  if exists (select * from shift
             where shift_start <= new.shift_end
             and shift_end >= new.shift_start ) then
    signal sqlstate '45000' SET MESSAGE_TEXT = 'Shifts are overlapping';
  end if;
end;

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

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

1 Ответ

0 голосов
/ 21 октября 2018

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

begin
  if exists (select * from shift
             where shift_start <= new.shift_end
             and shift_end >= new.shift_start
             and staff_id = new.staff_id) then
    signal sqlstate '45000' SET MESSAGE_TEXT = 'Shifts are overlapping';
  end if;
end

Еще раз спасибо Нику ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...