不允许 SQL Server 约束子查询

Posted

技术标签:

【中文标题】不允许 SQL Server 约束子查询【英文标题】:SQL Server constraint subqueries not allowed 【发布时间】:2017-04-24 20:37:25 【问题描述】:

我有以下 3 个表:

    员工 部门 employees_departments(员工和部门之间的连接表以及附加信息)

该部门还有一个列manager_id,它是employees 表的外键(一个部门有一个来自employees 表的经理)。

我有一个要求,我必须设置一个约束条件,即经理下的任何员工的薪水都不能高于经理。

我尝试解决这个问题:

ALTER TABLE employees 
    ADD CONSTRAINT check_salary 
        CHECK (salary > (SELECT salary
                         FROM employees e2
                         INNER JOIN employees_departments ed2 ON e2.id_employee = ed2.id_employee
                         INNER JOIN departments d2 ON d2.id_department = ed2.id_department
                         WHERE e2.id_employee != manager_id (but how do I get the manager id)
                           AND d2.id_departament = manager_department_id (again don't know how to do get it)
)

我收到不允许子查询的错误。这甚至可以在约束条件下做到吗?如何在普通查询中建模?

我还必须补充一点,我几乎没有使用 SQL Server 的经验,而且总体上很少使用 SQL。

非常感谢任何帮助!

【问题讨论】:

您不能在检查约束中直接使用子查询。您可以使用标量 UDF,但这些检查约束有很多问题。 注意,你真正想要的是外键约束。也就是说,要将“查询”放入检查中,您可以编写一个包含查询并输出标量值的函数,然后在检查约束中使用该函数。 【参考方案1】:

即使您可以做到这一点,当数据发生更改以致某些行的约束失效(例如经理减薪)时,您期望会发生什么?听起来这可能是一个糟糕的问题/业务规则描述。

如果它纯粹是插入/更新时间检查,则使用代码或(yuk)触发器。

另一种选择可能是使用可更新视图,该视图仅选择收入低于其经理的员工(即所有人)。通过在那里更新和插入,您可能能够使其在每种情况下都能正常工作,因为如果视图中的插入/更新不满足视图的标准,它将拒绝它。

阅读视图,特别是 WITH CHECK OPTION

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql

【讨论】:

以上是关于不允许 SQL Server 约束子查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 之 子查询与嵌套查询

SQL Server 触发器:子查询返回超过 1 个值

sqlserver 表 无法更新和删除 子查询返回的值不止一个

在SQL Server的子查询视图内联函数等数据库对象中,不应该单独使用ORDER BY语句

在SQL Server中为什么不建议使用Not In子查询

SQL 中的错误 - 当子查询跟随 =、!=、<、<=、>、>= 或当子查询用作表达式时,这是不允许的