Sql Server 自定義約束 實現:某列 可空,但非空值唯一不重複

dead_lee發表於2021-09-09

案例:

1、準備表

create table student(   --學生表
     id int primary key identity(1,1),  --自增主鍵
     name nvarchar(255),  --姓名
     student_no  varchar(255)   --學號
)



2、 應用場景

一個學生表,學號不能重複,但是插入資料是又不能立刻決定,而需要後期更新,所以一開始學號是空值,後期更新,所以就產生了標題中的需求。列可以為空,但是如果有值的話,值不能重複。


3、自定義約束函式

create function student_no_unique(@arg varchar(255))
returns bit
as 
begin
    declare @result bit
    if((select COUNT(*) from student stu where stu.student_no is not null and stu.student_no=@arg)>1)
        set @result = 0
    else
        set @result = 1
    return @result
end

解釋幾個地方:
1.@arg 是函式的引數,資料型別要和該列一致。
2.if條件使用 >1,而不是 >0,如果是大於0的話,只能插入空值。我猜想約束的執行過程是:插入資料 > 驗證資料是否符合約束 > 若不符合,則回滾。



4、增添約束

alter table student
add constraint student_no_unique_constraint check (dbo.student_no_unique(student_no)=1)

將要插入的資料的student_no作為引數傳遞給函式。



5、測試資料

insert into student values('name1',null)
insert into student values('name2',null)
insert into student values('name3','123456')
insert into student values('name4','123456')
insert into student values('name5','123')

執行結果為

(1 行受影響)
(1 行受影響)
(1 行受影響)

訊息 547,級別 16,狀態 0,第 4 行
INSERT 語句與 CHECK 約束"student_no_unique_constraint"衝突。該衝突發生於資料庫"OnlineStore",表"dbo.student", column 'student_no'。
語句已終止。

(1 行受影響)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4686/viewspace-2808178/,如需轉載,請註明出處,否則將追究法律責任。

相關文章