温馨提示:本文翻译自stackoverflow.com,查看原文请点击:mysql - Using trigger to make sure inserted data doesnt cross limit
mysql triggers

mysql - 使用触发器确保插入的数据不会超过限制

发布于 2020-07-20 17:22:01

我想将表1中的值总和与表2中的极限值进行比较。我尝试使用约束或触发器,但没有任何帮助

如下图所示,表中有2个表,表1保留了2列,并且可用。这些列中的数据来自用户,并且其取决不能超过第二个表的限制。

例如,用户可以输入任何数量,其中所有列的总和必须小于限制

从表一开始,我可以在预订的列中输入值,该值可以在0到表2的限制之间,但是如果达到限制,则它无法为该元素添加更多行

create table booked (room_id foreign key (room_id),
   booked datetime, booked_seats int, remaining_seats);

create table rooms ( room_id primary key
   room_size int);

预订的座位是由用户完成的,为此我有单独的触发器以确保用户输入正确,要使用触发器或类似的东西,它将检查第一个表中所有已预订座位的总和并与第二个表中的room_size比较。如果总和小于它将编辑的大小,否则返回错误

create trigger test after insert on booked 
begin 
if sum of all (new.booked ) where the id is same > table2.limit then
    ....
end

我使用触发器来比较值,但没有用

查看更多

提问者
Deamon
被浏览
14
nbk 2020-04-20 04:12

为了获得快速而良好的答案,您需要提供的功能比提供示例功能的示例数据还要多。

如果room_size小于合计席位,则此触发器将阻止任何插入尝试。

请阅读我解释的结尾,您必须在其中进行一些工作

DELIMITER $$
CREATE TRIGGER check_roomsize_Before_Insert BEFORE insert on booked 
FOR EACH ROW
begin 
    if (SELECT SUM(booked_seats) + NEW.booked_seats FROM booked  WHERE room_id  = NEW.room_id  AND booked  = NEW.booked  GROUP BY room_id) 
        > (select room_size from rooms where rooms.room_id= new.room_id) then
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Roomsize too smal!';
    end if;
END$$
DELIMITER ;

模式(MySQL v5.7)

create table rooms ( room_id int primary key,
   room_size int);

 create table booked (room_id int,
   booked datetime, booked_seats int, remaining_seats int,    CONSTRAINT fk_category
    FOREIGN KEY (room_id) 
        REFERENCES rooms(room_id));

INSERT INTO rooms VALUES ( 1,5);

DELIMITER $$
CREATE TRIGGER check_roomsize_Before_Insert BEFORE insert on booked 
FOR EACH ROW
begin 
    if (SELECT SUM(booked_seats) + NEW.booked_seats FROM booked  WHERE room_id  = NEW.room_id  AND booked  = NEW.booked  GROUP BY room_id) 
        > (select room_size from rooms where rooms.room_id= new.room_id) then
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Roomsize too smal!';
    end if;
END$$
DELIMITER ;

INSERT INTO booked VALUES (1,now(),3,2);
#INSERT INTO booked VALUES (1,now(),3,0);

查询#1

SELECT * FROM booked;

| room_id | booked              | booked_seats | remaining_seats |
| ------- | ------------------- | ------------ | --------------- |
| 1       | 2020-04-19 20:04:07 | 3            | 2               |

在数据库小提琴上查看

如您在示例中看到的,插入了第一行,第二行给出了一个例外。

您需要改进我总结的预定座位的部分,

AND已预订= NEW.booked

因为我绝对不知道什么时间标准才能算出完整的座位数。现在的时间戳没有任何意义来测试我需要一些日期的触发器。