CHECK 約束
CHECK 約束通過限制輸入到列中的值來強制域的完整性。這與 FOREIGN KEY 約束控制列中數值相似。區別在於它們如何判斷哪些值有效:FOREIGN KEY 約束從另一個表中獲得有效數值列表,CHECK 約束從邏輯表達式判斷而非基於其它列的數據。例如,通過創建 CHECK 約束可將 salary 列的取值範圍限制在 $15,000 至 $100,000 之間,從而防止輸入的薪金值超出正常的薪金範圍。
可以通過任何基於邏輯運算符返回結果 TRUE 或 FALSE 的邏輯(布爾)表達式來創建 CHECK 約束。對上例,邏輯表達式爲:
salary >= 15000 AND salary <= 100000
對單獨一列可使用多個 CHECK 約束。按約束創建的順序對其取值。通過在表一級上創建 CHECK 約束,可以將該約束應用到多列上。例如,多列 CHECK 約束可以用來判明 country 列值爲 USA 且 state 列值爲兩個字母值所對應的行。這樣就允許在一處同時檢查多個條件。
創建和修改 CHECK 約束
CHECK 約束可以:
- 作爲表定義的一部分在創建表時創建。
- 添加到現有表中。表和列可以包含多個 CHECK 約束。
- 修改或刪除現有的 CHECK 約束。例如,可以修改表中列的CHECK 約束的表達式。
說明 若要使用 Transact-SQL 或 SQL-DMO修改 CHECK 約束,必須首先刪除已有的 CHECK 約束,然後再通過新定義重新創建。
在現有表中添加 CHECK 約束時,該約束可以僅作用於新數據也可以同時作用於現有的數據。默認設置爲 CHECK 約束同時作用於現有數據和新數據。當現有數據已符合新的 CHECK 約束,或業務規則要求從此開始強制約束時,使用約束僅作用於新數據選項比較有用。
例如,舊約束要求郵政編碼爲 5 位,而新約束要求爲 9 位。5 位的舊郵政編碼依然有效並與 9 位的新郵政編碼共存。因此,只須對新郵政編碼按新的約束進行檢驗。
不過,添加約束而不檢查現有數據時一定要小心,因爲這樣做將放棄 Microsoft® SQL Server™ 2000 對錶強制完整性規則的控制。
禁用 CHECK 約束
下列情況可以禁用現有 CHECK 約束:
- INSERT 和 UPDATE 語句,以允許不經約束確認修改表中的數據。在執行 INSERT 和 UPDATE 語句時,如果新數據違反約束或約束應只適用於數據庫中已有的數據,那麼可禁用 CHECK 約束。
- 複製處理。如果該約束爲源數據庫所特有,則在複製時請禁用 CHECK 約束。複製表時,表定義和數據從源數據庫複製到目標數據庫。這兩個數據庫通常(但不一定)在不同的服務器上。如果源數據庫特有的 CHECK 約束在複製時未禁用,則可能無謂地妨礙向目標數據庫輸入新數據。
刪除 CHECK 約束以取消對約束表達式所包含列在接受數據時的限制。
修改 CHECK 約束
當要更改約束表達式,或更改對特定條件啓用或禁用約束的選項時,修改 CHECK 約束。
修改 CHECK 約束
- 在數據庫關係圖中右擊包含約束的表,然後從快捷菜單中選擇"屬性"命令。
-或-
爲包含約束的表打開表設計器,在表設計器中右擊,然後從快捷菜單中選擇"屬性"命令。
- 選擇"CHECK 約束"選項卡。
- 從"選定的約束"列表中,選擇要更改的約束。
- 完成下表中的操作:
若要 遵循下列步驟 編輯約束表達式 在"約束表達式"框中,鍵入新的表達式。有關詳細信息,請參見定義 CHECK 約束表達式。 重命名約束 在"約束名"框中,鍵入新的名稱。 將約束應用到現有數據 選擇"創建中檢查現存數據"選項。有關詳細信息,請參見創建 CHECK 約束時檢查現有數據。 當將新數據添加到表中或更新表中的現有數據時禁用約束 清除"對 INSERT 和 UPDATE 強制約束"選項。有關詳細信息,請參見對 INSERT 和 UPDATE 語句禁用 CHECK 約束。 當在另一個數據庫中複製表時禁用約束 清除"對複製強制約束"選項。有關詳細信息,請參見對複製禁用 CHECK 約束。
當保存表或關係圖時,約束即在數據庫內被更新。
定義 CHECK 約束表達式
當將 CHECK 約束附加到表或列時,必須包括 SQL 表達式。有關該操作的詳細信息,請參見將新的 CHECK 約束附加到表或列。
可以創建簡單的約束表達式在簡單條件下檢查數據;或使用布爾運算符創建複雜的約束表達式以在多種條件下檢查數據。例如,假設 authors
表中有一個 zip
列,該列要求 5 位數字的字符串。下面的示例約束表達式確保只允許 5 位數字:
zip LIKE '[0-9][0-9][0-9][0-9][0-9]'
或者假設 sales
表中有一個名爲 qty
的列,該列要求大於 0 的值。下面的示例約束確保只允許正值:
qty > 0
或者假設 orders
表限制所有信用卡訂單可接受的信用卡類型。下面的示例約束確保如果用信用卡發出訂單,則只接受 Visa、MasterCard 或 American Express:
NOT (payment_method = 'credit card') OR
(card_type IN ('VISA', 'MASTERCARD', 'AMERICAN EXPRESS'))
定義約束表達式
- 創建新的 CHECK 約束。有關如何執行該操作的詳細信息,請參見將新的 CHECK 約束附加到表或列。
- 在屬性頁的"CHECK 約束"選項卡中,使用下列語法在"約束表達式"框中鍵入表達式:
{constant | column_name | function | (subquery)}
[{operator | AND | OR | NOT}
{constant | column_name | function | (subquery)}...]SQL 語法由下列參數組成:
參數 描述 constant 字面值,如數字或字符數據。字符數據必須用單引號 ( '
) 括起來。column_name 指定列。 function 內置函數。 operator 算術運算符、位運算符、比較運算符或字符串運算符。 AND 在布爾表達式中用於連接兩個表達式。當兩個表達式均爲真時才返回結果。 當一個語句中同時使用 AND 和 OR 時,先處理 AND。可以使用括號更改執行順序。
OR 在布爾表達式中用於連接兩個或更多條件。只要條件中有一個爲真就返回結果。 當一個語句中同時使用 AND 和 OR 時,在 AND 之後再計算 OR。可以使用括號更改執行順序。
NOT 用於求反任何布爾表達式(可以包含關鍵字,如 LIKE、NULL、BETWEEN、IN 和 EXISTS)。 當在一個語句中使用多個邏輯運算符時,先處理 NOT。可以使用括號更改執行順序。
將新的 CHECK 約束附加到表或列
將 CHECK 約束附加到表以指定一列或多列中可接受的數據值。
附加新的 CHECK 約束
- 在數據庫關係圖中,右擊包含約束的表,然後從快捷菜單中選擇"約束"命令。
-或-
爲將包含約束的表打開表設計器,在表設計器中右擊,然後從快捷菜單中選擇"約束"命令。
- 選擇"新建"命令。"選定的約束"框顯示由系統分配的新約束名。系統分配的名稱以"CK_"開始,後跟表名。
- 在"約束表達式"框中,爲 CHECK 約束鍵入 SQL 表達式。例如,若要將
authors
表中state
列的輸入項限制爲 New York,請鍵入:state = 'NY'
或者,若要要求
zip
列中的輸入項爲 5 位數字,請鍵入:zip LIKE '[0-9][0-9][0-9][0-9][0-9]'
注意 確保將任何非數字約束值用單引號 (') 括起來。有關更多信息,請參見定義 CHECK 約束表達式。
- 若要給約束提供一個不同的名稱,請在"約束名"框中鍵入名稱。
- 用複選框控制何時強制約束:
- 若要在創建約束前對現有數據測試約束,請選中"創建中檢查現存數據"複選框。
- 若要在該表中發生複製操作時強制約束,請選中"對複製強制約束"複選框。
- 若要在該表中插入或更新行時強制約束,請選中"對 INSERT 和 UPDATE 強制約束"複選框。
創建 CHECK 約束時檢查現有數據
當創建 CHECK 約束時,可以設置選項將約束只應用於新數據或同時也應用於現有數據。當知道現有數據已滿足新 CHECK 約束時,或者當業務規則要求僅從這點開始強制約束時,這種使約束僅應用於新數據的選項很有用。
例如,過去可能要求郵政編碼必須是五位數字,但現在卻需要新數據允許有九位郵政編碼。包含五位郵政編碼的舊數據將與包含九位郵政編碼的新數據共存。
創建 CHECK 約束時檢查現有數據
- 在數據庫關係圖中右擊包含約束的表,然後從快捷菜單中選擇"屬性"命令。
-或-
爲包含約束的表打開表設計器,在表設計器中右擊,然後從快捷菜單中選擇"屬性"命令。
- 選擇"CHECK 約束"選項卡。
- 從"選定的約束"列表中選擇約束。
- 選擇"創建中檢查現存數據"複選框。默認情況下選擇該選項。
當保存表或數據庫關係圖時,將應用 CHECK 約束。如果在保存過程中遇到任何違反約束的行爲,則不能保存表。
對 INSERT 和 UPDATE 語句禁用 CHECK 約束
當在表中添加、更新或刪除數據時,可以禁用 CHECK 約束。禁用約束使您能夠執行下列事務:
- 如果表中的現有行過去必須遵從的特定業務規則已不再適用,則可以向該表添加新的數據行(使用 INSERT 語句)。例如,過去可能要求郵政編碼必須是五位數字,但現在卻需要新數據允許有九位郵政編碼。包含五位郵政編碼的舊數據將與包含九位郵政編碼的新數據共存。
- 如果表中的現有行過去必須遵從的特定業務規則已不再適用,則可以修改現有行(使用 UPDATE 語句)。例如,可能需要將所有現有的五位郵政編碼更新爲九位郵政編碼。
如果知道新數據將違反約束,或者約束僅適用於數據庫中的已有數據,則選擇該選項以在 INSERT 和 UPDATE 事務處理期間禁用 CHECK 約束。
對 INSERT 和 UPDATE 語句禁用 CHECK 約束
- 在數據庫關係圖中右擊包含約束的表,然後從快捷菜單中選擇"屬性"命令。
-或-
爲包含約束的表打開表設計器,在表設計器中右擊,然後從快捷菜單中選擇"屬性"命令。
- 選擇"CHECK 約束"選項卡。
- 從"選定的約束"列表中選擇約束。
- 清除"對 INSERT 和 UPDATE 強制約束"複選框。
可以在添加或修改數據後選擇該選項,以確保約束能應用到後續的數據修改中。
對複製禁用 CHECK 約束
當在另一個數據庫中複製表時,可以禁用 CHECK 約束。複製表時,表定義和數據從源數據庫複製到目的數據庫。這兩個數據庫通常(但不一定)位於不同的服務器上。如果 CHECK 約束僅針對源數據庫,則可能會不必要地阻止新數據輸入到目的數據庫。當在遠程站點上覆制數據庫時,不應重新應用 CHECK 約束,因爲:
- 數據在被輸入原始數據庫時將進行完整性檢查。
- 如果數據違反 CHECK 約束,複製將失敗。
對複製禁用 CHECK 約束
- 在數據庫關係圖中右擊包含約束的表,然後從快捷菜單中選擇"屬性"命令。
-或-
爲包含約束的表打開表設計器,在表設計器中右擊,然後從快捷菜單中選擇"屬性"命令。
- 選擇"CHECK 約束"選項卡。
- 從"選定的約束"列表中選擇約束。
- 清除"對複製強制約束"複選框。