一、SQL约束
约束定义关于列中允许值的规则,是强制完整性的标准机制。 

      使用约束优先于使用触发器、规则和默认值。查询优化器也使用约束定义生成高性能的查询执行计划。



1:类型 
约束的类型一共分三种 
域约束: 涉及一个或多个列,(限制某一列的数据大于0) 
实体约束: 相同的值不能存在于其他的行中 
引用完整性约束: 一个表中的一个列与某个表中的另一个列的值匹配 
2:命名 
约束是可以命名的 一般这样命名: 
pk_customer_*** 
pk代表主键 customer代表主键所在的表后面是你自己定义的(要确保整个名称的唯一性) 
3:主键约束 
主键约束:一般就是id, 一个表中最多有一个主键 
例子1 
use accounting 
create table employee 
(id int identity not null, 
firstname varchar(20) not null 
) 
例子2 
use accounting 
alter table employee 
add constraint pk_employeeid 
primary key (id) 

4:外键约束 
外键约束用在确保数据完整性和两个表之间的关系上 
先看例子 
create table orders 
( 
id int identity not null primary key, 
customerid int not null foreign key references customer(id), 
orderdate smalldatetime not null, 
eid int not null 
) 
注意:这个表的外键必须是另一个表的主键! 
在现有表上添加外键 
alter table orders 
add constraint fk_employee_creator_order 
foreign key (eid) references employee(employeeid) 
使用表自引用 
表内至少要有一行数据才可以这么做 
alter table employee 
add constraint fk_employee_has_manager 
foreign key (managerid) references employee(employeeid) 
创建表的时候做表自引用 就可以忽略 foreign key 语句 
表自引用的外键列 必须允许为null 要不是不允许插入的(避免对最初行的需要) 

一个表与另一个表有约束,这个表是不能被删除的 
级联操作 
先看例子 
create table orderdetails 
( 
orderid int not null , 
id int not null , 
description varchar(123) not null, 
--设置主键 
constraint pkOrderdetails primary key (orderid,id), 
--设置外键,级联操作 
constraint fkOrderContainsDetails 
foreign key (orderid) 
references orders(orderid) 
on update no action 
on delete cacade 
)on delete cacade 当删除父记录时 同时删除该记录 
也就是当删除orders表中的一条记录, 
与之相关的orderdetails表中的记录也将被删除 
级联的深度是没有限制的,但是每个外键都必须设置on delete cacade 
no action是可选的 

5:unique约束 
unique约束与主键约束类似,同样也是要求指定的列有唯一的值 
但是一个表中可以有多个unique约束的列,同时这个列允许存在null值。(最多有一个null值) 
看例子: 
create table shippers 
( 
id int indentity not null primery key, 
zip varchar(10) not null , 
phoneno varchar(14) not null unique) 
例子二: 
alter table employee 
add constraint ak_employeeSSN 
unique(ssn) 

6:check约束 
check不局限于一个特定的列,可以约束一个列,也可以通过某个列来约束另一个列 
定义check约束使用的规则与where子句中的基本一样 
下面我写几个 
between 1 and 12 
like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]' 
in ('ups','fed ex','usps') 
price >=0 
shipdate >= orderdate 
看例子: 
alter table customers 
add constraint cn_customerDateinsystem 
check 
(dateinsystem <= getdate()) 
getdate()函数得到当前时间,上面这个例子的意思是dateinsystem列的数据不能大于当前时间 
现在如果给这个列插入一个明天的时间,就会出错 

7:default约束 
如果插入的新行在定义了默认值的列上没有给出值,那么这个列上的数据就是定义的默认值 
默认值只在insert语句中使用 
如果插入的记录给出了这个列的值,那么该列的数据就是插入的数据 
如果没有给出值,那么该列的数据总是默认值 

8:禁用约束 
在创建约束之前,数据库中已经有一些不符合规矩的数据存在。 
创建约束之后,又想加入一些不符合规矩的数据。 
这些时候就要禁用约束。primary key 和 unique约束 这对孪生约束是不能禁用的 
对一个已经存在数据的表加一个约束: 
alter table customers 
add constraint cn_customerPhoneNo 
check 
(phone like '([0-9][0-9][0-9])[0-9][0-9][0-9][0-9][0-9][0-9]') 
如果表内有不符合这个约束的记录,sqlserver就会报错 
如果这样写,就不会报错了 
alter table customers 
with no check 
add constraint cn_customerPhoneNo 
check 
(phone like '([0-9][0-9][0-9])[0-9][0-9][0-9][0-9][0-9][0-9]') 
如果需要把一些不符合规矩的数据加入到表中怎么办这时候就需要临时禁用现有的约束: 
alter table customers 
nocheck 
constraint cn_customerPhoneNo 
--允许不带套插入,此处的名称是前面定义的 
insert into customer (phone) values (123456) 
--开始不带套插入! 
alter table customers 
check 
constraint cn_customerPhoneNo 
--下次插入要带套  
9. 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选项。10、列约束和表约束
约束可以是列约束或表约束:     
  列约束被指定为列定义的一部分,并且仅适用于那个列(前面的示例中的约束就是列约束)。    
  表约束的声明与列的定义无关,可以适用于表中一个以上的列。     
  当一个约束中必须包含一个以上的列时,必须使用表约束。   
  例如,如果一个表的主键内有两个或两个以上的列,则必须使用表约束将这两列加入主键内。假设有一个表记录工厂内的一台计算机上所发生的事件。假定有几类事件可以同时发生,但不能有两个同时发生的事件属于同一类型。这一点可以通过将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
再看例子: 
Create rule SalaryRule 
as @salary >0; 
sp_bindrule 'SalaryRule' , 'Employee.Salary' 
第一句定义了一个规则叫SalaryRule 
进行比较的事物是一个变量 
这个变量的值是所检查的列的值 
第二句把规则绑定到某个表的一个列上 

规则和ckeck约束很相似, 
但是规则只作用在一个列上 
一个规则可以绑定在多个列上,但是它不会意识到其他列的存在 
check可以定义column1>=column2 

取消规则 
exec sp_unbindrule 'Employee.Salary' 

删除规则 
Drop rule SalaryRule 

1:默认值

默认值与default约束类似(有区别的,但是我说不清楚) 
先看例子: 
create default salarydefault 
as 0; 
exec sp_binddefault 'salarydefault' , 'employee.salary'; 
取消默认值: 
exec sp_unbinddefault 'employee.salary' 
删除默认值: 
drop default 'salarydefault'外记:
在Create Table 语句的属性清单后,加上外部码说明子句,格式为: 
FOREIGN KEY <属性名表1> REFERENCES <表名>(<属性名表2>) 
eno char(4) CONSTRAINT PK_employee PRIMARY KEY, 
dno char(4)CONSTRAINT FK_employee FOREIGN KEY REFERENCES department(dno); 
ALTER TABLE语句来更新与属性或表有关的各种约束。如: 
ALTER TABLE employee DROP CONSTRAINT FK_employee; 
ALER TABLE Salary ADD CONSTRAINT RightSalary CHECK(Insure+Fund<Rest);