MySQL的check约束中可以包含子查询吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL的check约束中可以包含子查询吗相关的知识,希望对你有一定的参考价值。

参考技术A mysql试图中是不可以使用子查询的,你可以把子查询 建立成一个试图嘛, 如: CREATE VIEW View_bb as select id from bb; 然后再 建立上面试图中 调用该试图,如: select a.* from aa a inner join View_bb b on a.id=b.id

Oracle SQL - 我可以在 DDL 的 CHECK 约束中使用子查询吗?

【中文标题】Oracle SQL - 我可以在 DDL 的 CHECK 约束中使用子查询吗?【英文标题】:Oracle SQL - Can I use sub-query in a CHECK constraint in DDL? 【发布时间】:2020-10-23 16:13:54 【问题描述】:

我正在使用 Oracle SQL,我想知道在创建新表时是否可以在 CHECK 约束中使用子查询。请考虑以下示例:

假设我想创建一个名为EnrollsIn 的表,它有两个属性——studentcoursestudent 是一个包含唯一学生 ID 的字符串,course 属性包含一个课程代码字符串。

CREATE TABLE EnrollsIn (
   student char(8) PRIMARY KEY,
   course char(7),
   -- Insert constraint here (Constraint is written below)
);

INSERT INTO EnrollsIn VALUE ('12345678', 'COMP200');
INSERT INTO EnrollsIn VALUE ('12345678', 'COMP300');
INSERT INTO EnrollsIn VALUE ('12345678', 'COMP400');
INSERT INTO EnrollsIn VALUE ('12345678', 'MATH100');  -- This violates the constraint written below!

现在,我希望此表有一个约束,即单个学生最多只能注册 3 门课程。换句话说,对于每个student,以下查询的值应该始终为enrollCount

-- I want the value "enrollCount" always <= 3 for all students
SELECT student, count(*) as enrollCount FROM EnrollsIn GROUP BY student;

CERATE TABLE EnrollsIn 语句中定义 CHECK 约束时,我可以使用这个子查询吗?如果是这样,我该如何定义这个约束?

【问题讨论】:

唉,你不能在检查约束中这样做。这种结构称为 SQL 断言,Oracle 或任何其他主要数据库尚不支持它,尽管已经采取措施增加支持。 实现此要求的一种方法是使用复合触发器:有关示例,请参见 this answer。或者,您可以创建一个带有检查约束的物化视图:there is an example here。 @APC:我不确定复合触发方法是否适用。如果您在两个并发会话中的每一个中为同一个学生插入两行,触发器将永远不会检测到问题,因为它只会看到每个会话中的两行,而不是所有四行,所以你肯定会得到那个学生注册了四门课程? 顺便提一下,Oracle 为字符串提供了varchar2char 用于固定长度的字符串,nobody has ever needed,使用它经常会产生错误。 @LukeWoodward - 这是一个有效的观点。为了使复合触发器工作,我们需要锁定 STUDENT 记录,该记录将过程序列化。在生产环境中并不理想,但对于家庭作业解决方案来说还可以(我一直认为这是学生入学问题的情况:D) 【参考方案1】:

最好向documentation询问:

检查约束的限制

检查约束受以下限制:

检查约束条件不能包含以下结构: 子查询和标量子查询表达式 调用用户定义的函数

【讨论】:

以上是关于MySQL的check约束中可以包含子查询吗的主要内容,如果未能解决你的问题,请参考以下文章

哪些 SQL 数据库支持 CHECK 约束中的子查询?

检查约束内的子查询

mysql非空字段不允许插入空字符串怎么处理?

MySQL的约束多表查询子查询

MySQL学习笔记

Mysql2外键约束,多表/子查询,事务