如何为外键添加约束,使其取决于来自表 FK 的列的值?

问题描述 投票:0回答:2

我需要设置约束,以便仅当该表中的另一列具有特定值时该表才接受来自其他表的外键。

数据库相当复杂,但让我举个例子:

餐桌福:

Foo_id | Foo_value | Another values...
   1   |  "GOOD"   |
   2   |  "BAD"    |
   3   |  "GOOD"   |

桌栏:

Bar_id | Foo_id(FK) | Another values...
   1   |     1      |
   2   |     1      |
   3   |     3      |

如您所见,Bar 应该只接受来自 Foo 的接受 id,其中 Foo_Value 为“GOOD”。

我尝试添加检查约束,但它不接受 WHERE 语句,因此我无法访问 Foo_Value。我尝试搜索,但我找不到任何东西,或者我对此的解释是错误的。

mysql database constraints
2个回答
2
投票

可能唯一的方法是使用

trigger
(用于插入/更新):

create trigger chk_bar before insert on bar  /* before update */
for each row 
begin  
   if  not exists (SELECT 1 FROM foo 
                  WHERE Foo_value = 'GOOD' AND foo_id = new.foo_id)  then
       SIGNAL SQLSTATE '45000'   
       SET MESSAGE_TEXT = 'Invalid FK';
   end if; 
end; 

Rextester 演示

请记住在更新

foo
->
GOOD
时在
BAD
上添加另一个触发器,或删除该触发器,以检查引用完整性。


2
投票

MySQL 直到 8.0.16 版本才实现 CHECK 约束。

仅当外键包含您的 Foo_value 列时,您才可以使用外键强制执行您的规则。这意味着您的父表中需要一个额外的 KEY。

ALTER TABLE Foo ADD UNIQUE KEY (Foo_id, Foo_value);

ALTER TABLE Bar ADD COLUMN Foo_value VARCHAR(4) DEFAULT 'GOOD',
    ADD FOREIGN KEY (Foo_id, Foo_value) REFERENCES Foo (Foo_id, Foo_value);

由于无法使用 CHECK 约束,因此必须使用触发器来确保 Bar.Foo_value 为“GOOD”:

CREATE TRIGGER BarInsertFooValueGood BEFORE INSERT ON Bar FOR EACH ROW
    SET Foo_value = 'GOOD';

CREATE TRIGGER BarUpdateFooValueGood BEFORE UPDATE ON Bar FOR EACH ROW
    SET Foo_value = 'GOOD';
© www.soinside.com 2019 - 2024. All rights reserved.