MySQL:约束一组列,这样至少有一列不是NULL

时间:2011-04-08 11:39:22

标签: mysql constraints

我想要一个包含两列的SQL表。一个是另一个表的键,另一个是字符串文字。这个想法是可以准确输入电话号码(在这种情况下使用电话簿表中的ID)或作为通配符(使用字符串文字)。

这意味着表中的一列将保存一个值,另一列将保留NULL。

是否可以以一个列必须具有值,另一个必须为NULL的方式约束表?如果两列都为NULL或两者都有值,则该行无效。

我有一种感觉,MySQL无法做到这一点(因为它似乎没有一个全面的工具箱,当涉及约束),但它可以没有伤害问。

4 个答案:

答案 0 :(得分:4)

我不知道如何强制实施这样的约束。

作为一种变通方法,您可以考虑使用两个不同的列:如果您有一列数据 - 包含电话簿ID或字符串文字,另一列包含数据类型 - “确切”或“通配符” - ,您可以为两列设置NOT NULL约束。一个明显的缺点是你不能再对电话簿表有一个FK约束。

答案 1 :(得分:2)

您可以在插入之前使触发器运行,以检查值并确定插入或更新是否应该发生。有关如何创建此类触发器的一个很好的示例,请访问:https://dba.stackexchange.com/questions/43284/two-nullable-columns-one-required-to-have-value

答案 2 :(得分:0)

以下触发器为我工作:

CREATE TRIGGER tgr_OrgFeeOwnerInsert
    BEFORE INSERT
    ON OrganisationFee
    FOR EACH ROW
BEGIN
    IF (SELECT ((new.fieldA IS NULL) + (new.fieldB IS NULL) + (new.fieldC IS NULL)) <> 2)
    THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'my error message';
    END IF;
END;

CREATE TRIGGER tgr_OrgFeeOwnerUpdate
    BEFORE INSERT
    ON OrganisationFee
    FOR EACH ROW
BEGIN
    IF (SELECT ((new.fieldA IS NULL) + (new.fieldB IS NULL) + (new.fieldC IS NULL)) <> 2)
    THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'my error message';
    END IF;
END;

答案 3 :(得分:0)

由于GENERATED列是一回事,所以这是可能的。

CREATE TABLE `test_multiple_not_null` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `idOne` int(11) DEFAULT NULL,
  `idTwo` int(11) DEFAULT NULL,
  `not_null_constrain` int(11) GENERATED ALWAYS AS (coalesce(`idOne`,`idTwo`)) VIRTUAL NOT NULL,
  PRIMARY KEY (`id`)
);

由于每次插入一行,生成的列都必须运行才能查看它是否满足NOT NULL约束,如果它违反此限制,它将以1048: Column 'not_null_constrain' cannot be null进行答复。