MySQL:约束一组列,使至少一个列不为 NULL

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

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

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

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

我有一种感觉,MySQL 无法做到这一点(因为它在约束方面似乎没有一个全面的工具箱),但问一下也无妨。

mysql constraints
5个回答
6
投票

自从

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


4
投票

我不知道有什么方法可以强制执行这样的限制。

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


2
投票

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


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 UPDATE
    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;

0
投票

只需一行代码

您可以使用 CHECK 约束来确保其中一列不为空。

check (column1 is not null or column2 is not null)

在 MySQL 中测试的完整示例:

create table Clients (
    id int primary key,
    name varchar(100) not null,
    email varchar(100),
    telephone varchar(20),
    constraint Clients_CHK_EmailTelefone check (email is not null or telephone is not null)
);
© www.soinside.com 2019 - 2024. All rights reserved.