2014-09-04 78 views
1

我已經繼承了一個數據庫設計,它有很多軟刪除標誌。唯一約束(與另一列的某個值相結合)

在下面的代碼中,我試圖找出是否存在一個約束條件,允許「一個非軟刪除員工的唯一EmployeeNumber」。

在這個模擬的例子中,EmployeeNumber的可以被重用,但是一次只能有一個EmployeeNumber被非軟刪除。

我試圖約束(註釋如下),但知道他們不會工作。

任何想法?

在下面的例子中,只有'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'會失敗。

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE') 
BEGIN 
DROP TABLE [dbo].[Employee] 
END 
GO 



CREATE TABLE [dbo].[Employee] ( 

    [EmployeeUUID] [uniqueidentifier] NOT NULL, 
    [EmployeeNumber] [varchar](10) NOT NULL, 
    [LastName] [varchar](64) NOT NULL, 
    [FirstName] [varchar](64) NOT NULL, 
    [CreateDate] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    [HireDate] [datetime] NOT NULL, 
    IsSoftDeleted bit not null default 0 
    ) 

GO 

ALTER TABLE [dbo].[Employee] ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeUUID) 
GO 

/* Does not work for fairly obvious reasons */ 
/* 
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_EmployeeNumber_Unique UNIQUE (EmployeeNumber) 
*/ 
GO 

/* Does not work because it only allows one IsSoftDeleted=1 rowo, not multiples */ 
/* 
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_EmployeeNumber_Unique UNIQUE (EmployeeNumber, [IsSoftDeleted]) 
*/ 
GO 



INSERT INTO [dbo].[Employee] ([EmployeeUUID] , [EmployeeNumber] , [LastName] , [FirstName] , [HireDate] , [IsSoftDeleted]) 
Select 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA' , '1111111111' , 'Jones' , 'Mary' , '01/01/2001' , 0 

INSERT INTO [dbo].[Employee] ([EmployeeUUID] , [EmployeeNumber] , [LastName] , [FirstName] , [HireDate] , [IsSoftDeleted]) 
Select 'BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBBBBBB' , '1111111111' , 'Smith' , 'John' , '02/02/2002' , 1 

INSERT INTO [dbo].[Employee] ([EmployeeUUID] , [EmployeeNumber] , [LastName] , [FirstName] , [HireDate] , [IsSoftDeleted]) 
Select 'CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC' , '1111111111' , 'Apple' , 'Andy' , '03/03/2003' , 1 

INSERT INTO [dbo].[Employee] ([EmployeeUUID] , [EmployeeNumber] , [LastName] , [FirstName] , [HireDate] , [IsSoftDeleted]) 
Select 'DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD' , '1111111111' , 'Banana' , 'Ben' , '03/03/2003' , 1 


/* This would be the only row that would fail to insert, because of the duplicate ([EmployeeNumber]='1111111111' and [IsSoftDeleted]='1') */ 
INSERT INTO [dbo].[Employee] ([EmployeeUUID] , [EmployeeNumber] , [LastName] , [FirstName] , [HireDate] , [IsSoftDeleted]) 
Select 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF' , '1111111111' , 'Banana' , 'Ben' , '03/03/2003' , 0 



Select * from [dbo].[Employee] 
+0

你能用一個觸發器而不是一個約束來解決這個問題嗎? – 2014-09-04 19:27:27

+0

所有選項都在表格.........(在db級別)。 – granadaCoder 2014-09-04 19:28:23

+0

那麼一次只能有一行IsSoftDeleted在整個表中?這意味着不是每個員工,而是全部只有1個?如果是這樣的話,那麼我會同意觸發器會讓這件事更容易處理。 – 2014-09-04 19:49:54

回答

3

你用過濾後的唯一索引來做到這一點。

create unique index UX_Employee_EmployeeNumber 
    on dbo.Employee(EmployeeNumber) 
    where IsSoftDeleted = 0