Sql server SQL Server表在给定时间内只有一条活动记录

Sql server SQL Server表在给定时间内只有一条活动记录,sql-server,non-clustered-index,Sql Server,Non Clustered Index,我有一个SQL Server 2016表,其中在任何给定时间只有一条记录处于活动状态。它将有积垢操作 我试图在该表上创建一个唯一的非聚集索引,以便它在任何时候都只有一条活动记录。活动记录的标准是今天的日期是否介于StartDate和StopDate之间。ID是唯一的密钥。对于其余部分,我不确定我的语法和策略是否正确 以下是我的SQL: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[GWFO_Flash

我有一个SQL Server 2016表,其中在任何给定时间只有一条记录处于活动状态。它将有积垢操作

我试图在该表上创建一个唯一的非聚集索引,以便它在任何时候都只有一条活动记录。活动记录的标准是今天的日期是否介于
StartDate
StopDate
之间。ID是唯一的密钥。对于其余部分,我不确定我的语法和策略是否正确

以下是我的SQL:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[GWFO_FlashNewsItem]
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [Title] [VARCHAR](150) NOT NULL,
    [NavigateToURL] [VARCHAR](250) NULL,
    [StartDate] [SMALLDATETIME] NOT NULL,
    [StopDate] [SMALLDATETIME] NULL,
    [Active] [BIT] NOT Null,
    [UpdateSOEID] [CHAR](7) NULL,
    [UpdateDate] [SMALLDATETIME] NULL,

    CONSTRAINT [PK_GWFO_FlashNewsItem] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE UNIQUE NONCLUSTERED INDEX uixf_GWFO_FlashNews_Active_filtered
ON GWFO_FlashNewsItem (Active)
INCLUDE (ID, Title) 
WHERE Active = 1

从上下文来看,似乎您正试图限制插入或更新包含不在当前日期内的日期范围的记录。为了做到这一点,你可以使用触发器。如果日期范围不符合激活条件,则可以引发错误并阻止插入或更新

我还尝试创建了一个检查约束,该约束同样有效:

CREATE TABLE [dbo].[test]
(
    [d1] [DATETIME] NULL,
    [d2] [DATETIME] NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[test] WITH CHECK 
    ADD CONSTRAINT [CK_test] CHECK ((GETDATE() >= [d1] AND GETDATE() <= [d2]))
GO

ALTER TABLE [dbo].[test] CHECK CONSTRAINT [CK_test]
GO
抛出此错误:

Msg 547,第16级,状态0,第24行
INSERT语句与检查约束“CK_test”冲突。冲突发生在数据库“SysproSupport”表“dbo.test”中。声明已终止


最终,您似乎应该能够控制前端处理的记录类型。如果有一个应用程序或数据输入接口正在处理数据,则可以将这些约束放入其中。将此实现为约束或触发器将确保即使管理员也无法在不禁用数据的情况下清理数据。

我认为您需要更清楚地确定首先需要什么。例如,您有一个设置了活动位的记录,StartDate是今天0:00:00,StopDate是今天23:59:59,一切正常

直到23:59:59,您的条件(仅当GetDate()介于StartDate和StopDate之间时才应设置活动位)不再有效。你认为那一秒会发生什么?那个位神奇地变成了0,仅仅是它自己


另一个问题是,即使满足条件,您的需求是否允许将活动记录设置为0?如果这个问题的答案是“否”,那么您的活动位不是单独的字段,而只是StartDate和StopDate的一个[非确定性]函数,您唯一关心的是不允许重叠的时间间隔。

我很有信心您无法基于当前日期创建过滤索引。(我无法检查,但这毫无意义,因为索引中的行将永远在变化)。@Larnu,这是正确的,仅限确定性子句。您可以建议其他解决方案吗?例如,添加另一位列“活动”,并在插入/更新操作期间相应地设置它。并对其应用索引?为什么要将smalldatetime转换为字符串以进行比较?除此之外,如果你不努力工作,那就是白费力气。只需比较smalldatetime值。对于手头的任务,为什么需要筛选索引?只需使用排序逻辑创建一个具有top 1的视图。触发器将允许您在每次更新表时检查所需的任何条件。它将为您的建议提供一个机会
INSERT INTO test SELECT '1/1/2000', '1/1/2001'