16

16. 建立與使用預設值、條件約束及規則

預設值

條件約束

規則物件

本章總結

預設值、條件約束及規則物件皆是您可以在資料表的資料行定義中的選擇性屬性。在 第15章 ，曾學習了使用如何用ALTER TABLE命令替資料表新增具有預設值的資料行。本章則涵蓋設立及修改預設值之方式。回顧一下，設定 預設值 （default）指的是在一沒有明確設定值的資料行中，輸入一明確的值。 條件約束 （constraint）則是提供了用於辨識有效資料行值的方法（為了拒絕無效的值）。本章將介紹五種類型的條件約束值及如何使用T-SQL及Microsoft SQL Server Enterprise Manager來設立和修改預設值及條件約束的方法，不過，使用Enterprise Manager會較為簡單。

預設值

下述狀況得以解釋為何需要在資料表的資料行中設立預設值。例如您如果想在含有一個或多個可為NULL資料行的資料表中插入資料列，則這些資料行將會被輸入為NULL值。但是如果這些資料行被定義為NOT NULL，並且於插入資料列時並未替該批資料行提供值，那麼將會有一條錯誤訊息提醒您NULL無法被插入該批資料行中。此時預設值即可發揮其功效。預設值可在此時替代NULL值，以避免產生錯誤訊息。

Microsoft SQL Server 7.0允許您為資料表中的每一資料行定義一個預設值。具有timestamp資料型別或IDENTITY、ROWGUIDCOL屬性的資料行不能定義預設值，因為這些資料行必須是特殊的值。 預設值 定義中指定的值也必須與資料行中的資料型別是相容的。

有幾種建立和修改預設值定義的方式。在這部份，我們首先介紹如何以T-SQL於建立資料表時定義一個預設值，以及如何透過新增或修改預設值來修改資料行；之後則會介紹以Enterprise Manager來執行相同的工作。在

第15章 裡我們曾介紹如何替資料表新增有預設值的資料行，以及此資料行對資料表中現存的資料列所產生的影響。在此，我們將提供一範例以詳述可用的選項及新增預設值對資料表中現存資料行的影響。

使用T-SQL來定義和修改預設值

您可以用下列三項陳述式之一為資料行定義預設值：CREATE TABLE、ALTER TABLE或CREATE DEFAULT。SQL Server 2000使用CREATE DEFAULT來建立 預設 物件，保持向後相容性。使用這種方式時，SQL Server把資料表和物件分開儲存，因此必須透過系統預存程序sp_bindefault把物件繫結到資料表上。刪除資料表時，DEFAULT定義自動從資料表中解除繫結，但是 預設 物件仍然存在。在使用CREATE TABLE或ALTER TABLE時，SQL Server會把 預設 物件定義和資料表一同儲存，如果資料表被刪除，預設物件也會自動被刪除，而不須再採取其他操作步驟。因此，通常不建議使用CREATE DEFAULT。然而，當對多個資料行使用相同的預設值時，使用 預設 物件也可能會帶來好處。

當執行T-SQL時，應使用SQL Query Analyzer，因其執行結果可顯示在使用者圖形介面上。此項功能比在命令視窗內執行更方便使用者閱讀。

使用CREATE TABLE建立預設值

使用CREATE TABLE命令在資料行中建立預設值是較常用的標準技巧。以下的陳述式在MyDB中建立一有預設值的資料表，並同時定義了兩個資料行：A資料行為char類型；B資料行為int類型。

    USE MyDB
    CREATE TABLE MyTABLE
    (
    columnA  char(15)  NULL DEFAULT 'n/a',
    columnB  int NULL  DEFAULT 0
    )
    GO

columnA中的預設值n/a與該資料行的char資料型別相容；相同的，columnB中的預設值0和該資料行的int資料型別相容。如果我們在資料表中插入一資料列而沒有為columnA及columnB的兩個資料行指定數值，則預設值會被自動取用。所以若要該資料行保持NULL，則要明白表示要插入NULL值。因為此兩資料行皆可包含NULL值，所以欲插入NULL值是被允許的。但若資料行定義為NOT NULL，則不能插入NULL值。

使用ALTER TABLE修改預設值

使用ALTER TABLE命令可以修改資料行中的預設值定義或新增一資料行。若要更改已經定義的預設值資料行，首先必須刪除已經有的預設值，然後新增一個新的預設值（若您使用的是Enterprise Manager就會較為簡單，因為使用Enterprise Manager就不需執行刪除的步驟）。

如果用CREATE TABLE命令建立未命名的預設值，或使用Enterprise Manager（將在本章後面部份介紹），SQL Server將自動替預設值命名。要知道SQL Server為預設值分配了什麼名字，以便可以使用T-SQL刪除它，您可執行sp_help程序如下：

    USE MyDB
    GO
    sp_help MyTable
    GO

所有MyTable的預設值名稱皆列示在圖16-1中的constraint_name資料行下面：

圖16-1 sp_help程序的輸出

假設我們要把columnA的預設值從n/a改成not applicable。記住首先必須刪除存在的預設值然後再新增一個新的。下述命令即可刪除預設值：

    ALTER TABLE MyTable
    DROP CONSTRAINT DF_MyTable_columnA_2B3F6F97

現在您可以使用下述命令新增一個預設值，這次由我們自己命名，：

    ALTER TABLE MyTable
    ADD CONSTRAINT DF_MyTable_columnA
    DEFAULT "Not applicable" FOR columnA
    GO

當變更已存在的預設值時，所有現存的列將保持原始的預設值。只有新插入的列會使用新的預設值。

如

第15章 所述，您也可以用ALTER TABLE命令為已有的資料表新增完整的新資料行，如下所示：

    ALTER TABLE MyTable
    ADD columnC tinyint NOT NULL DEFAULT 13
    GO

現在MyTable範例資料表已新增了資料行columnC資料行，其預設值為13。因為columnC是定義為NOT NULL的新資料行，資料表中現存資料行的新資料行將會被分配為預設值13。

如果新資料行允許被設定為NULL值，資料表中現存資料行的新資料行則會被分配為NULL值。若我們希望用預設值而不是NULL插入已存在的列，則應該使用DEFAULT中的WITH VALUES選項，如下所示：

    ALTER TABLE MyTable
    ADD columnC tinyint NULL DEFAULT 13 WITH VALUES
    GO

WITH VALUES命令會強行使MyTable中所有現存列的新資料行接受預設值13來代替原來的NULL值。

現在，我們已經學習了如何建立與資料表儲存在一起的DEFAULT定義。下面我們將學習如何用CREATE DEFAULT來建立一個和資料表分開儲存的 預設 物件。

CREATE DEFAULT和sp_bindefault

您還可以使用T-SQL CREATE DEFAULT命令來建立Default物件，進而新增或修改現存資料行的預設值。建立預設值物件後，使用系統預存程序sp_bindefault可以把它繫結至資料行或繫結至使用者自訂的資料型別上。如前所述，在SQL Server 2000中保留這種方法的目的是為了向後相容性，因此它不是很好的方法。但是，如果要在不同的資料表中使用相同的預設值資料行，此方法則較為有效。

下面介紹一個例子，使用CREATE DEFAULT來建立名稱為DF_not_applicable的預設值物件，其值為n/a。在MyDB資料庫中建立該 預設 物件，並繫結至MyTable的columnA上（假定資料表中現在不存在預設值）。使用CREATE DEFAULT的語法如下：

    CREATE DEFAULT default_name AS constant_expression

sp_bindefault的語法如下：

    sp_bindefault 'default_name' table.column | user_defined_datatype
    [", futureonly"]

參數default_name是 預設 物件的名稱。Table.column是指定要分配預設物件的資料行。

下面的T-SQL陳述式能建立範例的預設物件，並把它繫結至MyTable的columnA上：

    USE MyDB
    GO
    CREATE DEFAULT DF_not_applicable AS 'n/a'
    GO
    sp_bindefault "DF_not_applicable", "MyTable.columnA"
    GO

如果columnA中已經存在預設值，執行sp_bindefault時，SQL Server將傳回一條錯誤訊息，通知您不能繫結 預設 物件到已經具有預設值的資料行上。您首先須刪除原預設值，然後把新的預設物件繫結至該資料行上（使用DROP DEFAULT刪除預設物件的過程將在本節後面介紹）。

您還可以建立一預設物件並將此物件與使用者自訂資料型別繫結起來。繫結預設物件到使用者自訂資料型別時，您可以使用sp_bindefault的futureonly選項。這一選項防止現存的使用者自訂型別資料行接受這個新的預設值，而只有新建立的使用者自訂型別的資料行才能接受其相關聯的預設值。如果沒有指定futureonly，SQL Server將預設值繫結到所有已經存在的和新建立的使用者自訂類型的資料行上。

例如，讓我們建立一個名稱為area_code的使用者自訂型別和名稱為DF_area_code的預設值物件，其值為786；然後繫結預設值到該使用者自訂資料型別上（使用者自訂資料型別的建立在 第10章 介紹過）。因為這是新的使用者自訂資料型別，因此目前還沒有資料行，也就不需要futureonly選項，但我們依然保留它，因為保留它不會有什麼影響。該陳述式將如下所示：

    sp_addtype "area_code", "char(3)", "NOT NULL"
    GO
    CREATE DEFAULT DF_area_code AS 786
    GO
    sp_bindefault "DF_area_code", "area_code", "futureonly"
    GO

要檢視 預設 物件的資料型別，可使用sp_help系統程序，如圖16-2所示。

圖16-2 sp_help的Query Analyzer結果。

sp_unbindefault

要從資料行或使用者自訂資料型別中解除繫結預設物件，您可以使用sp_unbindefault。例如要解除MyTable中與columnA資料行繫結的預設值：sp_unbindefault，其陳述式如下：

    sp_unbindefault "MyTable.columnA"
    GO

使用下列陳述式，從使用者自訂的資料型別area_code中解除繫結預設值：

    sp_unbindefault "area_code"
    GO

當執行以上程序，所有已經由使用者自訂資料型別area_code的預設值屬性將會同時移除。

您可以使用不同的sp_bindefault陳述式將預設物件繫結到多個資料行中。同樣的，只要在不刪除預設物件的情形下，您可以隨意地解除或繫結某個資料行的預設。使用DROP DEFAULT陳述式，可以完全刪除一個 預設 物件，如下所示：

    DROP DEFAULT DF_area_code
    GO

一旦刪除了預設物件，就無法再取回。如果要再次使用，必須使用CREATE DEFAULT重新建立物件。

使用Enterprise Manager定義及修改預設值

正如 第15章 所示，使用Enterprise Manager建立和修改資料表可能是最簡單的方法。用Enterprise Manager建立或修改資料表或資料行時，SQL Server會自動執行適當的T-SQL命令替您完成任務（關於如何使用Enterprise Manager按部就班地建立資料表，請參閱 第10章 ）。這部分將學習如何用Enterprise Manager指定預設值定義和修改預設值資料行的詳細內容，以及如何建立預設物件。讓我們從指定及修改預設值定義的例子講起。

指定及修改預設值定義

假設在MyDB資料庫中有一個名為Product_Info的資料表。資料表的結構如圖16-3所示（使用Enterprise Manager建立資料表的說明請參閱 第10章 ）。

圖16-3 Product_Info資料表的 設計資料表 視窗

要定義預設值，只需在 預設值 標題下的儲存格中鍵入資料行的預設值。注意圖16-3中Desciption資料行的預設值定義為 ' n/a '，這只是表示目前尚未指定該項產品的特徵。同時要注意預設值被括在小括號中－Enterprise Manager會在您儲存資料表時自動新增以上預設值。

變更預設值也很簡單。僅需用新預設值取代原預設值，再按一下 存檔 按鈕將操作儲存即可。圖16-4顯示把Desciption的預設值變更為'not available'；圖16-5顯示在Product_Name新增一個預設值general merchandise。

說明

在 預設值 儲存格中輸入字串，必須放在單引號中，否則儲存時會顯示SQL Server的錯誤訊息。

圖16-4 設計資料表視窗，顯示修改的預設值

圖16-5 設計資料表視窗，顯示新增的預設值

與T-SQL類似，使用Enterprise Manager新增或修改現存資料行上的預設值時，並不影響資料表中現存的資料列，只有新插入的資料列會使用新的預設值。如果替資料表新增一個資料行並指定一個預設值，在預設值不允許為NULL值的情況下，任何現存資料列中的資料將得到新資料行的預設值；如果允許為NULL值，則現存列中的新資料行將會分配為NULL值。要使新資料行允許為NULL值，並把預設值強行插入到所有現存列中，請參考本章前面 〈使用ALTER TABLE修改預設值〉 部分介紹的方法。

建立和管理預設物件

您也可以使用Enterprise Manager來建立預設物件和檢視已有的預設物件。要檢視已有的預設物件，開啟Enterprise Manager，展開要使用的伺服器和資料庫，按一下 預設 。所有現存的預設物件將顯示在右邊窗格中，如圖16-6所示。注意，您將可以看到在本章前面用CREATE DEFAULT建立的DF_not_applicable及DF_area_code預設物件。

圖16-6 檢視現存的預設物件

要使用Enterprise Manager建立新的預設物件，並關聯預設物件到資料行或使用者自訂資料型別上，須遵循下列步驟：

1. 展開伺服器和資料庫，在 預設 上按右鈕，並在快顯功能表上選擇 新增預設 ，以顯示出 預設屬性 視窗，如圖16-7所示。把此預設物件命名為DF_none，並分配 ' none ' 為其值。完成操作後按一下 確定 。

   圖16-7 預設屬性視窗

- 要繫結預設物件到使用者自訂資料型別或某一資料行上，在Enterprise Manager右邊窗格中的預設值名稱（本例是DF_none）上按右鈕，並從快顯功能表中選擇 內容 。 預設屬性 視窗將再次出現，不過這次可以使用 繫結UDT （使用者自訂資料型別）和 繫結資料行 按鈕。

按一下 繫結UDT 按鈕會顯示 繫結預設值到使用者自訂的資料型別 的對話方塊，如圖16-8所示。這個對話方塊將顯示所有使用者自訂資料型別，從清單中選擇要關聯預設值的使用者自訂資料型別。圖16-8中，可以看見area_code及brand_type資料型別。如果已經定義了很多使用者自訂資料型別，它們也會顯示在此清單中。操作完成後，按一下 套用 再按 確定 即可返回 預設屬性 視窗。

- 要將預設值繫結到資料行上，按一下 繫結資料行 按鈕， 繫結預設值到資料行 的對話方塊即會顯示。現在選擇要繫結的資料行。首先從 資料表 下拉式清單中選擇資料表名稱，然後從 未繫結資料行 清單中選擇要繫結預設值的資料行名稱。然後按一下 新增 （圖16-9顯示從Product_Info資料表中的繫結資料行清單新增Price資料行的對話方塊）。

  按一下 確定 返回 預設屬性 視窗，然後按一下 確定 關閉 預設屬性 視窗。

  圖16-8 「繫結預設值到使用者自訂的資料型別」對話方塊

  圖16-9 「繫結預設值到資料行」對話方塊

要從使用者自訂類型中解除預設物件，可在 預設屬性 視窗中開啟如上所述的 繫結預設值到使用者自訂的資料型別 對話方塊，然後清除 繫結 核取方塊。要解除預設物件的預設值，開啟 繫結預設值到資料行 對話方塊，選擇資料行名稱，按一下 移除 。

要刪除預設物件，首先必須先從其他物件中解除預設物件的繫結。如果您試圖刪除與物件繫結的預設，SQL Server將傳回錯誤訊息。要刪除預設物件，按一下Enterprise Manager左邊窗格中的 預設 ，在預設物件名稱上按右鈕，並在快顯功能表中選擇 刪除 ，再按一下 卸除物件 對話方塊中的 卸除全部 。

到此為止，我們已講述了預設物件，下面將開始介紹條件約束。

條件約束

條件約束用於自動維護資料的完整性。舉個例子，您可以將一個整數資料行條件約束在1到100的範圍內，那麼超出此範圍的數值則無法被接受（CHECK功能即可設立此條件約束）。在單一資料行上的條件約束稱為資料行條件約束（column constraint），它只約束該資料行的取值範圍。影響兩個或多個資料行的條件約束稱為資料表條件約束（table constraint），它確保資料行中值的結合符合條件約束的要求。條件約束的五種類型為NOT NULL、UNIQUE、PRIMARY KEY、FOREIGN KEY和CHECK。

使用T-SQL建立和修改條件約束

在這部分，我們將學習各種類型的條件約束和如何用T-SQL建立條件約束。稍後的部分將學習用Enterprise Manager完成同樣的過程。

NOT NULL

NOT NULL條件約束相當簡單。實際上在本章和前面章節的例子中我們已經接觸過了，置於資料行中的NOT NULL條件約束能避免在資料行中插入NULL值（這與允許NULL值的NULL條件約束相反）。使用T-SQL修改資料行時，可以在建立資料表時或在建立資料表以後指定該資料行為NOT NULL（詳細內容請參閱

第10章 關於修改資料庫資料表部分）。

UNIQUE

UNIQUE條件約束用以確保一個或多個資料行中沒有重複的數值。換句話說，加強資料行中數值的唯一性。要加強這種唯一性，SQL Server在UNIQUE條件約束中建立一個唯一的非叢集索引。您可以指定索引是叢集還是非叢集的，但要記住的是，一個資料表只允許有一個叢集索引。

說明

本章將經常使用叢集索引和非叢集索引這兩個專有名詞，如果您對它們的含義不是十分確定， 第17章 將詳細介紹這兩種類型的索引。

UNIQUE條件約束可以用於任一個非PRIMARY KEY的條件約束（將於下一部分介紹）的資料行，PRIMARY KEY條件約束便加強了值的唯一性。UNIQUE條件約束可以用於允許NULL值的資料行，而PRIMARY KEY條件約束不能。UNIQUE條件約束將忽略NULL值。一個被UNIQUE限制的資料行可以被FOREIGN KEY條件約束引用（在本章後面 〈FOREIGN KEY〉 部分介紹）。一張資料表能有多個UNIQUE條件約束，只要資料表的索引數不超過249個非叢集索引和1個叢集索引。

要用T-SQL為資料表建立UNIQUE條件約束，須執行CREATE TABLE或ALTER TABLE命令。例如，下面的陳述式將建立customer資料表，並在其中的SSN資料行上建立UNIQUE條件約束作為叢集索引：

    CREATE TABLE customer
    (
    first_name   char(20) NOT NULL,
    mid_init     char(1) NULL,
    last_name    char(20) NOT NULL,
    SSN          char(11) NOT NULL UNIQUE CLUSTERED,
    cust_phone   char(10) NULL
    )
    GO

前面的CREATE陳述式使用了一個資料行條件約束。下面的例子同樣將建立customer資料表，而這次在first_name、mid_init和last_name資料行上新增UNIQUE資料表條件約束：

    CREATE TABLE customer
    (
    first_name   char(20) NOT NULL,
    mid_init     char(1) NULL,
    last_name    char(20) NOT NULL,
    SSN          char(11) NOT NULL UNIQUE CLUSTERED,
    cust_phone   char(10) NULL,
    CONSTRAINT   UQ_full_name UNIQUE NONCLUSTERED (first_name,
                 mid_init, last_name)
    )
    GO

UNIQUE資料表條件約束（多於一資料行的條件約束）確保資料行中的所有數值是唯一的。即表示此資料庫無法接受first name、mid initial及last name完全相同的客戶。注意此處的UNIQUE資料表條件約束是一個非叢集索引，因為在SSN中已經存在一個叢集索引。

要為現存資料表新增UNIQUE條件約束，須使用ALTER TABLE命令。如果要透過新增UNIQUE條件約束來修改已有的資料行，資料表中所有現存的列在這些資料行中必須保持單一或NULL的數值，否則會顯示一條錯誤訊息，提示您不能新增UNIQUE條件約束。假設我們已經建立了沒有條件約束的customer資料表。下面是新增資料行條件約束和資料表條件約束的兩組命令：

    ALTER TABLE customer
    ADD CONSTRAINT UQ_ssn UNIQUE CLUSTERED(SSN)
    GO

    ALTER TABLE customer
    ADD CONSTRAINT UQ_full_name UNIQUE NONCLUSTERED (first_name,
        mid_init, last_name)
    GO

同樣的，您只能在現存的資料符合條件約束要求時，為資料表新增條件約束。

要用T-SQL來修改資料行或資料表中已有的UNIQUE條件約束，必須先刪除條件約束再重新建立。和預設值一樣，為了能夠簡單地完成查詢和刪除條件約束，而不用判斷SQL Server給它們分配了什麼名稱，您應使用描述性名稱。在 〈使用Enterprise Manager建立和修改條件約束〉 部分，我們將看到，當用Enterprise Manager修改條件約束時，SQL Server將自動刪除舊的條件約束，並在儲存修改時重新建立條件約束。

主索引鍵

主索引鍵條件約束是用於指定資料表中一或多個資料行的 主索引鍵 （primary key），能唯一的區分某一資料列。由於主索引鍵的設定是為了辨識資料列，所以主索引鍵條件約束不可以是NULL；這一點與UNIQUE條件約束恰巧相反。為一組資料行定義主索引鍵條件約束時，為符合條件約束，資料行中值的結合對於每一資料列都必須是唯一的。和UNIQUE條件約束一樣，PRIMARY KEY條件約束不允許有重複的值，並在主索引鍵中自動建立一個單一的索引。您也可以指定主索引鍵的索引是叢集還是非叢集；如果沒有特別指定，資料表將被自動預設為叢集索引。

每張資料表只有一個PRIMARY KEY條件約束。IDENTITY資料行是做為主索引鍵的最好選擇，或是相對於其他資料列時該資料行（或一組資料行）的值是唯一值，就可以設定主索引鍵。舉例來說，在範例資料表customer中，我們可以將SSN資料行設為主索引鍵，而不是在資料行中建立UNIQUE條件約束。PRIMARY KEY條件約束不允許NULL值，所以會加強SSN資料行中值的唯一性，並自動在主索引鍵資料行中建立叢集索引。下面的T-SQL命令示範指定SSN資料行作為主索引鍵的方法。透過這種方法SQL Server會主動命名此PRIMARY KEY條件約束，因此這並不是最好的方法，因為以後可能需要透過名稱來刪除該鍵值（但是您無法知道SQL將此PRIMARY KEY取了什麼名稱）。

    CREATE TABLE customer
    (
    first_name      char(20)      NOT NULL,
    mid_init        char(1)       NULL,
    last_name       char(20)      NOT NULL,
    SSN             char(11)      PRIMARY KEY,
    cust_phone      char(10)      NULL
    )
    GO

另一種可行的方法是以增加CONSTRAINT關鍵字來命名。使用下面的命令將主索引鍵命名為PK_SSN：

    CREATE TABLE customer
    (
    first_name      char(20)      NOT NULL,
    mid_init        char(1)       NULL,
    last_name       char(20)      NOT NULL,
    SSN             char(11)      CONSTRAINT PK_SSN PRIMARY KEY,
    cust_phone      char(10)      NULL
    )
    GO

您也可以在定義了所有資料表的資料行後，再指定PRIMARY KEY條件約束。資料行名稱必須在括號中，並在CONSTRAINT後指定，語法如下所示：

    CREATE TABLE customer
    (
    first_name      char(20)      NOT NULL,
    mid_init        char(1)       NULL,
    last_name       char(20)      NOT NULL,
    SSN             char(11),
    cust_phone      char(10)      NULL,
    CONSTRAINT PK_SSN PRIMARY KEY (SSN)
    )
    GO

使用ALTER TABLE命令為沒有PRIMARY KEY條件約束的資料表新增PRIMARY KEY條件約束。以下為替customer資料表新增PRIMARY KEY：

    ALTER TABLE customer
    ADD CONSTRAINT PK_SSN PRIMARY KEY CLUSTERED (SSN)
    GO

以上的命令包括了選擇性的關鍵字CLUSTERED，是為了表明：儘管資料表預設為叢集索引，我們仍可在主索引鍵資料行建立叢集索引。

要刪除PRIMARY KEY條件約束，須使用ALTER TABLE命令和DROP CONSTRAINT陳述式。下面為刪除SSN資料行的條件約束的命令：

    ALTER TABLE customer
    DROP CONSTRAINT PK_SSN
    GO

您應該特別注意的是，只有在DROP CONSTRAINT的陳述式中，需要條件約束名稱。要使用T-SQL命令修改資料表中現存的PRIMARY KEY條件約束，必須先使用ALTER TABLE...DROP CONSTRAINT刪除現存條件約束和ALTER TABLE... ADD CONSTRAINT陳述式來新增條件約束以修改資料表。

外部索引鍵

外部索引鍵 （FOREIGN KEY）條件約束是用於識別兩資料表之間關聯性，識別的方式為資料表A外部索引鍵會參照資料表B中的候選索引鍵（candidate key，可以是一行或多行）。要將資料列插入一個具外部索引鍵的資料表中，被插入的資料表會檢查參照資料表中的候選索引鍵，如果兩個資料表中的外部索引鍵和候選索引鍵的值不符，就不允許插入；反之，就允許插入。

當更新參照資料表中或具外部索引鍵的資料表的資料列時，也會檢查外部索引條件約束，所以在更新候選索引鍵或外部索引鍵時，不能違反所設定的條件約束。這個規則有一個例外：更新參照資料表時使用了T-SQL CREATE TABLE陳述式中的ON UPDATE CASCADE選項。這項選擇在本章 〈使用Enterprise Manager建立和修改條件約束〉 一節中會介紹。

另外，若是要從參照資料表中刪除一個資料列，也會檢查外部索引鍵。如果要刪除的資料列有被具外部索引鍵的資料表引用，就不能被刪除。換句話說，每一個在具外部索引鍵資料表中的資料，在參照資料表中都要有一個相對的資料列，而當所要刪除的資料列被另一個資料表所參照時，就不能刪除該資料列。這個規則只有一個例外的情形：更新參照資料表時使用了T-SQL CREATE TABLE陳述式中的ON DELETE CASCADE選項。這個選項在 〈使用Enterprise Manager建立和修改條件約束〉 一節中會介紹。

外部索引鍵資料表只能引用資料表中具PRIMARY KEY條件約束或UNIQUE條件約束的資料行。如果要引用一個不包含上述條件約束的外部索引鍵，SQL Server會回傳錯誤訊息。外部索引鍵資料行的資料型別和大小必須和所參照的資料行一致。

請參照以下範例，以便更進一步的了解外部索引鍵的使用。首先建立一個資料表，命名為items，其中的item_id資料行具主索引鍵，如下所示：

    CREATE TABLE items
    (
    item_name       char(15)      NOT NULL,
    item_id         smallint      NOT NULL IDENTITY(1,1),
    price           smallmoney    NULL,
    item_desc       varchar(30)   NOT NULL DEFAULT 'none'
    CONSTRAINT      PK_item_id    PRIMARY KEY (item_id)
    )
    GO

接下來，我們將建立inventory的資料表，其中有稱為FK_item_id的外部索引鍵，此外部索引鍵引用items資料表的item_id，如下所示：

    CREATE TABLE inventory
    (
    store_id       tinyint    NOT NULL,
    item_id        smallint   NOT NULL,
    item_quantity  tinyint    NOT NULL,
    CONSTRAINT     FK_item_id FORGIEN KEY(item_id)
    REFERENCES     items(item_id)
    )
    GO

要觀察兩個資料表之間的關聯性，可參閱圖16-10所示的資料庫圖表（如何建立資料庫圖表見 第15章 ）。本例中，items為具候選索引鍵item_id的參考資料表。由於它是資料表的主索引鍵，而資料表中沒有其他的UNIQUE條件約束，所以是唯一可能的候選索引鍵。記住，只有主索引鍵和UNIQUE條件約束才可能是有效的候選索引鍵。Inventory資料表的item_id已經被定義了外部索引鍵，因此建立了兩資料表之間的關聯性。這兩個相關資料行的資料型別都是smallint。在inventory資料表的item_id資料行建立外部索引鍵，可確保當某個值不存在於items資料表時，就不能插入資料到資料表中，也不能從資料表items中刪除被資料表inventory的外部索引鍵所引用的資料列。換句話說，如果有一項目同時存在於items資料表及inventory資料表，該項目則無法從items資料表或inventory資料表中刪除。

圖16-10 顯示items和inventory資料表間外部索引鍵關聯性的資料庫圖表

要利用T-SQL命令修改FOREIGN KEY條件約束，必須先刪除舊的條件約束，然後使用ALTER TABLE命令建立新的條件約束。這種方法類似於修改PRIMARY KEY條件約束的方法。下面為先刪除inventory資料表的舊條件約束，然後新增條件約束的命令：

    ALTER TABLE inventory
    DROP CONSTRAINT FK_item_id
    GO

    ALTER TABLE inventory
    ADD CONSTRAINT FK_item_id FOREIGN KEY (item_id)
    REFERENCES items(item_id)
    GO

當您在現存資料行中新增FOREIGN KEY條件約束，SQL Server會檢查資料表中現存的資料列，以確保除NULL值外，外部索引鍵資料行的值符合參照資料表的PRIMARY KEY條件約束或UNIQUE條件約束。當建立FOREIGN KEY條件約束時，可以使用ALTER TABLE的WITH NOCHECK選項，那麼SQL Server就不會去驗證現有的值，如下所示：

    ALTER TABLE inventory
    WITH NOCHECK ADD CONSTRAINT FK_item_id
    FOREIGN KEY (item_id)
    REFERENCES items(item_id)
    GO

WITH NOCHECK選項可避免SQL檢查資料表中現存列的值。如此，無論現有值為何，都可以新增條件約束到資料表上。新增條件約束後，外部索引鍵的完整性也會增強。

注意

使用WITH NOCHECK選項時要小心。因為當您預計更新現存資料，但是現存資料中卻包含與條件約束衝突的值，您將無法更新現存資料。

您也可以控制是否啟用FOREIGN KEY條件約束。如果要插入與現存條件約束衝突的資料列，可以暫時使條件約束無效，等完成插入後再重新使條件約束生效。NOCHECK關鍵字表示忽略條件約束（條件約束失效）；CHECK關鍵字表示條件約束生效。下面的命令使用NOCHECK和CHECK關鍵字來控制FOREIGN KEY條件約束是否生效：

    ALTER TABLE inventory
    NOCHECK CONSTRAINT FK_item_id   -- 使條件約束無效
    GO

    --在此插入您需要的資料列
    ALTER TABLE inventory
    CHECK CONSTRAINT FK_item_id     -- 重新回復條件約束
    GO

說明

盡量不要插入與FOREIGN KEY條件約束衝突的資料行。否則可能導致將來資料表的有衝突的資料列無法被更新。

CHECK

CHECK條件約束用於限制資料行中值的允許範圍。條件約束中指定的布林（Boolean）搜尋條件傳回的是TRUE時，在資料行中插入或修改的值才算有效。例如，如果我們要限制items資料表的price資料行允許值的可能範圍在 $0.01到 $500.00之間，應該使用下面的陳述式：

    CREATE TABLE items
    (
    item_name       char(15)      NOT NULL,
    item_id         smallint      NOT NULL IDENTITY(1,1),
    price           smallmoney    NULL,
    item_desc       varchar(30)   NOT NULL DEFAULT 'none'
    CONSTRAINT      PK_item_id    PRIMARY KEY (item_id),
    CONSTRAINT      CK_price      CHECK (price >= .01 AND
                                  price <= 500.00)
    )
    GO

注意，我們在price資料行中允許NULL，且在資料行中有CHECK條件約束。由於SQL Server可以辨別NULL值和其他型別的值，所以儘管有CHECK條件約束，price資料行仍然可允許為NULL值。同時需要注意的是，我們將這個條件約束命名為CK_price。我們之前曾看到，將條件約束命名在稍後即可簡單地用T-SQL來刪除和重新建立條件約束。例如，把值的範圍修改為從 $1.00到 $1000.00之間，可以使用下面的陳述式：

    ALTER TABLE items
    DROP CONSTRAINT CK_price
    GO

    ALTER TABLE items
    ADD CONSTRAINT CK_price CHECK (price >= 1.00 AND
        price <= 1000.00)
    GO

第二個ALTER TABLE命令應該與第一次為現存的items資料表新增條件約束時所使用的命令相同。為現存資料表新增CHECK條件約束和新增FOREIGN KEY條件約束所遵守的規則是一樣的。所有現存的列將會根據條件約束來檢查，如果所有回傳的值不是TRUE，則無法將條件約束將新增到資料表中，而且SQL Server將回傳錯誤訊息：指出ALTER TABLE陳述式與CHECK條件約束衝突。如果一定要新增條件約束，使用WITH NOCHECK指定現存的資料列不生效，而將來插入和修改的資料列得以生效。

注意

不建議使用WITH NOCHECK，因為將來可能無法更新不符合條件約束的列。

下面是增加CK_price條件約束時使用WITH NOCHECK的一個例子：

    ALTER TABLE items
    WITH NOCHECK ADD CONSTRAINT CK_price
    CHECK (price >= 1.00    AND price <= 1000.00)
    GO

和FOREIGN KEY條件約束一樣，在ALTER TABLE中使用CHECK和NOCHECK關鍵字也可以控制CHECK條件約束是否生效。您可能想用這種方法插入一個超出指定範圍但依然有效的價格。下面的例子先停用CK_price條件約束，然後再使其生效：

    ALTER TABLE items
    NOCHECK CONSTRAINT CK_price   -- 使條件約束無效
    GO

    -- 在此插入資料列
    GO

    ALTER TABLE items
    CHECK CONSTRAINT CK_price     -- 重新啟用條件約束
    GO

說明

只有CHECK和FOREIGN KEY類型的條件約束可以用這種方式來控制是否生效。

用Enterprise Manager建立和修改條件約束

這部分將學習如何用Enterprise Manager設計資料表視窗來建立、修改和刪除條件約束，以及在FOREIGN KEY條件約束的情況下，建立資料庫圖表（在

第15章 介紹了如何建立資料庫圖表）。使用Enterprise Manager來建立新資料表或編輯現存資料表時，將顯示設計資料表視窗。要建立新資料表，在Enterprise Manager的左邊窗格中展開伺服器和資料庫資料夾，在資料表上按右鈕，從快顯功能表中選擇 新增 / 資料表 。要顯示現存資料表的 設計資料表 視窗，首先在左邊窗格中找出展開 資料表 ，在右邊窗格中的資料表名稱上按右鈕，然後從快顯功能表中選擇 設計資料表 。

允許NULL值

要指定資料行中是否允許NULL值，在 設計資料表 視窗中的 是否允許NULL 標題下簡單地選取或清除適當的核取方塊即可。您可以在建立資料表或修改資料表時設定這一選項。關於允許NULL值的規則請參見 第10章 。圖16-11顯示了本章前面 〈用T-SQL建立和修改資料表〉 我們曾經建立的customer資料表的 設計資料表 視窗。您可以看到mid_init和cust_phone兩個資料行允許NULL值，但其他三資料行不允許NULL值。

圖16-11 customer資料表設計資料表視窗的「是否允許NULL」資料行的設定

UNIQUE

1. 要使用Enterprise Manager來建立和修改條件約束，請遵循以下步驟：

   在 設計資料表 視窗中，在工具列中選擇 資料表索引屬性 按鈕（ 存檔 按鈕右邊的按鈕），在 屬性 對話方塊中選擇 索引/索引鍵 標籤頁。圖16-12顯示了customer資料表的 屬性 對話方塊中的 索引/索引鍵 標籤頁。

   使用下面的命令來建立這張資料表。資料表的SSN資料行包括一條作為叢集索引的UNIQUE條件約束（SQL Server自動替索引命名為UQ_customer_398D8EEE；您現在應可明白為條件約束及索引特別命名的好處）：

       CREATE TABLE customer
       (
       first_name      char(20)   NOT NULL,
       mid_init        char(1)    NULL,
       last_name       char(20)   NOT NULL,
       SSN             char(11)   NOT NULL UNIQUE CLUSTERED,
       cust_phone      char(10)   NULL
       )
       GO

   圖16-12 customer資料表的屬性對話方塊中的索引/索引鍵標籤頁

2. 要建立一個新的UNIQUE條件約束，在 屬性 對話方塊的 索引/索引鍵 標籤頁上按 新增 按鈕，選擇條件約束使用的資料行名稱，鍵入新的條件約束名稱，然後選擇 建立成唯一 - UNIQUE 核取方塊。如果要使它作為資料行的叢集索引，在資料表中選擇 建立成叢集 - CLUSTERED 核取方塊，並指定填滿因數。如果不要SQL Server定期地自動計算索引資料，則選取選取方塊旁的選項。
3. 您可以使用 屬性 對話方塊修改UNIQUE條件約束。例如，修改條件約束名稱、指定要新增到條件約束的資料行、設定叢集索引選項，以及為索引選擇填充因數等。（填滿因數將在 第17章 詳細介紹。）對條件約束進行修改，完成後按一下 關閉 按鈕，然後在Enterprise Manager中按 儲存 按鈕儲存修改。

主索引鍵

您可以為一或多個資料行指定一個主索引鍵（PRIMARY KEY）條件約束。按以下步驟指定一個PRIMARY KEY條件約束：

1. 在 設計資料表 視窗中，按一下某列中的儲存格來選擇某個資料行，或按住CTRL鍵，按一下資料行名稱左側的灰色方塊以同時選擇多個資料行。
2. 在所選的一個資料行上按右鈕，在快顯功能表中選擇 設定主索引鍵 。設定為主索引鍵的資料行左邊會出現一把小鑰匙。在把SSN資料行設定為主索引鍵後，顯示的視窗如圖16-13所示。我們也已經刪除了SSN資料行的UNIQUE條件約束，因為並不需要在同一資料行同時具有UNIQUE條件約束和PRIMARY KEY條件約束。

   圖16-13 在設計資料表視窗中設定PRIMARY KEY條件約束

- 如果要把PRIMARY KEY條件約束移動到另一資料行，只需要把新資料行設定為主索引鍵即可。您並不一定要先移除原來的主索引鍵，SQL Server將為您刪除和重新建立PRIMARY KEY索引。您也可以在 屬性 視窗中修改PRIMARY KEY索引。按一下工具列的 儲存 按鈕儲存操作後，修改就會生效。

說明

如果修改了包含資料的資料表中的PRIMARY KEY條件約束，重新建立索引可能會花費一定時間。若資料表中包含大量資料，欲對索引作較大的修改，例如變更資料行或叢集狀態，最好在資料庫的非使用高峰期進行這種操作。

外部索引鍵

要使用Enterprise Manager建立或修改FOREIGN KEY條件約束，可使用 設計資料表 視窗或建立與外部索引鍵有關聯性的資料庫圖表。最好在建立資料表時（或者至少在資料插入資料表之前）建立外部索引鍵關聯性。下面的例子將解釋這個原因。首先，會學習如何使用 設計資料表 來建立FOREIGN KEY條件約束。我們將利用本章前面建立的兩個資料庫資料表items和inventory來設定外部索引鍵關鍵性。我們會重新建立一個有PRIMARY KEY條件約束的item資料表（這是我們之前使用的），只是這次的item_id資料行沒有IDENTITY性質。因為我們需要一個item_id已經被更新的範例，而擁有IDENTITY性質的資料行需要較多的步驟才能進行更新。我們也會重新建立一個沒有FOREIGN KEY條件約束的inventory資料表，以方便我們稍後加入FOREIGN KEY條件約束。要建立上述的兩個資料表，請詳以下的陳述式：

    CREATE TABLE items
    (
    item_name       char(15)      NOT NULL,
    item_id         smallint      NOT NULL,
    price           smallmoney    NULL,
    item_desc       varchar(30)   NOT NULL DEFAULT 'none',
    CONSTRAINT      PK_item_id    PRIMARY KEY (item_id)
    )
    GO

    CREATE TABLE inventory
    (
    store_id        tinyint       NOT NULL,
    item_id         smallint      NOT NULL,
    item_quantity   tinyint       NOT NULL
    )
    GO

要在inventory資料表中增加FOREIGN KEY條件約束，請按照下列步驟：

1. 在Enterprise Manager右方視窗的inventory資料表名稱上按右鈕，選擇 設計資料表 。並在視窗的空白部份按右鈕，在快選功能表選取 關聯性 進入 關聯性 標籤頁，如圖16-14所示：

   圖16-14 Inventory資料表中屬性視窗內的關聯性標籤頁

- 按一下 新增 按鈕，預設值資料則會顯示在視窗內，如圖16-15所示。
- 此範例中，我們在 主索引鍵表 選取items，並選取item_id資料行作為items及inventory資料表的外部索引鍵。只要在剛才選取的資料表名稱下方空白的資料行部份按一下，即會出現下拉式選項。當選完所要關聯的資料表後， 關聯性名稱 的方塊內容就會改變，如圖16-16所示。

圖16-15 按一下新增之後「關聯性」標籤頁中預設的內容

圖16-16 「關聯性」標籤頁顯示items及inventory資料表的外部索引鍵關聯性

- 下面的視窗下方有幾個核取方塊，範例選項如圖16-17所示。若要SQL Server根據外部索引鍵的關聯性一併檢查已經存在的資料，須選取 建立時立即檢查現有資料 選項。此時資料如果不符，條件約束的建立就會失敗。在不需要檢查現有資料的情況下，您也可以選擇清除此方塊。但是若之後要更新或刪除已存在的列，就會遇到麻煩。

圖16-17 「關聯性」標籤頁顯示已經選取的選項

- 下一個選項是 複寫動作將使用此關聯性 。如果不要複寫，請勿選擇此選項。就算是要複寫，其實也不需要選取，因為原資料表中的資料皆根據條件約束檢查過，所以複寫時，可以不再檢視一次。如果仍選擇啟用，在這兩個相關聯資料表無法相互配合產生複寫資料表的情況下，在複寫進行時就會接收到錯誤訊息，告訴您複寫資料列的動作因違反外部索引鍵條件約束而無法執行。
- 接下來是 插入和更新動作將使用此關聯性 選項。選取此選項表示在插入、更新及刪除的動作時，FOREIGN KEY條件約束會同時接受檢視。選擇後以下的兩個核取方塊就會可以選取。
- 選擇 串聯更新相關欄位 表示當更新參考資料表中被引用的資料行時（例如：更新items資料表的item_id值），就會一併也更新外部索引鍵資料表（例如：inventory資料表中的item_id資料行，就會同時被更新－串聯更新）。在外部索引鍵資料表中，除了該資料行外，其餘資料行的資料將不會改變。如果您沒有選取這個選項，您將會無法更新外部索引鍵資料表的外部索引鍵資料行，SQL Server會傳送一個如下的錯誤訊息：「UPDATE陳述式與 'FK_inventory_items' 的COLUMN REFERENCE條件約束互相衝突。此衝突產生在'MyDB'資料庫，'inventory' 資料表，'item_id' 資料行。故此陳述式已終止。」
- 選擇 串聯刪除相關記錄 表示在參考資料表中的刪除動作一樣會刪除外部索引鍵資料表中的資料－串聯刪除。舉個例子，如果刪除items資料表中的資料列，那麼inventory資料表中擁有相同item_id值的資料列也會同時被刪除。這個動作會讓您的資訊保持一致性。如果您不選取此項目，您就無法更新有被外部索引鍵資料表引用的資料行。SQL Server會傳送一個如下的錯誤訊息：「DELETE陳述式與 'FK_inventory_items' 的COLUMN REFERENCE條件約束互相衝突。此衝突產生在 'MyDB' 資料庫，'inventory' 資料表，'item_id' 資料行。故此陳述式已終止。」
- 選取完畢後，在 設計資料表 視窗中按一下 關閉 ，然後按一下 儲存 鈕以儲存變更。另一個視窗會顯示，告訴您所列示的資料表將會儲存到資料庫，並顯示這兩個資料表外部索引鍵的關聯性。完成後，按一下 確定 ，然後在 設計資料表 （非Enterprise Manager視窗，否則Enterprise Manager會關閉）的右上方按一下 關閉 。

另外一個可以建立和修改FOREIGN KEY條件約束的方法是使用資料庫圖表。要學習如何使用資料庫圖表來建立和修改FOREIGN KEY條件約束，我們會利用上一個範例所使用的兩個資料表： items和inventory資料表，來建立一個圖表。首先看一下沒有外部索引鍵關聯性的資料庫圖表，然後再新增外部索引鍵關聯性。初始資料庫圖表如圖16-18所示。

圖16-18 包含items和inventory資料表的資料庫圖表

如圖16-18所示，items資料表的item_id資料行是主索引鍵資料行。它是能用於外部索引鍵資料表的唯一候選索引鍵（因為items資料表沒有其他的UNIQUE條件約束）。要建立inventory資料表的item_id資料行和items資料表的item_id資料行之間的外部索引鍵關聯性，按下面步驟進行：

1. 按住表示items資料表item_id資料行的列的左邊（灰色的方塊），將指標拖曳到inventory資料表上（您可以看到指標後面有一條虛線）。當指標指向inventory資料表的item_id列時鬆開滑鼠按鈕。此時將顯示 建立關聯性 對話方塊，如圖16-19。這對話方塊與之前所示的 設計資料表 視窗的 屬性 視窗相類似。對話方塊中資料表資料行將顯示item_id資料行，表示將在兩資料表之間的item_id資料行建立外部索引鍵關聯性。

   圖16-19 「建立關聯性」對話方塊中顯示所建議的外部索引鍵關聯性

- 您可以變更關聯性名稱，或者視需要選取或清除對話方塊下面的選項。這些選項在之前已為您介紹。
- 按一下 確定 以表示外部索引鍵關聯性的兩個資料表的圖表連接，如圖16-20所示（此步驟尚未儲存），會有一把小鑰匙從外部索引鍵資料表連接到主索引鍵資料表。
- 按一下 儲存 按鈕儲存修改。請輸入資料庫圖表的名稱，並確認相關資料表的更改。然後按一下 確定 即完成。

圖16-20 顯示外部索引鍵關聯性的資料庫圖表。

要修改現存的外部索引鍵，可使用此章節介紹的兩種方法。在 設計資料表 視窗中，只要再次開啟 關聯性 標籤頁進行、儲存修改即可。在資料庫圖表中，則在圖表的關聯性線條上按右鈕，選取 屬性 以更新條件約束，或者選取 從資料庫刪除關聯性 完全刪除條件約束。然後在依您所需增設一個新的。

CHECK

要使用 設計資料表 視窗建立CHECK條件約束，打開您所要的資料表的 設計資料表 視窗，然後按照以下的步驟執行：

1. 在視窗中按右鈕，從快顯功能表中選擇 屬性 來顯示 屬性 視窗。按一下 檢查條件約束 標籤頁，按一下 新增 ，如圖16-21所示。
2. 接下來輸入用於驗證插入或修改資料的運算式。在我們的例子中，於items資料表的price資料行新增CHECK條件約束，只有介於 $1.00和 $1000.00之間的值可以被插入到資料表中，如圖16-22所示。
3. 注意到三個在下方的選取方塊。第一個：選取 建立時立即檢查選取資料 選項，表示所有已經存在於資料表的資料皆要經過CHECK條件約束的檢視。不符合CHECK條件約束者，則無法建立條件約束。第二個：選取 複寫動作必須合乎條件約束 ，表示在複寫已經存在的資料時，因為此資料在輸入時已檢視過，所以複寫的資料不需要再檢視一次。第三個：選取 插入和更新動作必須合乎條件約束 ，表示要使CHECK條件約束生效。若沒有選取此選項，條件約束仍會設立，只是沒有設定生效，所以CHECK條件約束不會有作用。

   圖16-21 「屬性」視窗中的「檢查條件約束」標籤頁

圖16-22 在items資料表中新增price資料行的CHECK條件約束

若要更改CHECK條件約束，須至 檢查條件約束 標籤頁更新名稱、運算式，以及選項。如圖16-23顯示price資料行的CHECK條件約束從1到1000更新為1到99。

此時您應該可以看見 建立時立即檢查現有資料 選項的選取方塊已被清除，因為條件約束再之前已經設定了。若要根據變更後的範圍來驗證現存的資料，則應該選取此選項。若對現有資料的驗證失敗，則會得到錯誤訊息，更新的範圍則無法成立。您也可以在 選取的條件約束 下拉式清單中選擇想要刪除的條件約束，只要在 檢查條件約束 標籤頁按一下 刪除 按鈕來刪除條件約束即可。

規則物件

使用CHECK條件約束的另一種方式是建立 規則 物件，用以限制資料行中所插入和修改的數值範圍。規則物件類似於預設物件，其與資料表分開建立，而且在刪除資料表時也不同時刪除規則物件。您必須把規則物件建立繫結到資料行上或使用者自訂的型別上，本例使用sp_bindrule系統預存程序。和預設物件一樣，在SQL Server 2000保留規則物件是為了向後相容性的緣故。使用CHECK條件約束是條件約束資料行中數值範圍的最好辦法，但在需要對很多資料行或使用者自訂的資料型別應用相同的規則時，規則物件會比較方便。

用T-SQL建立規則物件

例如，讓我們建立一個和前面用CHECK條件約束建立的有相同的功能的規則物件。規則使用變數名稱 ＠price來引用items資料表的price資料行。變數名稱必須以 ＠ 符號開始，但是您可以任意選擇變數名稱。首先我們將建立規則，然後把它繫結到資料行上，如下所示：

    USE MyDB
    GO
    CREATE RULE price_rule AS
    (@price >= .01 AND @price <= 500.00)
    GO
    sp_bindrule "price_rule", "items.price", "futureonly"
    GO

要解除繫結並刪除該關聯，使用下面的陳述式:

    sp_unbindrule "items.price"
    GO
    DROP RULE price_rule
    GO

sp_bindrule和sp_unbindrule的參數與sp_bindefault和sp_unbindefault的參數相同（在本章前面的CREATE DEFAULT和sp_bindefault部分曾介紹過）。儘管您可以在相同的資料行或使用者自訂資料型別上同時分配一個規則和一個以上的CHECK條件約束，但是每一個資料行或一個使用者自訂型別只能有一個規則。如果您這樣做，SQL Server將對插入或修改的資料套用所有的條件約束。

使用Enterprise Manager建立規則物件

依照下列步驟，使用Enterprise Manager建立，並且繫結規則物件：

1. 在Enterprise Manager中展開伺服器和資料庫名稱，在 規則 上按右鈕，從快顯功能表中選擇 新增規則 ，顯示 規則屬性 對話方塊。在本例中，我們將規則命名為price_rule，並且新增文字，如圖16-24。按一下 確定 完成建立規則物件。
2. 要繫結規則，按一下Enterprise Manager左邊窗格中的 規則 ，在新規則名稱上按右鈕，從快顯功能表中選擇 屬性 顯示 規則屬性 視窗。和前面繫結預設物件一樣，按一下 繫結UDT 按鈕把規則繫結到使用者自訂資料型別上；或者按一下 繫結資料行 按鈕把規則繫結到資料行上。本例中，按一下 繫結資料行 ，選擇items資料表的price資料行來繫結規則，如圖16-25所示。

   圖16-24 建立規則的「規則屬性」視窗

圖16-25 繫結規則到資料行上

按一下 確定 套用規則，然後再按一下 確定 關閉 規則屬性 視窗。

要刪除規則，必須先從資料行上或使用者自訂資料型別上移除規則。移除規則後，在規則名稱上按右鈕，從快顯功能表中選擇 刪除 ，在 卸除物件 對話方塊中按一下 全部卸除 。如果要刪除的規則被繫結到任何物件上，SQL Server會出現錯誤訊息，表示該規則物件不能被刪除。

本章總結

本章中，我們學習了可以應用於資料行或資料表的預設值和條件約束的五種類型，以及如何使用T-SQL命令和Enterprise Manager來建立和修改預設值和條件約束。同時也學習了如何使用預設值和規則物件來建立和修改預設值和規則。如果沒有分配特定的值，預設值提供了一種為資料行指定預設值的方式。條件約束提供了幾種保持資料庫中資料完整性的不同方式。如果要在資料庫資料表中套用預設值和條件約束，就會發現它們是非常有用的工具。在

第17章 將學習如何使用SQL Server索引，包括叢集索引和非叢集索引，因為索引可以大大提高資料存取的效率。