1.Check Constraints
我相信大部分的朋友对约束的概念理解应该都是Check类型的约束,这种约束对表中的某一列的格式或者值
进行限制,只有满足条件的数据才能被写入。比如:
create table Goods
(
GoodsID int identity(1,1) primary key,
Price decimal(12,4) constraint chkPrice check (Price>1000)
)
上面的SQL建立了一张新表,并且对表中的列Price建立一个check约束,名叫chkPrice,它的作用就是对插
入price列数据进行判断,如果大于1000,满足条件就插入,否则就报错。
insert into Goods values(2000) (1 row(s) affected) 成功
insert into Goods values(200) ERROR:The INSERT statement conflicted with the CHECK
constraint "chkPrice". The conflict occurred in database "AdventureWorks", table "dbo.Goods",
column 'Price'.
这里顺便提一下,如果我们执行了下面的代码,结果会是怎样呢?
insert into goods values(null)
如果你觉得也会报错,那么恭喜你,你错了。约束其实是对满足条件,即条件表达式返回TRUE的一律通过。
那么,如果结果是NULL呢?NULL在SQL SERVER里的类型是UNKNOWN,就是不知道。那我们就要把它理解成可以成
为任何类型,可能为TRUE。所以在这个例子中,NULL是可以被插入的。
2.Default Constraints
这个约束相对简单一些,就是事先定义一个默认值,如果在插入数据的时候没有指定,系统会自动把事先定
义好的默认值写入对应的列。
create table Product(
ProductID int identity(1,1) primary key,
ProductName varchar(80) not null,
Country varchar(40) default 'China'
)
Country这列就是一个含有Default约束的列,如果在插入一条数据的时候没有指定值,那么系统会默认的插
入China.
insert into product values('AAA','US')
insert into product(ProductName) values('BBB')
结果为
1 AAA US
2 BBB China
3.Unique Constraints
Unique就是独有的,这个约束就是确保在非主键列中不输入重复的值。这一点与主键的概念可能有一些类似
,之所以把Unique放在前面说,就是为了强调一点,如果想强制一列或者多列的组合的唯一性时,应该选择
Unique而不是主键。
同时,还有一点,主键不能为null,但是Unique可以支持null。
alter table product add ProductCode int null constraint pc_unique unique
我们对Product表中的ProductCode列设置了unique约束,这一列的值不可重复.但允许有空值存在.
insert into product (productname,ProductCode) values('aaa',null)
OK
第一个空值插入成功
insert into product (productname,ProductCode) values('bbb',null)
ERROR:Violation of UNIQUE KEY constraint 'pc_unique'. Cannot insert duplicate key in object
'dbo.product'. 第二个空值插入失败
4.Primary Key Constraints
主键约束可能是大家最为熟悉的,在数据库的设计中,我们基本上会对每一张表建一个主键约束,用以把数据
库的每条记录(行)区分开来.主键可以针对表中的一列或多列。但与约束不同的是,它的值不能为空。
下面的例子是对其中一列设置主键:
Create Table Users(
UserID int primary key,
UserName varchar(50) not null
)
下面是对多列设置主键:
CREATE TABLE KeyData
(
FiscalYear int not null,
Period int not null,
DataType int not null,
KeyValue int not null
CONSTRAINT [PK_constraint_keydata] PRIMARY KEY CLUSTERED (
FiscalYear,
Period
)
)
5.Foreign Key Constraints
前面提到约束分语义上限制和属性关系的限制,外键约束就是用来限制属性间关系的。通俗一点讲,就是一
张表中的某列引用了另一张表的主键,因为该列的值必须出自主键列的值。
Create table Manager
(
ManagerID int primary key,
ManagerName varchar(50),
)
上面我们建立了一个Manager的表,有一个ID列是该表的主键,唯一代表了每一个经理。
下面建立了销售区域的表,并指定每个区域有一个经理负责:
Create Table SalesRegion
(
SalesRegionID int Primary Key,
SalesRegionName varchar(100),
ManagerID int foreign key REFERENCES Manager(ManagerID)
)
从上面的命令中可以看出,ManagerID就是外键,它的作用是连接了SalesRegion与Manager两张表,限制
ManagerID在表SalesRegion中的使用,我们不能把某个区域指定给一个不存在经理负责。如果我们试图往
SalesRegion插入一条记录,而该记录的ManagerID是Manager表中不存在的ManagerID,系统就会报出以下的错误
:
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK__SalesRegi__Manag__3F6663D5". The conflict occurred in database "AdventureWorks", table
"dbo.Manager", column 'ManagerID'.
==================================================================================================
一、约束
约束定义关于列中允许值的规则,是强制完整性的标准机制。
使用约束优先于使用触发器、规则和默认值。查询优化器也使用约束定义生成高性能的查询执行计划。
SQL Server 2005支持五类约束:
1. NOT NULL指定不接受NULL值的列。
2. CHECK 约束对可以放入列中的值进行限制,以强制执行域的完整性。CHECK约束拒绝所有在检测条件中
取值为false的值。可以为每列指定多个CHECK约束。下例显示名为chk_id约束的创建,该约束确保只对此关键字
输入指定范围内的数字,以进一步强制执行主键的域。
CREATE TABLE cust_sample
(
cust_id int PRIMARY KEY,
cust_name char(50),
cust_address char(50),
cust_credit_limit money,
CONSTRAINT chk_id CHECK(cust_id BETWEEN 0 and 10000)
)
3. UNIQUE约束:对于 UNIQUE 约束中的列,表中不允许有两行包含相同的非空值。主键也强制执行唯一性
,但主键不允许空值。UNIQUE 约束优先于唯一索引。
4. PRIMARY KEY 约束标识列或列集,这些列或列集的值唯一标识表中的行。在一个表中,不能有两行包
含相同的主键值。不能在主键内的任何列中输入NULL值。在数据库中NULL是特殊值,代表不同于空白和0值的未
知值。建议使用一个小的整数列作为主键。每个表都应有一个主键。
一个表中可以有一个以上的列组合,这些组合能唯一标识表中的行,每个组合就是一个候选键。数据库管
理员从候选键中选择一个作为主键。例如,在part_sample表中,part_nmbr和part_name都可以是候选键,但是
只将part_nmbr选作主键。
CREATE TABLE part_sample
(
part_nmbr int PRIMARY KEY,
part_name char(30),
part_weight decimal(6,2),
part_color char(15)
)
5. FOREIGN KEY约束标识表之间的关系。
一个表的外键指向另一个表的候选键。当外键值没有候选键时,外键可防止操作保留带外键值的行。在下例中
,order_part 表建立一个外键引用前面定义的part_sample表。通常情况下,order_part在order表上也有一
个外键,下面只不过是一个简单示例。
CREATE TABLE order_part
(
order_nmbr int,
part_nmbr int
FOREIGN KEY REFERENCES part_sample(part_nmbr) ON DELETE NO ACTION,
qty_ordered int
)
如果一个外键值没有候选键,则不能插入带该值(NULL除外)的行。如果尝试删除现有外键指向的行,ON
DELETE子句将控制所采取的操作。
ON DELETE子句有两个选项:
A、NO ACTION指定删除因错误而失败。
B、CASCADE 指定还将删除包含指向已删除行的外键的所有行。
如果尝试更新现有外键指向的候选键值,ON UPDATE 子句将定义所采取的操作。它也支持NO ACTION和CASCADE
选项。
列约束和表约束
约束可以是列约束或表约束:
列约束被指定为列定义的一部分,并且仅适用于那个列(前面的示例中的约束就是列约束)。
表约束的声明与列的定义无关,可以适用于表中一个以上的列。
当一个约束中必须包含一个以上的列时,必须使用表约束。
例如,如果一个表的主键内有两个或两个以上的列,则必须使用表约束将这两列加入主键内。假设有一个表记
录工厂内的一台计算机上所发生的事件。假定有几类事件可以同时发生,但不能有两个同时发生的事件属于同一
类型。这一点可以通过将type列和time列加入双列主键内来强制执行。
CREATE TABLE factory_process
(
event_type int,
event_time datetime,
event_site char(50),
event_desc char(1024),
CONSTRAINT event_key PRIMARY KEY(event_type,event_time)
)
二、规则:
规则是一个向后兼容的功能,用于执行一些与CHECK约束相同的功能。CHECK约束是用来限制列值的首选标准
方法。CHECK约束比规则更简明,一个列只能应用一个规则,但是却可以应用多个CHECK约束。CHECK约束作为
CREATE TABLE 语句的一部分进行指定,而规则以单独的对象创建,然后绑定到列上。
下例创建一个规则,执行与前面主题中的CHECK约束示例相同的功能。SQL Srver2005 首选的方法是
CHECK 约束。
CREATE RULE id_chk AS @id BETWEEN 0 and 10000
GO
CREATE TABLE cust_sample
(
cust_id int
PRIMARY KEY,
cust_name char(50),
cust_address char(50),
cust_credit_limit money,
)
GO
sp_bindrule id_chk,'cust_sample.cust_id'
GO