【问题标题】:SQL constraint with UNIQUE and CHECK带有 UNIQUE 和 CHECK 的 SQL 约束
【发布时间】:2020-02-28 09:42:36
【问题描述】:

我的目标是防止在“地址”与“is_principal”具有相同“account_id”的情况下发生 INSERT(我只需要一个帐户的 is_principal 地址)。

有没有办法使用 UNIQUE 和 CHECK 创建 SQL 约束?

我试试这个:

ALTER TABLE address ADD CONSTRAINT fk_account_adresses2_idx UNIQUE(account_id, CHECK (is_principal >= 1)); 

错误:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHECK (is_principal >= 1))' at line 1 (SQL: ALTER TABLE address ADD CONSTRAINT fk_compte_adresses2_idx UNIQUE(account_id, CHECK (is_principal >= 1));)

谢谢。

编辑:

插入应该工作的例子:

insert into `address` (`address`, `account_id`, `is_principal`) values (address 1, 1, 1);
insert into `address` (`address`, `account_id`, `is_principal`) values (address 2, 1, 0);
insert into `address` (`address`, `account_id`, `is_principal`) values (address 3, 1, 0);

插入应该失败的例子:

insert into `address` (`address`, `account_id`, `is_principal`) values (address 1, 1, 1);
insert into `address` (`address`, `account_id`, `is_principal`) values (address 2, 1, 1);

【问题讨论】:

  • 我猜你需要单独的 UNIQUE 和 CHECK 约束。
  • 我只想要一个帐户的 is_principal 地址 您是否希望允许任意数量的具有相同 account_idis_principal 的记录被视为 FALSE(NULL,零,空字符串)并且只有一个 is_principal 被视为 TRUE(非空字符串或非零数字)?
  • 没错@Akina

标签: mysql constraints unique ddl


【解决方案1】:
ALTER TABLE address 
ADD COLUMN for_check INT AS (CASE WHEN is_principal 
                                  THEN account_id 
                                  END) VIRTUAL,
ADD CONSTRAINT check_only_one_principal_address 
    UNIQUE INDEX (for_check);

fiddle

在另一种情况下,生成的列为具有is_principal = TRUENULL 的记录生成account_id 值。在 UNIQUE 约束中不检查 NULL。

虚拟生成的列不需要额外的磁盘空间。

适用于从 5.7.8 版本开始的 MySQL(如果您不指定 VIRTUAL 并使用静态、STORED 列,则从 5.7.6 开始)。

【讨论】:

  • 是的!谢谢@Akina
【解决方案2】:

使用逗号分隔语法:

ALTER TABLE address ADD CONSTRAINT fk_account_adresses2_idx UNIQUE(account_id),
                    ADD CHECK (is_principal >= 1);

附带说明,MySQL 8+ 之前的版本中的检查约束将被忽略。因此,如果您使用的是早期版本的 MySQL,那么检查约束将被忽略。

【讨论】:

  • 您好蒂姆,您的代码正在为“account_id”创建一个唯一约束,但我希望一个帐户能够保存多个地址。你的代码给了我这个错误:SQL Integrity constraint violation: 1062 Duplicate entry '1' for key 'fk_compte_adresses2_idx'
  • 然后将示例数据添加到您的问题中。
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多