CHECK 约束的限制 CHECK 约束不接受计算结果为 FALSE 的值。因为空值的计算结果为 UNKNOWN,所以表达式中存在这些值可能会覆盖约束。例如,假设对 int 列 MyColumn 应用一个约束,指定 MyColumn 只能包含值 10(即 MyColumn = 10)。如果将值 NULL 插入到 MyColumn,数据库引擎将插入 NULL 且不返回错误。如果 CHECK 约束检查的条件对于表中的任何行都不是 FALSE,它将返回 TRUE。如果刚创建的表没有任何行,则此表的任何 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 语句将成功。执行 DELETE 语句时不验证 CHECK 约束。因此,使用特定类型的 CHECK 约束对表执行 DELETE 语句时可能会产生意外结果。例如,假设对表 CheckTbl 执行下列语句。 复制代码 INSERT INTO CheckTbl VALUES (10, 10) GO DELETE CheckTbl WHERE col1 = 10;即使 CHECK 约束指定表 CheckTbl 必须至少包含 1 行,DELETE 语句也会成功。
1)禁止所有表约束的SQL select 'alter table '+name+' nocheck constraint all' from sysobjects where type='U'2)删除所有表数据的SQL select 'TRUNCATE TABLE '+name from sysobjects where type='U'3)恢复所有表约束的SQL select 'alter table '+name+' check constraint all' from sysobjects where type='U'4)删除某字段的约束 declare @name varchar(100) --DF为约束名称前缀 select @name=b.name from syscolumns a,sysobjects b where a.id=object_id('表名') and b.id=a.cdefault and a.name='字段名' and b.name like 'DF%' --删除约束 alter table 表名 drop constraint @name --为字段添加新默认值和约束 ALTER TABLE 表名 ADD CONSTRAINT @name DEFAULT (0) FOR [字段名] 对字段约束进行更改 --删除约束 ALTER TABLE tablename Drop CONSTRAINT 约束名 --修改表中已经存在的列的属性(不包括约束,但可以为主键或递增或唯一) ALTER TABLE tablename alter column 列名 int not null --添加列的约束 ALTER TABLE tablename ADD CONSTRAINT DF_tablename_列名 DEFAULT(0) FOR 列名 --添加范围约束 alter table tablename add check(性别 in ('M','F'))
create table t (ID int constraint U_T check(ID>10)) --or create table t (ID int) alter table t add constraint U_T check(ID>10)
create table tb(ID int ,[name]varchar(10) check (abc in('PAN','ABO','KKK')))
go
create table tb(ID int ,sex varchar(10) check( sex in('男','女')))
包括隐式或显式数据类型转换的约束可能会导致某些操作失败。例如,为表定义的作为分区切换的源的此类约束可能会导致 ALTER TABLE...SWITCH 操作失败。在约束定义中避免数据类型转换。
CHECK 约束的限制
CHECK 约束不接受计算结果为 FALSE 的值。因为空值的计算结果为 UNKNOWN,所以表达式中存在这些值可能会覆盖约束。例如,假设对 int 列 MyColumn 应用一个约束,指定 MyColumn 只能包含值 10(即 MyColumn = 10)。如果将值 NULL 插入到 MyColumn,数据库引擎将插入 NULL 且不返回错误。如果 CHECK 约束检查的条件对于表中的任何行都不是 FALSE,它将返回 TRUE。如果刚创建的表没有任何行,则此表的任何 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 语句将成功。执行 DELETE 语句时不验证 CHECK 约束。因此,使用特定类型的 CHECK 约束对表执行 DELETE 语句时可能会产生意外结果。例如,假设对表 CheckTbl 执行下列语句。 复制代码
INSERT INTO CheckTbl VALUES (10, 10)
GO
DELETE CheckTbl WHERE col1 = 10;即使 CHECK 约束指定表 CheckTbl 必须至少包含 1 行,DELETE 语句也会成功。
select 'alter table '+name+' nocheck constraint all' from sysobjects where type='U'2)删除所有表数据的SQL
select 'TRUNCATE TABLE '+name from sysobjects where type='U'3)恢复所有表约束的SQL
select 'alter table '+name+' check constraint all' from sysobjects where type='U'4)删除某字段的约束
declare @name varchar(100)
--DF为约束名称前缀
select @name=b.name from syscolumns a,sysobjects b where a.id=object_id('表名') and b.id=a.cdefault and a.name='字段名' and b.name like 'DF%'
--删除约束
alter table 表名 drop constraint @name
--为字段添加新默认值和约束
ALTER TABLE 表名 ADD CONSTRAINT @name DEFAULT (0) FOR [字段名] 对字段约束进行更改
--删除约束
ALTER TABLE tablename
Drop CONSTRAINT 约束名
--修改表中已经存在的列的属性(不包括约束,但可以为主键或递增或唯一)
ALTER TABLE tablename
alter column 列名 int not null
--添加列的约束
ALTER TABLE tablename
ADD CONSTRAINT DF_tablename_列名 DEFAULT(0) FOR 列名
--添加范围约束
alter table tablename add check(性别 in ('M','F'))
--or
create table t (ID int)
alter table t add constraint U_T check(ID>10)