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.idOracle 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
的表,它有两个属性——student
和course
。 student
是一个包含唯一学生 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 为字符串提供了varchar2
。 char
用于固定长度的字符串,nobody has ever needed,使用它经常会产生错误。
@LukeWoodward - 这是一个有效的观点。为了使复合触发器工作,我们需要锁定 STUDENT 记录,该记录将过程序列化。在生产环境中并不理想,但对于家庭作业解决方案来说还可以(我一直认为这是学生入学问题的情况:D)
【参考方案1】:
最好向documentation询问:
检查约束的限制
检查约束受以下限制:
检查约束条件不能包含以下结构: 子查询和标量子查询表达式 调用用户定义的函数
【讨论】:
以上是关于MySQL的check约束中可以包含子查询吗的主要内容,如果未能解决你的问题,请参考以下文章