【问题标题】:Can't run NOCHECK CONSTRAINT on mysql - SQL syntax error无法在 mysql 上运行 NOCHECK CONSTRAINT - SQL 语法错误
【发布时间】:2021-10-31 19:09:09
【问题描述】:

我创建了一个名为Students 的表。 它有 4 个字段:姓名、年龄、班级、年份。

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| Name  | varchar(50) | NO   | PRI | NULL    |       |
| Age   | smallint    | YES  |     | 18      |       |
| Class | varchar(10) | YES  |     | NULL    |       |
| Years | smallint    | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

我在Years 字段上添加了一个检查约束,这意味着Years 列中的值不能低于3。 我是这样做的

mysql> alter table Students
    -> add constraint CK_Years check (Years >= 3);

我的目标是插入一条记录的查询,该记录的 Years 值为 2,这意味着它不会通过 CK_Years 检查约束。

我想在不更改约束或插入语句中的字段的情况下这样做。 有可能吗?

mysql> insert into Students
    -> (Name, Age, Class, Years) values ("Eric","25","110","2");

我试过了:

mysql> alter table Students
    -> NOCHECK CONSTRAINT CK_Years;
ERROR 1064 (42000): 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 'NOCHECK CONSTRAINT CK_Years' at line 2

我只想为这个插入禁用它,然后将它带回来(检查约束)。

如您所见,我收到了这个错误。 我试着用几种方式来写它。机智'CK_Years'CK_Years

`CK_Years`

所有这些方法都出现相同的错误。

我已验证我在表中有约束:

mysql> select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    -> where table_name='Students';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def                | School          | PRIMARY         | School     | Students   | PRIMARY KEY     | YES      |
| def                | School          | CK_Years        | School     | Students   | CHECK           | YES      |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+

那么如何在不更改约束或插入语句中的字段的情况下做到这一点? 如何修复语法错误? 又是什么原因呢?

谢谢。

【问题讨论】:

  • 你不能禁用它,那为什么你想给它加 2 的时候有一个 >=3 约束呢?
  • @nbk 进行练习。我正在研究 SQL rn,我想看看是否可以绕过约束并临时禁用约束。
  • 你只能禁用外键和键检查而已
  • MySQL 不支持 NOCHECK。它在 MS SQL Server 上的 T-SQL 中可用。
  • @nbk 是的,在这里我想禁用密钥检查,对吗? CK_Years 是关键检查,或者至少我认为是这样。 (如果我错了,请纠正我)

标签: mysql sql database constraints sql-insert


【解决方案1】:

MySQL 确实支持更改检查约束的语法,因此不强制执行,但它与 Microsoft SQL Server 语法不同。

mysql> alter table students alter check CK_Years NOT ENFORCED;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into students values ('Eric',25,'110',2);
Query OK, 1 row affected (0.00 sec)

记录在这里:https://dev.mysql.com/doc/refman/8.0/en/alter-table.html

如果您重新启用它,则会强制执行该约束,如果您插入了任何违反该约束的行,那么在尝试重新启用它时会出现错误。

mysql> alter table students alter check CK_Years ENFORCED;
ERROR 3819 (HY000): Check constraint 'CK_Years' is violated.

此外,一旦您使约束不强制执行,它将对所有客户端生效,而不仅仅是一个 INSERT。

所以我认为你不能用 CHECK 约束做你想做的事。您可能必须编写一个触发器,在该列上强制执行类似条件,但具有有条件强制执行它的逻辑。

或者做大多数开发人员在 MySQL 支持 CHECK 约束之前所做的事情:在执行 INSERT 之前在客户端应用程序中强制执行它。然后你可以应用任何你想要的条件。

【讨论】:

  • 是的,但我仍然看不到在正常情况下允许这样做的意义。可能是出于维护目的,当数据库关闭时,或者在 idk 中插入数百万行。
  • 我猜您是否需要插入一些不立即符合 CHECK 约束的数据(不管是一行还是多行),但您计划更新行在重新启用它之前满足约束的有效值。
  • @TheImpaler:这是一篇描述在 Microsoft SQL Server 中使用 NOCHECK 的文章:database.guide/… 您可能会发现必须加载数据的场景,即使它们不满足约束条件。正如您所评论的,这无法支持数据完整性,但我们都经历过这样的情况:我们必须在满足我们的学术自豪感与满足老板或支付账单的客户之间做出选择。
  • “……谁在付账。” -- 取点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
相关资源
最近更新 更多