可在 ALTER COLUMN 語句中指定 NULL 以使 NOT NULL 列允許空值,但 PRIMARY KEY 約束中的列除外。只有列中不包含空值時,ALTER COLUMN 中才可指定 NOT NULL。必須將空值更新為非空值后,才允許執(zhí)行 ALTER COLUMN NOT NULL 語句,比如:
UPDATE MyTable SET NullCol = N'some_value' WHERE NullCol IS NULLALTER TABLE MyTable ALTER COLUMN NullCOl NVARCHAR(20) NOT NULL 如果 ALTER COLUMN 中指定了 NULL 或 NOT NULL,那么必須同時指定 new_data_type [(precision [, scale ])]。如果不更改數(shù)據(jù)類型、精度和小數(shù)位數(shù),請指定列的這些值的當前值。
ROWGUIDCOL 屬性并不強制列中所存儲值的唯一性。該屬性也不會為插入到表中的新行自動生成值。若要為每列生成唯一值,那么或者在 INSERT 語句中使用 NEWID 函數(shù),或者將 NEWID 函數(shù)指定為該列的默認值。
ADD
指定要添加一個或多個列定義、計算列定義或者表約束。
computed_column_expression
是一個定義計算列的值的表達式。計算列是并不物理地存儲在表中的虛擬列,該列用表達式計算得出,該表達式使用同一表中的其它列。例如,計算列的定義可以是:cost AS price * qty。表達式可以是非計算列的列名、常量、函數(shù)、變量,也可以是用一個或多個運算符連接的上述元素的任意組合。表達式不能為子查詢。
計算列可用于選擇列表、WHERE 子句、ORDER BY 字句或其它任何可以使用常規(guī)表達式的位置,但下列情況除外:
如果對 Customers 表的某行執(zhí)行 UPDATE 語句,并且為 Orders.CustomerID 指定 ON UPDATE CASCADE 操作,則 SQL Server 將在 Orders 表中檢查是否有與被更新行相關的一行或多行。如果存在相關行,那么 Orders 表中的相關行將隨 Customers 表中的被引用行一同更新。
反之,如果指定了 NO ACTION,若在 Orders 表中至少存在一行引用 Customers 表中要更新的行,那么 SQL Server 將引發(fā)一個錯誤并回滾 Customers 表中的更新操作。
[ASC | DESC]
指定加入到表約束中的一列或多列的排序次序。默認設置為 ASC。
WITH VALUES
指定在添加到現(xiàn)有行的新列中存儲 DEFAULT constant_expression 中所給定的值。只有在 ADD 列子句中指定了 DEFAULT 的情況下,才能使用 WITH VALUES。如果要添加的列允許空值且指定了 WITH VALUES,那么將在現(xiàn)有行的新列中存儲默認值。如果沒有指定 WITH VALUES 且列允許空值,那么將在現(xiàn)有行的新列中存儲 NULL 值。如果新列不允許空值,那么不論是否指定 WITH VALUES,都將在現(xiàn)有行的新列中存儲默認值。
如果 ALTER TABLE 語句指定更改其它表所引用的列值,那么根據(jù)引用表中 ON UPDATE 或者 ON DELETE 所指定的操作,將發(fā)生以下兩個事件之一。
如果在引用表中沒有指定值或指定了 NO ACTION(默認值),那么 ALTER TABLE 語句導致的更改父表中被引用列的操作將回滾,并且 SQL Server 將引發(fā)一個錯誤。
如果在引用表中指定了 CASCADE,那么由 ALTER TABLE 語句導致的對父表的更改將應用于父表及其相關表。 添加 sql_variant 列的 ALTER TABLE 語句會生成下列警告:
The total row size (xx) for table 'yy' exceeds the maximum number of bytes per row (8060). Rows that exceed the maximum number of bytes will not be added. 因為 sql_variant 的最大長度為 8016 個字節(jié),所以產(chǎn)生該警告。當某 sql_variant 列所含值接近最大長度時,即會超過行長度的最大字節(jié)限制。
ALTER TABLE 語句對具有架構綁定視圖的表執(zhí)行時,所受限制與當前在更改具有簡單索引的表時所受的限制相同。添加列是允許的。但是,不允許刪除或更改參與架構綁定視圖的表中的列。如果 ALTER TABLE 語句要求更改用在架構綁定視圖中的列,更改操作將失敗,并且 SQL Server 將引發(fā)一條錯誤信息。
創(chuàng)建引用表的架構綁定視圖不會影響在基表上添加或刪除觸發(fā)器。
當除去約束時,作為約束的一部分而創(chuàng)建的索引也將除去。而通過 CREATE INDEX 創(chuàng)建的索引必須使用 DROP INDEX 語句來除去。DBCC DBREINDEX 語句可用來重建約束定義的索引部分;而不必使用 ALTER TABLE 先除去再重新添加約束。
SQL Server 在列定義中并不強制以特定的順序指定 DEFAULT、IDENTITY、ROWGUIDCOL 或列約束。
ALTER TABLE 的 ALTER COLUMN 子句并不會在列上綁定或取消綁定任何規(guī)則。必須分別使用 sp_bindrule 或 sp_unbindrule 來綁定或取消綁定規(guī)則。
可將規(guī)則綁定到用戶定義數(shù)據(jù)類型。然后 CREATE TABLE 將自動在以該用戶定義數(shù)據(jù)類型定義的列上綁定該規(guī)則。當用 ALTER COLUMN 更改列數(shù)據(jù)類型時,并不會取消綁定這些規(guī)則。原用戶定義數(shù)據(jù)類型上的規(guī)則仍然綁定在該列上。在 ALTER COLUMN 更改了列的數(shù)據(jù)類型之后,隨后執(zhí)行的任何從該用戶定義數(shù)據(jù)類型上取消綁定規(guī)則的 sp_unbindrule 都不會導致從更改了數(shù)據(jù)類型的列上取消綁定該規(guī)則。如果 ALTER COLUMN 將列的數(shù)據(jù)類型更改為綁定了規(guī)則的用戶定義數(shù)據(jù)類型,那么綁定到新數(shù)據(jù)類型的規(guī)則不會綁定到該列。
權限 ALTER TABLE 權限默認授予表的所有者、sysadmin 固定服務器角色成員、db_owner 和 db_ddladmin 固定數(shù)據(jù)庫角色成員且不可轉讓。
示例 A. 更改表以添加新列 下例添加一個允許空值的列,而且沒有通過 DEFAULT 定義提供值。各行的新列中的值將為 NULL。
CREATE TABLE doc_exe ( column_a INT CONSTRAINT column_a_un UNIQUE) GOALTER TABLE doc_exe ADD /* Add a PRIMARY KEY identity column. */ column_b INT IDENTITYCONSTRAINT column_b_pk PRIMARY KEY, /* Add a column referencing another column in the same table. */ column_c INT NULL CONSTRAINT column_c_fk REFERENCES doc_exe(column_a),/* Add a column with a constraint to enforce that */ /* nonnull data is in a valid phone number format. */column_d VARCHAR(16) NULL CONSTRAINT column_d_chkCHECK (column_d IS NULL OR column_d LIKE "[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]" ORcolumn_d LIKE"([0-9][0-9][0-9]) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]"),/* Add a nonnull column with a default. */ column_e DECIMAL(3,3)CONSTRAINT column_e_defaultDEFAULT .081GOEXEC sp_help doc_exeGODROP TABLE doc_exeGO F. 添加具有默認值的可為空的列 下例添加可為空的、具有 DEFAULT 定義的列,并使用 WITH VALUES 為表中的各現(xiàn)有行提供值。如果沒有使用 WITH VALUES,那么每一行的新列中都將具有 NULL 值。
ALTER TABLE MyTable ADD AddDate smalldatetime NULLCONSTRAINT AddDateDfltDEFAULT getdate() WITH VALUES G. 禁用并重新啟用一個約束 下例禁用用于限制可接受的薪水數(shù)據(jù)的約束。WITH NOCHECK CONSTRAINT 與 ALTER TABLE 一起使用,以禁用該約束并使正常情況下會引起約束違規(guī)的插入操作得以執(zhí)行。WITH CHECK CONSTRAINT 重新啟用該約束。
CREATE TABLE cnst_example (id INT NOT NULL, name VARCHAR(10) NOT NULL, salary MONEY NOT NULL CONSTRAINT salary_cap CHECK (salary 100000))-- Valid insertsINSERT INTO cnst_example VALUES (1,"Joe Brown",65000)INSERT INTO cnst_example VALUES (2,"Mary Smith",75000)-- This insert violates the constraint.INSERT INTO cnst_example VALUES (3,"Pat Jones",105000)-- Disable the constraint and try again.ALTER TABLE cnst_example NOCHECK CONSTRAINT salary_capINSERT INTO cnst_example VALUES (3,"Pat Jones",105000)-- Reenable the constraint and try another insert, will fail.ALTER TABLE cnst_example CHECK CONSTRAINT salary_capINSERT INTO cnst_example VALUES (4,"Eric James",110000) H. 禁用并重新啟用觸發(fā)器 下例使用 ALTER TABLE 的 DISABLE TRIGGER 選項來禁用觸發(fā)器,以使正常情況下會違反觸發(fā)器條件的插入操作得以執(zhí)行。然后下例使用 ENABLE TRIGGER 重新啟用觸發(fā)器。
CREATE TABLE trig_example (id INT, name VARCHAR(10),salary MONEY)go-- Create the trigger.CREATE TRIGGER trig1 ON trig_example FOR INSERTas IF (SELECT COUNT(*) FROM INSERTEDWHERE salary > 100000) > 0BEGINprint "TRIG1 Error: you attempted to insert a salary > $100,000"ROLLBACK TRANSACTIONENDGO-- Attempt an insert that violates the trigger.INSERT INTO trig_example VALUES (1,"Pat Smith",100001)GO-- Disable the trigger.ALTER TABLE trig_example DISABLE TRIGGER trig1GO-- Attempt an insert that would normally violate the triggerINSERT INTO trig_example VALUES (2,"Chuck Jones",100001)GO-- Re-enable the trigger.ALTER TABLE trig_example ENABLE TRIGGER trig1GO-- Attempt an insert that violates the trigger.INSERT INTO trig_example VALUES (3,"Mary Booth",100001)GO