1

关系 : students (1 can have N) addresses

场景:学生可以有许多记录,但只有一个关联记录必须将“ current”字段设置为“ Yes”(其他值为NULL),因此下面的查询应始终为每个学生返回一条记录。

SELECT * FROM address WHERE student_id = 5 AND current = 'Yes'

问题: 人们有时会在同一学生的 INSERT 或 UPDATE 之后将多个记录标记为“是”,所以我需要避免它。在 MySQL 中使用触发器或存储过程的最佳方法是什么?

如果 UPDATE 发生在“地址”表上,那么这应该在某处运行以将其他记录标记为 NULL:UPDATE addresses SET current = NULL WHERE student_id = IN_student_id

如果 INSERT 发生在“地址”表上,那么这应该在某处运行以将其他记录标记为 NULL:UPDATE addresses SET current = NULL WHERE student_id = IN_student_id AND id <> IN_inserted_id

提前致谢

4

1 回答 1

3

如果您需要在修改数据后自动更新某些内容,那么正确的方法是触发器。请注意,触发器可能会调用存储过程。

但是,您将无法在触发器中实现所描述的行为,因为

存储的函数或触发器不能修改已被调用函数或触发器的语句使用(用于读取或写入)的表。

实际上,“地址X是当前地址”信息应该存储在表中的一列中students,作为表的外键address。因此,保证了唯一性。

像这样的东西(在这里摆弄它):

CREATE TABLE student (
  id INT NOT NULL PRIMARY KEY,
  current_address INT,
  name VARCHAR(20)
);

CREATE TABLE address (
  id INT NOT NULL PRIMARY KEY,
  student_id INT NOT NULL,
  contents VARCHAR(50) NOT NULL,
  CONSTRAINT student_fk FOREIGN KEY student_fk_idx (student_id)
    REFERENCES student(id)  
);

ALTER TABLE student
  ADD CONSTRAINT curraddr_fk_idx
    FOREIGN KEY curraddr_fk_idx (id, current_address)
    REFERENCES address(student_id, id);

Notice this structure allows insertion of students with no "current address". This is because at least one for the two tables must allow a NULL value for their foreign key (or else we cannot add a single row in either table). If it makes more sense, let address.student_id be NULL instead, and allow an address to be nobody's address until you create the corresponding student.

于 2013-07-01T13:00:41.383 回答