共用方式為


唯一條件約束和檢查條件約束

UNIQUE 條件約束和 CHECK 條件約束是兩種類型的條件約束,可用來在 SQL Server 數據表中強制執行數據完整性。 這些都是重要的資料庫物件。

本主題包含下列各節。

UNIQUE 條件約束

CHECK 約束條件

相關工作

UNIQUE 條件約束

條件約束是 SQL Server 資料庫引擎為您強制使用的規則。 例如,您可以使用 UNIQUE 條件約束來確保不會在未參與主鍵的特定數據行中輸入重複的值。 儘管 UNIQUE 約束和 PRIMARY KEY 約束都強制執行唯一性,但當您想要強制一個非主鍵欄位或欄位組合的唯一性時,應使用 UNIQUE 約束,而非 PRIMARY KEY 約束。

不同於 PRIMARY KEY 條件約束,UNIQUE 條件約束允許 NULL 值。 不過,如同任何參與 UNIQUE 條件約束的值一樣,每個數據行只允許一個 Null 值。 UNIQUE 條件約束可以被 FOREIGN KEY 條件約束參考。

當 UNIQUE 條件約束新增至數據表中的現有數據行或數據行時,Database Engine 預設會檢查數據行中的現有數據,以確定所有值都是唯一的。 如果 UNIQUE 條件約束新增至具有重複值的數據行,Database Engine 會傳回錯誤,而且不會新增條件約束。

Database Engine 會自動建立 UNIQUE 索引,以強制執行 UNIQUE 條件約束的唯一性需求。 因此,如果嘗試插入重複的數據列,Database Engine 會傳回錯誤訊息,指出已違反 UNIQUE 條件約束,而且不會將數據列新增至數據表。 除非明確指定叢集索引,否則預設會建立唯一的非叢集索引,以強制執行 UNIQUE 條件約束。

CHECK 條件約束

CHECK 條件約束會限制一或多個數據行所接受的值,以強制執行定義域完整性。 您可以使用任何根據邏輯運算符返回 TRUE 或 FALSE 的邏輯(布林值)表達式來建立檢查約束。 例如,您可以建立 CHECK 條件約束來限制 薪資 數據行的值範圍,只允許從 $15,000 到 $100,000 的數據。 這可防止輸入的薪水超過一般的薪水範圍。 邏輯運算式可以是: salary >= 15000 AND salary <= 100000

您可以將多個 CHECK 條件約束套用至單一數據行。 您也可以藉由在數據表層級建立單一 CHECK 條件約束,將單一 CHECK 條件約束套用至多個數據行。 例如,多列 CHECK 條件約束可用來確認任何具有country_region欄位中值為美國的資料列,在欄位中也有兩個字符的值。 這允許可在某一個位置上檢查多個條件。

CHECK 條件約束與 FOREIGN KEY 條件約束類似,因為它們會控制放入數據行中的值。 差異在於它們如何判斷哪些值有效:FOREIGN KEY 條件約束會從另一個數據表取得有效值的清單,而 CHECK 條件約束則會從邏輯表達式判斷有效值。

謹慎

包含隱含或明確數據類型轉換的條件約束可能會導致某些作業失敗。 例如,在分割區切換來源的數據表上定義的這類條件約束可能會導致 ALTER TABLE...SWITCH 作業失敗。 應避免在條件約束定義中進行資料類型轉換。

CHECK 約束條件的限制

CHECK 條件約束會拒絕結果為假(FALSE)的值。 因為 Null 值評估為 UNKNOWN,因此它們在表達式中的存在可能會覆蓋約束。 例如,假設您在 MyColumn 數據行上int放置條件約束,指定 MyColumn 只能包含值 10 (MyColumn=10)。 如果您將 NULL 值插入 MyColumn 中,Database Engine 會插入 NULL,而不會傳回錯誤。

當檢查的條件不是 FALSE 時,CHECK 條件約束會針對數據表中的任何數據列傳回 TRUE。 CHECK 條件約束可在數據列層級運作。 如果剛建立的數據表沒有任何數據列,則此數據表上的任何 CHECK 條件約束都會被視為有效。 這種情況可能會產生非預期結果,如下列範例所示。

CREATE TABLE CheckTbl (col1 int, col2 int);  
GO  
CREATE FUNCTION CheckFnctn()  
RETURNS int  
AS   
BEGIN  
   DECLARE @retval int  
   SELECT @retval = COUNT(*) FROM CheckTbl  
   RETURN @retval  
END;  
GO  
ALTER TABLE CheckTbl  
ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() >= 1 );  
GO  

要加入的 CHECK 條件約束會指定 CheckTbl資料表中至少要有一個資料列。 不過,由於數據表中沒有任何行可以檢查此約束條件,因此 ALTER TABLE 語句會成功。

CHECK 條件約束不會在 DELETE 語句期間進行驗證。 因此,在具有特定檢查條件約束類型的數據表上執行 DELETE 語句可能會產生非預期的結果。 例如,考慮在 CheckTbl資料表上執行的下列陳述式。

INSERT INTO CheckTbl VALUES (10, 10);  
GO  
DELETE CheckTbl WHERE col1 = 10;  

即使 DELETE 條件約束會指定資料表 CHECK 至少必須具有 CheckTbl 個資料列, 1 陳述式也會執行成功。

相關工作

備註

如果數據表已發行以進行複寫,您必須使用 Transact-SQL 語句進行架構變更,ALTER TABLE 或 SQL Server 管理物件 (SMO)。 當使用數據表設計工具或資料庫關係圖設計工具進行架構變更時,它會嘗試卸除並重新建立數據表。 您無法卸除已發佈的物件,因此架構變更將會失敗。

任務 主題
描述如何建立唯一的條件約束。 建立唯一條件約束
描述如何修改唯一的條件約束。 修改唯一的條件約束
描述如何刪除唯一條件約束。 刪除唯一的條件約束
描述如何在複寫代理程式在資料表中插入或更新資料時,停用檢查條件約束。 停用複寫的檢查條件約束
描述如何在加入資料表資料、更新資料表資料或刪除資料表資料時,停用檢查條件約束。 使用 INSERT 與 UPDATE 陳述式停用檢查條件約束
描述如何變更條件約束運算式或啟用或停用特定條件之條件約束的選項。 修改檢查條件約束
描述如何刪除檢查條件約束。 刪除檢查條件約束
描述如何檢視檢查條件約束的屬性。 唯一條件約束與檢查條件約束