Sql - 基于日期的列检查约束

时间:2016-05-12 08:46:35

标签: tsql sql-server-2012

这不是Check constraint on date的副本,但我可能错过了另一个类似的问题。

在MS SQL上,您可以创建以下约束:

$("#hideshow").on('click',function() {
    if($("#adv_search").is(":visible")) { // hide div if visible
        $("#adv_search").hide();
    } else {
        $("#adv_search").show(); // if not visible show
    }
});

你可以很好地插入记录,但是我无法完全测试它的含义,但是当服务器日期到2017年时会发生什么?我的印象是它将允许2017年的插入,但它理论上会使2016年的所有记录无效。

此表是仅插入表,因此记录永远不会更新,因此不存在问题。我主要担心的是,是否可能出现服务器稳定性问题?

我似乎无法找到与此相关的任何内容,但MS必须有理由允许这样的约束。

通常情况下,我建议创建一个插入触发器并检查它,但这让我很好奇。

修改:来自目标数据的扩展测试答案:

ALTER TABLE [X] WITH CHECK ADD CONSTRAINT [CCCHK03_TBX] CHECK
(
    [TBX_YEAR] = DATEPART( year, GetDate() )
)

编辑2:摘要

根据测试和反馈,虽然它肯定是一个有趣的练习,并且肯定看起来100%完全有效,但我绝对建议不要仅仅来自未来的证据"从而永远无法改变支票的观点。我个人认为基于触发器的约束是最易维护的。

1 个答案:

答案 0 :(得分:2)

虽然我同意Vladimir Baranov的评论,但我也会考虑以下内容。

查询优化器可能会在查询数据时考虑CHECK约束(example),但如documentation中所述,这仅针对可信约束进行

  

查询优化器不考虑已定义的约束   没有检查。

当您创建指定WITH CHECK

的约束时
ALTER TABLE [X] WITH CHECK ADD CONSTRAINT [CCCHK03_TBX] CHECK ...

一年之后(在添加了与明年相对应的一些行之后),您将无法做到

ALTER TABLE [X] WITH CHECK CHECK CONSTRAINT [CCCHK03_TBX]

尝试这样做会产生错误信息

  

消息547,级别16,状态0,行... ALTER TABLE语句   与CHECK约束“CCCHK03_TBX”冲突。冲突   发生在数据库“DbName”,表“dbo.X”,列'TBX_YEAR'。

但是在sys.check_constraints系统视图

select is_not_trusted
from sys.check_constraints
where object_id = object_id('CCCHK03_TBX')

你仍会看到is_not_trusted = 0,我认为它与is_not_trusted = 1一样有效(因为某些表行不再满足检查表达式)。

我不确定,但我认为这可能会导致查询优化器生成次优计划的情况,除非它足够聪明,在某些情况下不考虑包含非确定性表达式的CHECK约束(我无法找到这些信息,如果有人能说清楚这一点,那就太好了)。我相信查询优化器在这种情况下足够聪明,不会做出可能导致产生错误查询结果的错误判断。