是否有替代使用子查询执行检查约束?

时间:2014-08-09 19:57:34

标签: mysql sql triggers check-constraints

我有两张桌子

Table Room(
  capacity INTEGER,
  roomID varchar(5)
)

Event(
  attendance INTEGER,
  room varchar(5), 
  CHECK(attendance <= (SELECT R.capacity FROM Room R, WHERE R.roomID = room))
)

但我猜MySQL不允许检查内的子查询。

是否有另一种方法来执行此检查?我只熟悉触发器,但看起来它们只允许插入,删除等显式操作。我只是想阻止数据被插入,除非它符合标准。

1 个答案:

答案 0 :(得分:3)

MySQL不强制执行CHECK约束。

在某些情况下,您可以使用外键约束而不是CHECK约束。例如,假设您想将room.capacity约束为15到100之间的值。在其他dbms中,我会写一个CHECK约束;对于MySQL,我会使用另一个表和外键约束。

create table capacities (
  capacity integer,
  primary key (capacity)
);

-- Assumes that all the values between 15 and 100
-- are valid capacities. But that's unlikely.
insert into capacities values
(15), (16), (17), (18),
-- . . .
(100);

create table room(
  capacity INTEGER,
  roomID varchar(5),
  primary key (roomID),
  foreign key (capacity) references capacities (capacity)
);

在你的情况下,我认为你坚持写作触发器。首先,表格。

create table event (
  eventID integer not null,
  attendance integer not null,
  roomID varchar(5) not null,
  primary key (eventID),
  foreign key (roomID) references room (roomID)
);

一个触发器处理INSERT语句。我看起来不太努力;可能比'22003'更好的SQLSTATE。

delimiter $$

create trigger check_capacity_on_insert
before insert on event
for each row begin
if(new.attendance) > (select capacity from room where room.roomid = roomid) then
    signal sqlstate '22003' set message_text = 'Value out of range for room.capacity';
end if; 
end;

$$

delimiter ;

另一个触发器处理UPDATE语句。

delimiter $$

create trigger check_capacity_on_update
before update on event
for each row begin
if(new.attendance) > (select capacity from room where room.roomid = roomid) then
    signal sqlstate '22003' set message_text = 'Value out of range for room.capacity';
end if; 
end;

$$

delimiter ;