Sql 检查约束-在此上下文中不允许子查询

Sql 检查约束-在此上下文中不允许子查询,sql,sql-server,sql-server-2008,tsql,constraints,Sql,Sql Server,Sql Server 2008,Tsql,Constraints,我试图添加一个检查约束,但到目前为止我失败了。解决这个问题的方法是什么: 味精1046,第15级,状态1,第6行 在此上下文中不允许子查询。仅标量表达式 是允许的 代码如下: ALTER TABLE dbo.PropertySeasonDiscount ADD CONSTRAINT [CC_PropertySeasonDiscount_MadeFrom_MadeTo] CHECK ( (SELECT COUNT(PropertySeasonDiscountId) FROM dbo.Pro

我试图添加一个检查约束,但到目前为止我失败了。解决这个问题的方法是什么:

味精1046,第15级,状态1,第6行

在此上下文中不允许子查询。仅标量表达式 是允许的

代码如下:

ALTER TABLE dbo.PropertySeasonDiscount ADD CONSTRAINT
[CC_PropertySeasonDiscount_MadeFrom_MadeTo]
CHECK (
    (SELECT COUNT(PropertySeasonDiscountId) FROM dbo.PropertySeasonDiscounts apsdeb 
        WHERE 
            (apsdeb.PropertySeasonId = PropertySeasonId) AND
            (
                (apsdeb.ValidForReservationsMadeTo >= ValidForReservationsMadeFrom AND ValidForReservationsMadeFrom >= apsdeb.ValidForReservationsMadeFrom) OR
                (apsdeb.ValidForReservationsMadeFrom <= ValidForReservationsMadeTo AND ValidForReservationsMadeTo <= apsdeb.ValidForReservationsMadeTo)
            )
    ) = 0
);

SQL Server当前不支持

正如您所发现的,在试图绕过子查询限制时,可能会涉及UDF

可供选择的约束实现策略包括触发过程和嵌入过程。前者是首选的,因为与声明性约束一样,它们无法规避


实现一个经过良好优化并处理并发问题的触发过程策略是非常重要的,但仍然是可行的。我强烈推荐这本书,第11章代码示例是Oracle,但可以很容易地移植到SQL Server。

正如其他人已经提到的,SQL Server中尚未实现这种类型的检查约束。除了触发器,还可以检查更改表设计的可能性

一种可能的替代方法包括在每一行中存储上一个间隔结束日期。有关详细信息,请参阅。强制约束很简单,但在处理表上的插入/删除/更新时会有一些复杂情况


另一种可能是,不像您现在这样存储折扣开始日期和结束日期的一行,而是存储整个系列的行,每个行对应折扣间隔的每个日期。强制约束将更加简单,但您将拥有大量的行,而不是当前表中的每一行。

@AaronBertrand我将逻辑放在UDF中,并返回该UDF的值。然后我在约束内与它进行比较,它没有抱怨。触发器会更好吗?@AaronBertrand当我创建时它并没有抱怨,但当我尝试向表中添加值时它会意外地动作。触发器可以更容易管理。此外,INSTEAD OF触发器可以防止在插入行时验证其他约束,因为如果您的检查未验证,您可以完全退出insert。您必须小心,无论走哪条路线,都要覆盖有趣的边缘情况。例如,如果一个insert语句包含两行重叠,会发生什么情况?您需要考虑表中的当前行,以及要作为一个整体添加的所有新行。dbo.PropertySeasonDiscount和dbo.PropertySeasonDiscount是同一个表吗?它是复数还是非复数,或者它们实际上是两张不同的桌子?