可在 ALTER COLUMN 语句中指定 NULL 以使 NOT NULL 列允许空值,但 PRIMARY KEY 约束中的列除外。只有列中不包含空值时,ALTER COLUMN 中才可指定 NOT NULL。必须将空值更新为非空值后,才允许执行 ALTER COLUMN NOT NULL 语句,比如:
UPDATE MyTable SET NullCol = N’some_value’ WHERE NullCol IS NULL
ALTER TABLE MyTable ALTER COLUMN NullCOl NVARCHAR(20) NOT NULL
如果 ALTER COLUMN 中指定了 NULL 或 NOT NULL,那么必须同时指定 new_data_type [(precision [, scale ])]。如果不更改数据类型、精度和小数位数,请指定列的这些值的当前值。
ROWGUIDCOL 属性并不强制列中所存储值的唯一性。该属性也不会为插入到表中的新行自动生成值。若要为每列生成唯一值,那么或者在 INSERT 语句中使用 NEWID 函数,或者将 NEWID 函数指定为该列的默认值。
ADD
指定要添加一个或多个列定义、计算列定义或者表约束。
computed_column_expression
是一个定义计算列的值的表达式。计算列是并不物理地存储在表中的虚拟列,该列用表达式计算得出,该表达式使用同一表中的其它列。例如,计算列的定义可以是:cost AS price * qty。表达式可以是非计算列的列名、常量、函数、变量,也可以是用一个或多个运算符连接的上述元素的任意组合。表达式不能为子查询。
计算列可用于选择列表、WHERE 子句、ORDER BY 字句或其它任何可以使用常规表达式的位置,但下列情况除外:
如果对 Customers 表的某行执行 UPDATE 语句,并且为 Orders.CustomerID 指定 ON UPDATE CASCADE 操作,则 SQL Server 将在 Orders 表中检查是否有与被更新行相关的一行或多行。如果存在相关行,那么 Orders 表中的相关行将随 Customers 表中的被引用行一同更新。
反之,如果指定了 NO ACTION,若在 Orders 表中至少存在一行引用 Customers 表中要更新的行,那么 SQL Server 将引发一个错误并回滚 Customers 表中的更新操作。
[ASC | DESC]
指定加入到表约束中的一列或多列的排序次序。默认设置为 ASC。
WITH VALUES
指定在添加到现有行的新列中存储 DEFAULT constant_expression 中所给定的值。只有在 ADD 列子句中指定了 DEFAULT 的情况下,才能使用 WITH VALUES。如果要添加的列允许空值且指定了 WITH VALUES,那么将在现有行的新列中存储默认值。如果没有指定 WITH VALUES 且列允许空值,那么将在现有行的新列中存储 NULL 值。如果新列不允许空值,那么不论是否指定 WITH VALUES,都将在现有行的新列中存储默认值。
如果 ALTER TABLE 语句指定更改其它表所引用的列值,那么根据引用表中 ON UPDATE 或者 ON DELETE 所指定的操作,将发生以下两个事件之一。
如果在引用表中没有指定值或指定了 NO ACTION(默认值),那么 ALTER TABLE 语句导致的更改父表中被引用列的操作将回滚,并且 SQL Server 将引发一个错误。
如果在引用表中指定了 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 个字节,所以产生该警告。当某 sql_variant 列所含值接近最大长度时,即会超过行长度的最大字节限制。
ALTER TABLE 语句对具有架构绑定视图的表执行时,所受限制与当前在更改具有简单索引的表时所受的限制相同。添加列是允许的。但是,不允许删除或更改参与架构绑定视图的表中的列。如果 ALTER TABLE 语句要求更改用在架构绑定视图中的列,更改操作将失败,并且 SQL Server 将引发一条错误信息。有关 SCHEMABINDING 和索引视图的更多信息,请参见 CREATE VIEW。
创建引用表的架构绑定视图不会影响在基表上添加或删除触发器。
当除去约束时,作为约束的一部分而创建的索引也将除去。而通过 CREATE INDEX 创建的索引必须使用 DROP INDEX 语句来除去。DBCC DBREINDEX 语句可用来重建约束定义的索引部分;而不必使用 ALTER TABLE 先除去再重新添加约束。
SQL Server 在列定义中并不强制以特定的顺序指定 DEFAULT、IDENTITY、ROWGUIDCOL 或列约束。
ALTER TABLE 的 ALTER COLUMN 子句并不会在列上绑定或取消绑定任何规则。必须分别使用 sp_bindrule 或 sp_unbindrule 来绑定或取消绑定规则。
可将规则绑定到用户定义数据类型。然后 CREATE TABLE 将自动在以该用户定义数据类型定义的列上绑定该规则。当用 ALTER COLUMN 更改列数据类型时,并不会取消绑定这些规则。原用户定义数据类型上的规则仍然绑定在该列上。在 ALTER COLUMN 更改了列的数据类型之后,随后执行的任何从该用户定义数据类型上取消绑定规则的 sp_unbindrule 都不会导致从更改了数据类型的列上取消绑定该规则。如果 ALTER COLUMN 将列的数据类型更改为绑定了规则的用户定义数据类型,那么绑定到新数据类型的规则不会绑定到该列。
权限 ALTER TABLE 权限默认授予表的所有者、sysadmin 固定服务器角色成员、db_owner 和 db_ddladmin 固定数据库角色成员且不可转让。
CREATE TABLE doc_exa ( column_a INT) GO ALTER TABLE doc_exa ADD column_b VARCHAR(20) NULL GO EXEC sp_help doc_exa GO DROP TABLE doc_exa GO
B. 更改表以除去列
下例修改表以删除一列。
CREATE TABLE doc_exb ( column_a INT, column_b VARCHAR(20) NULL) GO ALTER TABLE doc_exb DROP COLUMN column_b GO EXEC sp_help doc_exb GO DROP TABLE doc_exb GO
C. 更改表以添加具有约束的列
下例向表中添加具有 UNIQUE 约束的新列。
CREATE TABLE doc_exc ( column_a INT) GO ALTER TABLE doc_exc ADD column_b VARCHAR(20) NULL CONSTRAINT exb_unique UNIQUE GO EXEC sp_help doc_exc GO DROP TABLE doc_exc GO
D. 更改表以添加未验证的约束
下例向表中的现有列上添加约束。该列中存在一个违反约束的值;因此,利用 WITH NOCHECK 来防止对现有行验证约束,从而允许该约束的添加。
CREATE TABLE doc_exd ( column_a INT) GO INSERT INTO doc_exd VALUES (-1) GO ALTER TABLE doc_exd WITH NOCHECK ADD CONSTRAINT exd_check CHECK (column_a > 1) GO EXEC sp_help doc_exd GO DROP TABLE doc_exd GO
CREATE TABLE doc_exe ( column_a INT CONSTRAINT column_a_un UNIQUE) GO ALTER TABLE doc_exe ADD
/* Add a PRIMARY KEY identity column. */ column_b INT IDENTITY CONSTRAINT 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_chk CHECK (column_d IS NULL OR column_d LIKE “[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]” OR column_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_default DEFAULT .081 GO EXEC sp_help doc_exe GO DROP TABLE doc_exe GO
F. 添加具有默认值的可为空的列
下例添加可为空的、具有 DEFAULT 定义的列,并使用 WITH VALUES 为表中的各现有行提供值。如果没有使用 WITH VALUES,那么每一行的新列中都将具有 NULL 值。
ALTER TABLE MyTable ADD AddDate smalldatetime NULL CONSTRAINT AddDateDflt DEFAULT getdate() WITH VALUES
G. 禁用并重新启用一个约束
下例禁用用于限制可接受的薪水数据的约束。WITH NOCHECK CONSTRAINT 与 ALTER TABLE 一起使用,以禁用该约束并使正常情况下会引起约束违规的插入操作得以执行。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 inserts INSERT 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_cap INSERT INTO cnst_example VALUES (3,”Pat Jones”,105000)
— Reenable the constraint and try another insert, will fail. ALTER TABLE cnst_example CHECK CONSTRAINT salary_cap INSERT INTO cnst_example VALUES (4,”Eric James”,110000)
H. 禁用并重新启用触发器
下例使用 ALTER TABLE 的 DISABLE TRIGGER 选项来禁用触发器,以使正常情况下会违反触发器条件的插入操作得以执行。然后下例使用 ENABLE TRIGGER 重新启用触发器。
CREATE TABLE trig_example (id INT, name VARCHAR(10), salary MONEY) go — Create the trigger. CREATE TRIGGER trig1 ON trig_example FOR INSERT as IF (SELECT COUNT(*) FROM INSERTED WHERE salary > 100000) > 0 BEGIN print “TRIG1 Error: you attempted to insert a salary > $100,000” ROLLBACK TRANSACTION END GO — 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 trig1 GO — Attempt an insert that would normally violate the trigger INSERT INTO trig_example VALUES (2,”Chuck Jones”,100001) GO — Re-enable the trigger. ALTER TABLE trig_example ENABLE TRIGGER trig1 GO — Attempt an insert that violates the trigger. INSERT INTO trig_example VALUES (3,”Mary Booth”,100001) GO