SQL Server如何保證可空字段中非空值唯一

2021-08-26 11:17:13 字數 3025 閱讀 1616

今天同學向我提了乙個問題,是sql server中乙個關於「如何保證可空字段中非空值唯一」的問題,我覺得蠻有意思,現記錄下來大家**下。

問題是:在乙個表裡面,有乙個允許為空的字段,空是可以重複的,但是不為空的值需要唯一。

表結構如下面**建立

create

table

test_tb

( testid

intnot

null

identity(1,1)

primary

key,

captionnvarchar(100)

null

); go

解決方案:

解決方案1:

create

unique

nonclustered

index

un_test_tb

ontest_tb(caption)

go 索引建立好了,我們來測試下效果

insert

into

test_tb(caption)

values

(null

) go

insert

into

test_tb(caption)

values

(null

) go

執行之後我們會收到下面的錯誤資訊:

訊息2601,級別14,狀態1,第1行 

不能在具有唯一索引

'un_test_tb'

的物件'dbo.test_tb'

中插入重複鍵的行。

語句已終止。

所以該解決方案是不行的。

解決方案2:

新增約束,讓sql server在插入資料的時候,先驗證下已有資料中是否有現在要插入的這個值。由於這個約束不是簡單的乙個運算,因此我們先建立乙個函式,然後再在約束中呼叫這個函式。

建立驗證邏輯函式:

create

function

[dbo].[fn_ck_test_tb_caption]()

returns

bitas

begin

if(exists(

select

1 from

test_tb

asa

where

(caption

isnot

null

)and

exists

(select1as

expr1

from

test_tb

where

(caption

isnot

null

)and

(caption=a.caption)

and(a.testid<>testid))

)) return

0 return

1 end

go 在約束中引用函式:

alter

table

test_tb

addconstraint

ck_test_tb_caption

check

(dbo.fn_ck_test_tb_caption()=1)

go 現在來測試下效果。先來測試null值

insert

into

test_tb(caption)

values

(null

) go

insert

into

test_tb(caption)

values

(null

) go

select

*from

test_tb

go 可以成功執行,而且也出了多行為null的情況。現在再來測試不為空的插入情況。

insert

into

test_tb(caption)

values

(n'aaa'

) go

insert

into

test_tb(caption)

values

(n'bbb'

) go

insert

into

test_tb(caption)

values

(n'bbb'

) go

select

*from

test_tb

go 結果是在第三條語句的時候報錯了,表中的caption欄位也有'aaa'和'bbb'了,這也正好是我們要的結果。

所以解決方案2是正確的。但是為了這麼乙個小小功能,就寫這麼長一段東西是不是太繁瑣了呢?我們來看下面的解決方案。

解決方案3:(只適用於sql server 2008)

sql server 2008中有了乙個優雅的解決方案,那就是篩選索引。篩選索引是一種經過優化的非聚集索引,尤其適用於涵蓋從定義完善的資料子集中選擇資料的查詢。篩選索引使用篩選謂詞對錶中的部分行進行索引。有了篩選索引,我們只需要寫一條語句就達到上面的效果。

create

unique

nonclustered

index

un_test_tb

ontest_tb(caption)

where

caption

isnot

null

go 再用上面的一些測試語句來測試的話,會發現完全是達到了我們的要求。

這個方案的唯一缺點就是該語句只有sql server 2008支援。。

不知道各位有沒有又優雅又適用於各個版本的sql server的解決方案,望不勝賜教。

SQL Server如何保證可空字段中非空值唯一

今天同學向我提了乙個問題,是sql server中乙個關於 如何保證可空字段中非空值唯一 的問題,我覺得蠻有意思,現記錄下來大家 下。問題是 在乙個表裡面,有乙個允許為空的字段,空是可以重複的,但是不為空的值需要唯一。表結構如下面 建立 create table test tb testid int...

SQL Server如何保證可空字段中非空值唯一

今天同學向我提了乙個問題,是sql server中乙個關於 如何保證可空字段中非空值唯一 的問題,我覺得蠻有意思,現記錄下來大家 下。問題是 在乙個表裡面,有乙個允許為空的字段,空是可以重複的,但是不為空的值需要唯一。表結構如下面 建立 create table test tb testid int...

SQL Server如何保證可空字段中非空值唯一

今天同學向我提了乙個問題,是sql server中乙個關於 如何保證可空字段中非空值唯一 的問題,我覺得蠻有意思,現記錄下來大家 下。問題是 在乙個表裡面,有乙個允許為空的字段,空是可以重複的,但是不為空的值需要唯一。表結構如下面 建立 create table test tb testid int...