Ms SQL Server 约束和规则

一、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);

posted @ 2013-08-12 16:09  ZWmaqing  阅读(584)  评论(0编辑  收藏  举报