SQLserver数据的完整性

--sql约束

/*

(1)提供语义定义完整性约束条件的机制

实体完整性:主键、非空

    参照完整性:外键

    用户自定义完整性:check、触发器

(2)提供完整性检查方法

    一般在:Insert、Update、Delete执行后开始检查,及事务提交后开始检查。

(3)违约处理

    拒绝(no action)

    级连(级联 Cascade)

 

*/

/* 几种约束

非空约束(NOT NULL Constraint )

主键约束(Primary Key Constraint)

外键约束(Foreign Key Constraint)

唯一性约束(Unique Constraint)

检查约束(Check Constraint)

默认值约束(Default Constraint)

 

*/

 

--主键约束

--【例1】实体完整性约束。

CREATE TABLE student1 (

    sno char (9) PRIMARY key , --//列级约束

    sname varchar (10) ,

    ssex char (2) ,

    sage int NULL ,

    sdept char (10) ) --,

--或 PRIMARY key(sno)) --//表级约束

 

--表级约束

CREATE TABLE sc1 (

    sno char(9) ,

    cno char(3) ,

    grade int,

primary key(sno,cno) -- //表级约束

)

 

 

--参照完整性定义

--Foreign key(列名) references table_name(列名)

--注意要参考的列应该和被参考列的长度,数据类型相同

sp_help course;

sp_help student;

--【例2】参照完整性实例 (列级、表级均可)。

CREATE TABLE sc2 (

    sno char(9),

    cno char(4),

    grade int ,

primary key(sno,cno) ,

foreign key(cno) references course(cno),

foreign key(sno) references student(sno)

);

 

 

--测试约束

CREATE TABLE sc3 (

    sno char(9) ,

    cno char(4) ,

    grade int ,

primary key(sno,cno) ,

foreign key(sno) references student(sno)

on delete no action --当删除student的记录的时候 会失败

on update cascade --但更新student的记录时 sc3表中的记录也会更新

) ;

--恰当使用级联更新和级联删除 方便数据库在更新时的操作;

insert into student(sno) values('2014019');

insert into sc3 values('2014019','001',100);

 

 

delete from student where sno='2014019';

update student set sno='122222' where sno='2014019';

 

select * from sc3;

--在删除该约束后就可以成功删除了

--当你不给约束起名字的时候 DBMS会自动给该约束起一个名字

--sp_help sc3;

alter table sc3 drop FK__sc3__sno__398D8EEE;

 

drop table sc3;

------------------------------------------------


--check约束
/*CREATE TABLE student1 (
sno char (9) PRIMARY key ,
sname varchar (10) ,
ssex char (2) check(ssex in('男','女')),
sage int NULL ,
sdept char (10) ,
check(ssex='女' or sname not like 'Ms%')
) */
--测试check约束
--insert into student1 values('100053','heheh','x',19,'is');

--insert into student1 values('190292','Msxiao','男',19,'is');

--insert into student1 values('100023','Masd','男',19,'is');

---------------------------------------------------------------------------
--创建角色

CREATE RULE xb_rule
AS @xb IN ('男','女')

--绑定角色到特定的列
--sp_bindrule xb_rule,'student.ssex'

--测试
--select * from student ;
--insert into student values('2014012','李大海','x',21,'cs');

--insert into student values('2014012','李大海','男',21,'cs');
--delete from student where sno='2014012'
--解除绑定
-- sp_unbindrule 'student.ssex'

---------------------------------------------------------------------
--创建默认值
CREATE DEFAULT df_xf AS 4
--绑定默认值
sp_bindefault df_xf,'course.ccredit'
--解除绑定
sp_unbindefault 'course.ccredit'

select * from course

insert into course (cno,cname) values(8,'物理');
delete from course where cno=8

--解除绑定后才能够删除
drop default df_xf


CREATE DEFAULT df_xf AS 10

sp_bindefault df_xf,'course.cpno'
sp_unbindefault 'course.cpno'

-----------------------------------------------------------------
/*
use mydb
go
if exists(select name from sysobjects where name='sc_iu' and type='tr')
drop trigger sc_iu
go
create trigger sc_iu
on sc
for insert,update
as
print '插入或更新了sc表!\n'
print '插入或更新了sc表!\n'
Go
*/
--insert into sc values('2014005',5,100);

--update sc set grade=1000 where sno='2014005' and cno='5'

--select * from sc

/*
use mydb
go
alter trigger sc_iu
on sc
instead of insert
as
print '在sc表中没有插入记录!'
go
*/

--删除触发器
--drop trigger sc_iu


-------------------------------------------------------------------------------

create trigger st_delete on student
for delete as
declare @bsno char(9)
print '使用delete触发器级联删除sc表中相关的行-开始'
select @bsno=sno from deleted
print '删除的学号:'+@bsno
delete sc where sc.sno=@bsno
print '使用delete触发器级联删除sc表中相关的行--结束'
go

drop trigger st_delete


delete from student where sno='2014005'
--我这里删除有点小的问题 可能是 语句执行的顺序是 先删除student
--而sc表中的某些数据正好参照student的sno键所以 开始就不能删除

-----------------------------------------------------------------------------------
select * from sc

create table sc_back (
sno varchar(10),
cno varchar(2) ,
grade int,
)

--备份的触发器
select * from sc_back

if exists(select name from sysobjects where name='sc_delete' and type='tr')
drop trigger sc_delete
go
create trigger sc_delete
on sc for delete as
print '使用delete触发器备份删除sc表中相关的行--开始'
insert into sc_back
select * from deleted
print '使用delete触发器备份删除sc表中相关的行--结束'
go

 

delete from sc where sno='2014005'

----------------------------------------------------------------------

--更新触发器
create trigger st_update
on student for update as
if update(sno)
begin
declare @bsno char(9),@asno char(9)
print '使用update触发器级联更新sc表中相关的行-开始'
select @bsno=sno from deleted
print '更新前的学号:'+@bsno
select @asno=sno from inserted
print '更新后的学号:'+@asno
update sc set sno=@asno where sc.sno=@bsno
print '使用update触发器级联更新sc表中相关的行-结束'
end
go


update student set sno='2014065' where sno='2014002'

select * from student
select * from sc

----------------------------------------------


create rule gread_rule
as @gb >=0

sp_bindrule gread_rule , 'sc.grade'


create default credit_default as 4

sp_bindefault credit_default ,'course.ccredit'


select * from course

select * from sc

-------------------------------------------

create trigger grade_update
on sc for update as
if update(grade)
begin
declare @old_grade int,@new_grade int ,@sno_ varchar(10)
select @sno_=sno from deleted
select @old_grade=grade from deleted
print '更新前的成绩:'
print @old_grade
select @new_grade=grade from inserted
print '更新后的成绩'
print @new_grade
if(@new_grade>1.1*@old_grade)
begin
print '成绩升幅太大,更新无效'
update sc set grade=@old_grade where sno=@sno_
end
else
print '更新成功'
end
go


drop trigger grade_update

update sc set grade=111 where sno='2014002'

 

posted on 2014-11-28 17:12  gw123  阅读(663)  评论(0编辑  收藏  举报

导航