CHECK约束
CHECK约束会检查输⼊到记录中的值是否满⾜⼀个条件,如果不满⾜这个条件则对数据库做的修改不会成功。⽐如,⼀个⼈的年龄是不可能为负数的,⼀个⼈的⼊学⽇期不可能早于出⽣⽇期,出⼚⽉份不可能⼤于12。可以在CHECK条件中使⽤任意有效的SQL表达式,CHECK约束对于插⼊、更新等任何对数据进⾏变化的操作都进⾏检查。
在字段定义后添加CHECK 表达式就可以为这个字段添加CHECK约束,⼏乎所有字段中都可以添加CHECK约束,也就是⼀张表中可以存在多个CHECK 约束。
下⾯的SQL语句创建了⼀张⽤于保存⼈员信息的表T_Person,其中字段FNumber 为⼈员编号,字段FName 为⼈员姓名,字段FAge为⼈员年龄,字段FWorkYear为⼈员⼯龄:
MYSQL,MSSQLServer,DB2:
CREATE TABLE T_Person (FNumber VARCHAR(20),FName VARCHAR(20),FAge INT CHECK(FAge >0),FWorkYear INT CHECK(FWorkYear>0))
Oracle:
CREATE TABLE T_Person (FNumber VARCHAR2(20),FName VARCHAR2(20),FAge NUMBER (10) CHECK(FAge >0),FWorkYear NUMBER (10) CHECK(FWorkYear>0))
⼀个⼈的年龄和⼯龄显然不应该为负值的,所以为FAge和FWorkYear两个字段增加了CHECK约束“FAge>0”和“FWeight>0”。表创建完毕后执⾏下⾯的SQL语句进⾏测试:
INSERT INTO T_Person(FNumber, FName, FAge, FWorkYear) VALUES("001","John",25,-3)
因为这⾥将FWorkYear字段设置成了-3,这是违反“CHECK(FWorkYear>0)”这个CHECK约束,所以在数据库中执⾏此SQL语句后数据库会报出下⾯错误信息:INSERT 语句与CHECK 约束"CKT_PersonFWorkY__24927208"冲突。该冲突发⽣于数据库"demo",表"dbo.T_Person", column "FWorkYear"。
⽽执⾏下⾯的SQL语句则可以成功执⾏:
INSERT INTO T_Person(FNumber, FName, FAge, FWorkYear) VALUES("001","John",25,3)
除了可以在CHECK 约束中使⽤常量表达式之外,还可以在CHECK 约束中使⽤函数,⽐如⼈员编号长度要⼤于12,那么就需要如下编写建表语句:
MYSQL,DB2:
CREATE TABLE T_Person (FNumber VARCHAR(20) CHECK (LENGTH(FNumber)>12),FName VARCHAR(20),FAge INT CHECK(FAge >0),FWorkYear INT CHECK(FWorkYear>0))
MSSQLServer:
CREATE TABLE T_Person (FNumber VARCHAR(20) CHECK (LEN(FNumber)>12),FName VARCHAR(20),FAge INT CHECK(FAge >0),FWorkYear INT CHECK(FWorkYear>0))
Oracle:
CREATE TABLE T_Person (FNumber VARCHAR2(20) CHECK (LENGTH(FNumber)>12),FName VARCHAR2(20),FAge NUMBER (10) CHECK(FAge >0),FWorkYear NUMBER (10) CHECK(FWorkYear>12))表创建完毕后执⾏下⾯的SQL语句进⾏测试:
INSERT INTO T_Person(FNumber, FName, FAge, FWorkYear) VALUES("001","John",25, 3)
因为这⾥将FNumber字段设置成了"001",这是违反“CHECK(LENGTH(FNumber)>12)”这个CHECK约束的,所以在数据库中执⾏此SQL语句后数据库会报出下⾯错误信息:
INSERT 语句与CHECK 约束"CKT_PersonFNumbe__267ABA7A"冲突。该冲突发⽣于数据库"demo",表"dbo.T_Person", column "FNumber"。
⽽执⾏下⾯的SQL语句则可以成功执⾏:
INSERT INTO T_Person(FNumber, FName, FAge, FWorkYear)VALUES("001001001001001","John",25,3)
这种直接在列定义中通过CHECK⼦句添加CHECK约束的⽅式的缺点是约束条件不能引⽤其他列。⽐如我们想约束“⼈员的⼯龄必须⼩于他的年龄”,那么我们执⾏下⾯的SQL语句:
MYSQL,DB2:
CREATE TABLE T_Person (FNumber VARCHAR(20),FName VARCHAR(20),FAge INT,FWorkYear INT CHECK(FWorkYear< FAge))
MSSQLServer:
CREATE TABLE T_Person (FNumber VARCHAR(20),FName VARCHAR(20),FAge INT,FWorkYear INT CHECK(FWorkYear< FAge))
Oracle:
CREATE TABLE T_Person (FNumber VARCHAR2(20),FName VARCHAR2(20),FAge NUMBER (10),FWorkYear NUMBER (10) CHECK(FWorkYear< FAge))
执⾏这个SQL语句以后,数据库会报出如下的错误信息:
表 "T_Person" 的列 "FWorkYear" 的列CHECK 约束引⽤了另⼀列。
出现这个错误的原因是因为在这种⽅式定义的CHECK⼦句中是不能引⽤其他列的,如果希望CHECK⼦句中的条件语句中使⽤其他列,则必须在CREATE TABLe 语句的末尾使⽤CONSTRAINT 关键字定义它。语法为:
CONSTRAINT 约束名 CHECK(约束条件)
重新编写上述的SQL语句,如下:
MYSQL,DB2:
CREATE TABLE T_Person (FNumber VARCHAR(20),FName VARCHAR(20),FAge INT,FWorkYear INT,CONSTRAINT ck_1 CHECK(FWorkYear< FAge))
MSSQLServer:
CREATE TABLE T_Person (FNumber VARCHAR(20),FName VARCHAR(20),FAge INT,FWorkYear INT,CONSTRAINT ck_1 CHECK(FWorkYear< FAge))
Oracle:
CREATE TABLE T_Person (FNumber VARCHAR2(20),FName VARCHAR2(20),FAge NUMBER (10),FWorkYear NUMBER (10),CONSTRAINT ck_1 CHECK(FWorkYear< FAge))
表创建完毕后执⾏下⾯的SQL语句进⾏测试:
INSERT INTO T_Person(FNumber, FName, FAge, FWorkYear) VALUES("001","John",25, 30)
因为这⾥将FWorkYear字段设置成了30,⽐如年龄25岁还⼤,这是违反“CHECK(FWorkYear<FAge)”这个CHECK约束的,所以在数据库中执⾏此SQL语句后数据库会报出下⾯错误信息:
db2数据库sql语句INSERT 语句与 CHECK 约束"ck_1"冲突。该冲突发⽣于数据库"demo",表"dbo.T_Person"。
⽽执⾏下⾯的SQL语句则可以成功执⾏:
INSERT INTO T_Person(FNumber, FName, FAge, FWorkYear) VALUES("001001001001001","John",25,3)
可以看到,这种定义CHECK约束的⽅式⼏乎与定义⼀个复合唯⼀约束的⽅式⼀致。同样,可以通过ALTER TABLE的⽅式为已经存在的数据表添加CHECK 约束。下⾯的SQL语句在T_Person上添加新的约束:
ALTER TABLE T_Person ADD CONSTRAINT ck_2 CHECK(FAge>14)
上⾯的SQL语句中为约束指定了显式的名称,所以可以通过下⾯的SQL语句将CHECK约束ck_2删除(这个语句在MYSQL中⽆效):
ALTER TABLE T_Person
DROP CONSTRAINT ck_2;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论