存储过程,触发器----应用实例

         关于sysobjects,type,name:
sysobjects这个表记录一个数据库里的所有对象,包括表,索引,存储过程,触发器等等.type字段标志了他们的类别,‘P’表示是存储过程,‘S’表示是系统表,‘U’表示是用户自建表,等等。name是对象名称

存储过程(Stored Procedure)

       存储过程是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

  1. 运用存储过程创建STUDENT、GRADE、COURSE表(要求实现完整性)。
use student_data /*数据库名称*/
go 
if exists (select name from sysobjects
where name='cun' and type='P')
	drop procedure cun
go
create procedure cun /*procedure也可写为proc*/
as     
begin
   if not exists(select name from sysobjects 
                 where name='student' and type='U')
	   begin
		   create table student 
		   (sno char(6) not null unique,
			sname char(8) not null,
			sex char(2), 	 
			sage int,
			dno char(4),
			dormno char(5),
			constraint fk_dep foreign  key(dno) references department(dno),
			constraint pk_student primary key(sno));

			insert into student
			values('990101','原野','男',21,'1','2101');
		end
	if not exists(select name from sysobjects
				where name='grade' and type='U')  
		begin
			create table grade
		   (sno char(6),
			cno char(2),
			score int,
			constraint pk_grade primary key (sno,cno));
			insert into grade
			values ('990101','01',85);
		end
	if not exists(select name from sysobjects 
						where name='course' and type='U')   
		begin
			create table course
		   (cno char(2) not null unique,
			cname char(20) not null,
			cpno char(2), 	 
			credit int,
			teacher char(8),
			constraint pk_cor primary key(cno));
			insert into course
			values('01','数据库原理','05',4,'王凯');
		end
end

exec
cun
select *from student
  1. 运用存储过程对STUDENT、DEPARTMENT、DORM表插入一条符合完整性的记录。
use student_data
go 
if exists (select name from sysobjects
		   where name='cun' and type='P')
drop procedure cun
go
create procedure cun
@ssno char(6),@ssname char(8),@ssex char(2),  /*定义参数*/
@ssage int,@ddno char(4),@ddorm char(5),
@dddno char(4),@ddname char(8),@hhead char(20),
@dddorno char(5),@dddtel char(7)
as
begin
   if not exists(select sno from student where sno=@ssno) 
   if exists (select dno from department where dno=@ddno)
   if exists(select dormno from dorm where dormno=@ddorm) 
       insert into student (sno,sname,sex,sage,dno,dormno)
             values(@ssno,@ssname,@ssex,@ssage,@ddno,@ddorm)
   if not exists(select dno from department where dno=@dddno)
   if not exists(select dname from department where dname=@ddname)
       insert into department
            values(@dddno,@ddname,@hhead)
   if not exists(select dormno from dorm where dormno=@dddorno)
   if not exists(select tele from dorm where tele=@dddtel)
       insert into dorm
             values(@dddorno,@dddtel)
end

go
use student_data
go
cun '990109','达到','男',19,'4','2404','5','地质','哈哈','6504','8306753'

/*测试*/
select *from student
select *from department
select *from student
select *from dorm
  1. 编写带参的存储过程:实现删除"01"课程"数据库原理"的相关信息。
use student_data
go

if exists(select name from sysobjects
          where name='del_cname' and type='P')
	drop procedure del_cname
go
create procedure del_cname
@cname char(20)
as
begin
	delete grade where cno =(select cno from course where cname='数据库原理')
	delete course where cname=@cname
end

go
del_cname '数据库原理'

go 
drop procedure del_cname /*删除存储过程*/

go
select * from course 
select * from grade
  1. 编写带参的存储过程:实现删除 “990101” 学生 “原野” 的相关信息。
use student_data  
go 
if exists(select name from sysobjects 
         where name ='del_S'and type ='P')
	drop procedure del_S   
go
create procedure del_S
@stu char(6)
as 
begin
	delete grade where sno=@stu
	delete student where sno=@stu
end


go
del_S '990101'

go
select * from grade 
select * from student
  1. 编写带参的存储过程:实现宿舍号从 “2101” 修改为 “3101”。
use student_data
go
if exists (select name from sysobjects 
           where name = 'adjust_roo' and type = 'P')
   drop procedure adjust_roo
go
create procedure adjust_roo
@dormno char(5), @dormno1 char(5)
as
begin
	update student set dormno=@dormno1
	where dormno=@dormno
	delete from dorm
	where dormno=@dormno 
end  

go
adjust_roo '2101', '3101'

go
select * from student
  1. 编写带参的存储过程:实现查询宿舍号“2505”的相关信息。
use student_data
go
if exists(select name from sysobjects
          where name='search_dorm' and type='p')
	drop procedure search_dorm
go
create procedure search_dorm
@dormno char(5)
as
begin
	select dorm.*, sno,sname from dorm,student  
	where student.dormno=dorm.dormno 
	and dorm.dormno=@dormno
end

/*go也可以  
go
search_dorm ‘2505’
*/
exec 
 search_dorm '2505'

drop procedure search_dorm
触发器(Trigger)

       触发器是用户定义在关系表上的一类由事件驱动的特殊过程。一旦定义,任何用户对表的增,删,改操作均由服务器自动激活相应的触发器,在DBMS核心层进行集中的完整性控制。触发器类似于约束,但是比约束更加灵活,可以实施比FOREIGN KEY约束,CHECK约束更为复杂的检查和操作,具有更精细和更强大的数据控制能力。

  1. 运用触发器对GRADE实现插入记录“980101,08,99”(相关信息自己定义)。
use student_data
go
if exists(select name from sysobjects
           where name ='SC'and type ='TR')
	drop trigger SC 
go
create trigger SC on grade  /*grade是表名*/
for insert		/*delete,update,insert*/
as 
   declare @Sno char(6)	/*定义局部变量*/
   declare @Cno char(2)
   declare @Score int 
   declare @msg1 char(100)		/*提示信息*/
   declare @msg2 char(100) 		/*提示信息*/
   declare @msg3 char(100)		/*提示信息*/
    
   select @Sno= Sno from inserted /*给局部变量赋值*/
   select @msg1='没有此学生'
   if not exists(select * from student 
           where sno =@Sno )
	   begin     
		   print @msg1
		   rollback  transaction /*回滚*/
		   return  /*返回*/
	   end 
    select @Cno=Cno from inserted
    select @msg2='没有此课程'
    if not exists(select * from course 
           where cno =@Cno )
		begin     
		    print @msg2
			rollback  transaction
		    return     
		end 
    select @Score=score from inserted
    select @msg3='成绩不对'
    if (@Score is not null and (@Score<0 or @Score>100))
        begin     
            print @msg3
		    rollback  transaction
			return
		end   
go
insert into grade(sno,cno,score)
values('980101','08',99)  

drop trigger SC
  1. 运用触发器对STUDENT表中的SEX实现数据范围检查,若出错,提示信息。
use student_data
go
if exists (select name from sysobjects 
           where name='tr_ssex' and type='TR')
	drop trigger tr_ssex
go
create trigger tr_ssex on student
for update,insert 
as 
	declare @msg varchar(100)
	declare @vssex char(2)
	select @msg='数据有误,请检查后,重新输入!'
	select @vssex=sex from inserted
    if (@vssex<>'男'and @vssex<>'女') /* <>相当于!= */
		begin     
			print @msg
			rollback  transaction
			return
		end

go
update student set sex='难' where sno='980202'

insert into student(sno,sname,sex)
values('200001','小野','难')

drop trigger tr_ssex

  1. 运用触发器对STUDENT表的操作只能在工作时间:9点~15点,每周一到五,实现数据安全性控制。
use student_data
go
if exists(select name from sysobjects
		  where name='tr_up_student'and type='TR')
	drop trigger tr_up_student
go
create trigger tr_up_student on student
for update,insert,delete
as
	declare @msg varchar(100)
	select @msg ='无法操作'
	/*DateName():返回代表指定日期的指定日期部分的字符串
    语法:DateName(datepart,date) 返回类型:nvarchar
	*/
	if(DateName(weekday,getdate()) like '星期六' or DateName(weekday,getdate()) like '星期日' or 
	DateName(hour,getdate()) not between 9 and 15)
		begin
			print @msg
			rollback transaction
			return
		end

go
update student
set sage='30'
where sno='980202'

你可能感兴趣的:(数据库)