这不是Check constraint on date的重复,但我可能错过了另一个类似的问题。Sql - Column Check Constraint based on Date
在MS SQL,您可以创建以下限制:
ALTER TABLE [X] WITH CHECK ADD CONSTRAINT [CCCHK03_TBX] CHECK
(
[TBX_YEAR] = DATEPART(year, GetDate())
)
您可以插入记录得很好,但我无法虽然全面测试这意味着什么,会发生什么,当服务器日期剔到2017年?我的印象是,它将允许插入2017年,但它理论上将使2016年的所有记录无效。
此表是一个仅插入表,因此记录从不意味着可更新,所以这不是问题。我主要担心的是,是否可能导致由此导致的服务器稳定性问题?
我似乎无法找到与此相关的任何内容,但MS必须有一个允许这样的约束的理由。
通常我会建议创建一个插入触发器并检查,但这让我好奇。
编辑:从目的地数据的回答扩展测试:
IF (OBJECT_ID('tempdb..#CheckTest') IS NOT NULL)
DROP TABLE #CheckTest
GO
CREATE TABLE #CheckTest (MN INT)
ALTER TABLE #CheckTest WITH CHECK ADD CONSTRAINT CHK_MN CHECK (MN = DATEPART(SECOND, GETDATE()))
ALTER TABLE #CheckTest CHECK CONSTRAINT CHK_MN
GO
-- Control Test. This will fail with:
--Msg 547, Level 16, State 0, Line 12
--The INSERT statement conflicted with the CHECK constraint "CHK_MN". The conflict occurred in database "tempdb", table "dbo.#CheckTest", column 'MN'.
--The statement has been terminated.
INSERT INTO #CheckTest (MN)
VALUES (DATEPART(SECOND, DATEADD(SECOND, 5, GETDATE())))
-- Add 5 different seconds.
DECLARE @Counter int = 0;
WHILE @Counter < 5
BEGIN
INSERT INTO #CheckTest (MN)
VALUES (DATEPART(SECOND, GETDATE()))
SET @Counter += 1;
-- Delay for a second.
WAITFOR DELAY '00:00:01';
END
GO
-- Add a different second.
-- Disabling and Enabling a check will work just fine so long as the check already exists.
ALTER TABLE #CheckTest NOCHECK CONSTRAINT CHK_MN;
INSERT INTO #CheckTest (MN)
VALUES (DATEPART(SECOND, DATEADD(SECOND, 5, GETDATE())))
ALTER TABLE #CheckTest CHECK CONSTRAINT CHK_MN;
-- Control Test. This will fail with:
--Msg 547, Level 16, State 0, Line 12
--The INSERT statement conflicted with the CHECK constraint "CHK_MN". The conflict occurred in database "tempdb", table "dbo.#CheckTest", column 'MN'.
--The statement has been terminated.
INSERT INTO #CheckTest (MN)
VALUES (DATEPART(SECOND, DATEADD(SECOND, 5, GETDATE())))
GO
-- Check table contents.
SELECT * FROM #CheckTest;
GO
-- Dropping and recreating the check constraint will result in an error:
--Msg 547, Level 16, State 0, Line 37
--The ALTER TABLE statement conflicted with the CHECK constraint "CHK_MN". The conflict occurred in database "tempdb", table "dbo.#CheckTest", column 'MN'.
ALTER TABLE #CheckTest DROP CONSTRAINT CHK_MN;
ALTER TABLE #CheckTest WITH CHECK ADD CONSTRAINT CHK_MN CHECK (MN = DATEPART(SECOND, GETDATE()))
GO
DROP TABLE #CheckTest
GO
编辑2:基于测试和反馈,而这肯定是一个有趣的练习,肯定摘要
出现为100%完全有效,我肯定会建议完全从“未来证明”的观点来看,因为支票永远不会被改变。就我个人而言,我认为基于触发器的约束是最容易维护的。
当约束失败时,不会有任何系统不稳定。约束条件是为了执行我们预定义的规则 – TheGameiswar
现在我无法在文档中找到它,但最有可能的'CHECK'约束条件仅在行插入或更新(仅适用于插入或更新的行)。因此,您可以在今年插入2016年的行,并在明年插入2017年的行,但如果在2017年尝试更新2016年创建的行,则更新将失败。如果你不碰那个旧的行,它会保持原样。 –
@VladimirBaranov这很好,谢谢你的加固,我也是这么看的。如果那是我可以标记的答案。 – Storm