2017-08-10 55 views
0

我有類似結構的這種預先存在的SQL Server表:SQL約束 - 值的獨特組合,只有當另一列是空

[Username] [Gateway] [Code] [ActiveTo] [OrgId] 
------------------------------------------------------ 
user1  gateway  50  Null  100 
user1  gateway  50  Null  101 
user2  gateway2  51  Null  102 
user3  gateway3  52  12/08/17  103 

此表已有用戶名重複的組合,網關和代碼。我想添加一個約束,以便添加的任何新用戶都有[用戶名],[網關]和[代碼]的唯一組合,但會忽略兩個預先存在的重複項,例如上面的兩個user1條目(不會忽略匹配的新條目預先存在的)。

但我只希望在副本的[ActiveTo]值爲空(默認情況下,新條目的默認值爲ActiveTo)時應用此選項。

因此,將約束應用於上述表格將忽略兩個user1重複項。

然後添加一行[user2],[gateway2],[52],[Null],[104]就沒問題。

然後添加一行[user2],[gateway2],[51],[Null],[105]會引發錯誤。

但是,然後添加行[user3],[gateway3],[52],[空],[106]會很好。

任何想法?

+0

我們是否可以擴展表?約束通常應該可以在任何時候重新應用,所以「時間」要求(現有行)將更好地建模爲一個新的列,明確標記行不予考慮(一個非常糟糕的替代方法是將其基於OrgId,如果我們保證它會一直增長,並且我們知道在應用約束條件時要使用的值) –

回答

1

你可以使用一個唯一索引:

CREATE UNIQUE INDEX table_name_index_1 on table_name(Username, Gateway, Code) WHERE ActiveTo IS NOT NULL 
+0

已經問過關於SQL Server而不是Oracle的問題。 –

+1

我認爲只能用於oracle。用sql-server,我得到錯誤'關鍵字'CASE'附近的語法不正確。' – Freddie93

+0

嘗試在table_name(用戶名,網關,代碼)上CREATE UNIQUE INDEX table_name_index_1 WHERE ActiveTo IS NOT NULL –