忽略特定重复值的唯一键设置

时间:2021-05-28 16:25:29

标签: sql sql-server tsql

我有一个 MVC 代码正在运行,它需要一个设置,其中没有两个相同的 Employeeid 可以保持活动状态。

需求说明>> 重复的EmployeeID 不能同时保持活动状态,但如果您删除该EmployeeID,则多个已删除的条目可以保留在那里。即

员工 ID |已删除


    Fri May 28 16:21:16 UTC 2021 : HTTP Method: GET, Resource Path: /
    Fri May 28 16:21:16 UTC 2021 : Method request path: {}
    Fri May 28 16:21:16 UTC 2021 : Method request query string: {}
    Fri May 28 16:21:16 UTC 2021 : Method request headers: {}
    Fri May 28 16:21:16 UTC 2021 : Method request body before transformations: 
    Fri May 28 16:21:16 UTC 2021 : Execution failed due to configuration error: Invalid endpoint address
    Fri May 28 16:21:16 UTC 2021 : Method completed with status: 500

请注意,在应用场景中,我没有运行带有 'isdeleted' = 1 标志的插入,而只是删除活动记录并将 'isDeleted' 的值从 0 更新为 1。

采取的步骤 >> 我尝试在数据库中对 (EmployeeID , IsDeleted) 的组合进行唯一约束,但如上所述,当我尝试将“isDeleted”标志从 0 更新为 1 时,它会引发错误(原因 - 那里已经是一个具有相同 EmployeeID 和 Isdeleted 为 1 的条目)。

要完成的结果 >> 'IsDeleted' 应该成功地从 0 更新为 1。

现在收到的结果 >> 由于唯一约束更新失败。

请帮忙!

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要一个过滤的唯一索引:

create unique index unq_t_employeeId_isdeleted_0 on t(employeeId)
   where isDeleted = 0;

Here 是一个 db<>fiddle。

答案 1 :(得分:0)

您的唯一约束将不起作用,因为唯一允许的值是 (EmployeeId, 0) 和 (EmployeeId, 1),没有重复项。

要解决您的问题,您可以创建一个 FUNCTION 并将其与 CHECK 一起使用。

CREATE  FUNCTION CountActive(
    @EmployeeId INT
)
RETURNS TINYINT
AS
BEGIN
    RETURN  (
        SELECT  COUNT(1)
        FROM    [dbo].[Employee]
        WHERE [EmployeeId] = @EmployeeId
            AND [IsDeleted] = 0
    );
END;

并且,在您的表上添加一个 CHECK 约束:

CHECK([CountActive]([EmployeeId]) <= 1)

它最多允许一个活动的 EmployeeId