如果它们在同一天,检查是否重叠两次

时间:2018-03-10 16:49:08

标签: mysql database relational-database

我有下表。

CREATE TABLE IF NOT EXISTS mydb.Hours (
  Date DATE NULL,
  Start VARCHAR(5) NULL,
  End VARCHAR(5) NULL,
  Courses_ID INT NOT NULL,
  Classroom_ID INT NOT NULL,
  PRIMARY KEY (Courses_ID, Classroom_ID),
  INDEX fk_Hours_Classroom1_idx (Classroom_ID ASC),
  CONSTRAINT fk_Hours_Courses1
    FOREIGN KEY (Courses_ID)
    REFERENCES mydb.Courses (ID)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
 CONSTRAINT fk_Hours_Classroom1
   FOREIGN KEY (Classroom_ID)
   REFERENCES mydb.Classroom (ID)
   ON DELETE NO ACTION
   ON UPDATE NO ACTION)
ENGINE = InnoDB

我想检查在插入之前是否已经在当天分配给教室的课程,其时间可能与新条目重叠。

我不确定如何创建一个BEFORE INSERT触发器来获取该日期教室的时间并检查时间是否重叠,因为它们只是一个长度为5的字符串。

CREATE DEFINER = CURRENT_USER TRIGGER `mydb`.`Hours_BEFORE_INSERT` BEFORE INSERT ON `Hours` FOR EACH ROW
BEGIN
    if exists(select 1
    from Hours h
    where h.Classroom_ID = new.Classroom_ID
      and h.Date = new.Date
      and h.Start <= new.End
      and h.End   >= new.Start) then
      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Room is already booked at that time';
      end if;
END

1 个答案:

答案 0 :(得分:0)

您可以通过以下方式检查是否存在重叠:

select 1
from Hours h
where h.Classroom_ID = @Classroom_ID
  and h.Date = @Date
  and h.Start <= @End
  and h.End   >= @Start;

或运行条件插入:

insert into Hours (Date, Start, End, Courses_ID, Classroom_ID)
    select @Date, @Start, @End, @Courses_ID, @Classroom_ID
    from dual
    where not exists (
        select *
        from Hours h
        where h.Classroom_ID = @Classroom_ID
          and h.Date = @Date
          and h.Start <= @End
          and h.End   >= @Start;
    );

然后检查是否插入了任何行。

注意:将@ -variables替换为新记录的值。

您还可以检查触发器中的重叠并引发错误:

BEGIN
    IF EXISTS (
            select *
            from Hours h
            where h.Classroom_ID = new.Classroom_ID
              and h.Date = new.Date
              and h.Start <= new.End
              and h.End   >= new.Start
        )
        THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'course time overlap'
    END IF;
END

请注意,您可能还需要编写类似的UPDATE触发器。

另请注意,如果您想在一分钟内允许重叠,则可能需要将<=>=更改为<>(例如 11:30- 12:30 12:30 -13:30 )。