成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

數據庫 SQL Server
文章闡述了編者同學遇到的SQL Server中一個關于“如何保證可空字段中非空值唯一”的問題,以及編者給出的幾種解決方式。

今天同學向我提了一個問題,是SQL Server中一個關于“如何保證可空字段中非空值唯一”的問題,我覺得蠻有意思,現(xiàn)記錄下來大家探討下。

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

表結構如下面代碼創(chuàng)建

  1. CREATE TABLE test_tb  
  2. (  
  3.     TestId int not null identity(1,1) primary key,  
  4.     Caption nvarchar(100) null 
  5. );  
  6. GO  
 

#p#

解決方案:

解決方案1:

對于這個問題,大家的第一個想法可能是:在Caption這個字段上面加一個唯一鍵不就可以了嗎?好,我們按著這個思路做下去,先創(chuàng)建唯一索引。

  1. CREATE UNIQUE NONCLUSTERED INDEX un_test_tb   
  2. ON test_tb(Caption)  
  3. GO  

 索引創(chuàng)建好了,我們來測試下效果

  1. INSERT INTO test_tb (Caption)  
  2. VALUES (null)  
  3. GO  
  4. INSERT INTO test_tb (Caption)  
  5. VALUES (null)  
  6. GO  

 運行之后我們會收到下面的錯誤信息:

  1. 消息 2601,級別 14,狀態(tài) 1,第 1 行  
  2. 不能在具有唯一索引 'un_test_tb' 的對象 'dbo.test_tb' 中插入重復鍵的行。  
  3. 語句已終止。  

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

解決方案2:

添加約束,讓SQL Server在插入數據的時候,先驗證下已有數據中是否有現(xiàn)在要插入的這個值。由于這個約束不是簡單的一個運算,因此我們先創(chuàng)建一個函數,然后再在約束中調用這個函數。

創(chuàng)建驗證邏輯函數:

  1. CREATE FUNCTION [dbo].[fn_CK_test_tb_Caption]()  
  2. RETURNS BIT 
  3. AS   
  4. BEGIN 
  5.     IF(EXISTS(  
  6.     SELECT    1  
  7.     FROM test_tb AS a  
  8.     WHERE (Caption IS NOT NULLAND EXISTS  
  9.       (SELECT 1 AS Expr1  
  10.         FROM test_tb  
  11.         WHERE (Caption IS NOT NULLAND (Caption = a.Caption) AND (a.TestId <> TestId))  
  12.      ))  
  13.         RETURN 0  
  14.       
  15.     RETURN 1  
  16. END 
  17. GO  

 在約束中引用函數:

  1. ALTER TABLE test_tb  
  2. ADD CONSTRAINT CK_test_tb_Caption CHECK (dbo.fn_CK_test_tb_Caption() = 1)  
  3. GO  
  4.  

 現(xiàn)在來測試下效果。先來測試NULL值
 

  1. INSERT INTO test_tb (Caption)  
  2. VALUES (null)  
  3. GO  
  4. INSERT INTO test_tb (Caption)  
  5. VALUES (null)  
  6. GO  
  7. SELECT * FROM test_tb  
  8. GO  

  可以成功運行,而且也出了多行為NULL的情況。現(xiàn)在再來測試不為空的插入情況。

  1. INSERT INTO test_tb (Caption)  
  2. VALUES (N'AAA')  
  3. GO  
  4. INSERT INTO test_tb (Caption)  
  5. VALUES (N'BBB')  
  6. GO  
  7. INSERT INTO test_tb (Caption)  
  8. VALUES (N'BBB')  
  9. GO  
  10. SELECT * FROM test_tb  
  11. GO  

 結果是在第三條語句的時候報錯了,表中的Caption字段也有'AAA'和'BBB'了,這也正好是我們要的結果。

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

  解決方案3:(只適用于SQL Server 2008)

 SQL Server 2008中有了一個優(yōu)雅的解決方案,那就是篩選索引。篩選索引是一種經過優(yōu)化的非聚集索引,尤其適用于涵蓋從定義完善的數據子集中選擇數據的查詢。篩選索引使用篩選謂詞對表中的部分行進行索引。有了篩選索引,我們只需要寫一條語句就達到上面的效果。
 

  1. CREATE UNIQUE NONCLUSTERED INDEX un_test_tb   
  2. ON test_tb(Caption)  
  3. WHERE Caption is not null 
  4. GO  

 再用上面的一些測試語句來測試的話,會發(fā)現(xiàn)完全是達到了我們的要求。

這個方案的唯一缺點就是該語句只有SQL Server 2008支持。。

不知道各位有沒有又優(yōu)雅又適用于各個版本的SQL Server的解決方案,望不勝賜教。

【編輯推薦】

  1. SQL Server 2000刪除實戰(zhàn)演習
  2. SQL Server存儲過程的命名標準如何進行?
  3. 卸載SQL Server 2005組件的正確順序
  4. 對SQL Server字符串數據類型的具體描述
  5. SQL Server數據類型的種類與應用


 

責任編輯:艾婧 來源: 博客園
相關推薦

2010-07-06 10:25:16

SQL Server空

2009-08-25 17:52:01

C#可空值類型

2017-01-13 23:06:45

swiftios

2010-11-12 14:39:36

Sql Server唯

2010-11-12 14:45:19

Sql Server唯

2010-07-02 13:26:56

SQL Server處

2010-09-13 16:39:36

sql server觸

2011-04-01 14:14:42

SQL Server空值

2024-05-24 09:29:28

2010-10-20 10:04:36

sql server自

2010-06-28 09:59:47

SQL Server自

2010-09-26 16:39:27

SQL子查詢

2024-01-10 08:08:25

Python空值校驗開發(fā)

2021-11-15 06:56:45

系統(tǒng)運行空指針

2025-02-27 09:39:56

JavaJava 8對象

2010-09-24 17:08:03

SQL Server唯

2020-08-18 22:20:49

vue.jsnullclass

2010-07-15 10:37:15

SQL Server默

2012-03-07 10:00:35

2021-07-02 06:54:43

分布式環(huán)境ID
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产99久久久国产精品下药 | 午夜一区二区三区视频 | 中文字幕综合 | 免费毛片网站在线观看 | 国产午夜在线观看 | 精品视频一区二区三区四区 | 免费观看a级毛片在线播放 黄网站免费入口 | 久久久久国产精品 | 一二三四在线视频观看社区 | 一区二区三区免费 | 91国在线高清视频 | 国产黄色精品 | 国产免费一级一级 | 狠狠操狠狠色 | 欧美中文字幕在线 | 久久国产精品一区 | 成人免费视频 | 久久久无码精品亚洲日韩按摩 | 精品欧美一区二区三区久久久 | 日韩精品免费 | 国产精品96久久久久久 | 免费人成激情视频在线观看冫 | 免费在线视频精品 | 18性欧美| 91精品久久久久久久久久 | 成人一区二区三区在线观看 | 亚洲一区二区日韩 | 欧美精品91 | 男人av在线 | 免费视频一区二区 | 日日夜夜91 | 成在线人视频免费视频 | 91福利在线观看 | 91电影在线 | 久久久精品 | 久久亚洲国产 | 操久久 | www在线| 亚洲h视频| 日韩欧美在 | 中文字幕在线视频免费视频 |