视图、存储过程、触发器、函数、索引、游标

表:
major (专业表): mno(专业号) mname(专业名称)
stu(学生表) : sno(学号) sname(姓名) age sex mno
cou(课程表) : cno(课程号) cname(课程名称) ctime(学时) ccredit(学分)
sc(成绩表) : sno cno grade(成绩)

视图:
从一个或几个基本表中导出来的表,
虚表,数据库中只存放视图的定义,不存放对应的数据,
数据的来源与存放还是来源于原来的表,所以原来表中的数据一旦发生改变视图也会发生改变;

查询每个同学较自己平均分高的课程cno
1.每个同学的平均分视图
2.开始查询
查询学生的信息(sno,avg(grade))

create view v_stu3
as
select sno,AVG(grade) as avg_grade from sc group by sno
select * from v_stu3 where avg_grade < 89

存储过程:
存储过程是事先经过编译并保存在数据库中的一段sql的语句集合;
使用时调用即可。
创建:

create proc p1
as
begin
  select * from sc where sno = '202001'
end

调用:

exec p1

修改:

alter proc p1 @sno varchar(13),@cno varchar(13)
as
begin
  select sc.* ,cou.ccredit from sc,cou where sno = @sno and sc.cno = @cno and sc.cno = cou.cno
end

调用:

exec p1 '313153','115315'

删除:

drop proc p1

触发器:监视某种情况,并触发某种操作,当对一个表格进行增删改就有可能自动激活并执行
结构:
(after,instead of(对插入前要进行赋值声明))
(update,insert, delete)

学生人数不能大于17

create trigger t1 on stu after insert
as
begin
  if(select COUNT(* )from stu)>17
  begin
    print'error'
    rollback tran
  end
  else
  begin
    print'right'
  end
end

insert into stu(sno,sname) values('2015102','jk')

//插入之前声明(理解):

alter trigger t1 on stu instead of insert
as
begin
   select * from inserted
  select * from deleted
  if(select COUNT(* )from stu)>16
  begin
    print'error'
    rollback tran
  end
  else
  begin
    print'right'
    --insert
    declare @sno varchar(13)
    declare@sname varchar(30)
    declare@age int
    select @sno=sno from inserted
    select @sname=sname from inserted
    select @age=age from inserted
    insert into stu(sno,sname,age) values(@sno,@sname,@age)
  end
end

学生人数不能小于16

create trigger t2 on stu after delete
as
begin
  if(select COUNT(* )from stu)<16
  begin
    print'error'
    rollback tran
  end
  else
  begin
    print'right'
  end
end

当新增学生成绩55-59 改成60分

create trigger t3 on sc instead of insert
as
begin
declare @cno varchar(13)
declare@sno varchar(13)
declare@grade decimal(5,2)
select @cno=cno from inserted
select @sno=sno from inserted
select @grade=grade from inserted
if@grade>=55 and @grade<=59
begin
  set @grade = 60
end
  insert into sc(cno,sno,grade) values(@cno,@sno,@grade)
end

insert into sc values('5615','1613',58)

函数:
自定义函数,函数和存储过程很像,不同之处就是多了一个return
1.计算某门课程的平均分:

create function fun1(@cno varchar(30))
returns int
as
begin
  declare @avgscore int
  select @avgscore = avg(grade) from sc where cno = @cno
  return @avgscore
end

调用:

select dbo.fun1('20201')

2.输入专业
返回学生学号和姓名(这个专业)

create function fun2(@mno int)
returns @snoSname table(sno varchar(13) , sname varchar(30))
as
begin

  insert into @snoSname(sno,sname) select sno,sname from stu where mno=@mno
  return
end
select * from dbo.fun2(1)

3.输入专业号
返回这个专业所有学生的每个课程对应成绩的一个表

create function fun3(@mno int)
returns @Msc table(sno varchar(13) , cno varchar(13) , grade decimal(5,2))
as
begin

  insert into @Msc select stu.sno,cno,grade from major,stu,sc where major.mno=stu.mno and stu.sno=sc.sno
  and stu.mno=@mno
  return
end

select * from dbo.fun3(1)


索引:
对数据库列表中的一列或多列进行排序的一种结构
目的:加快查询速度(目录)select
但是,占用一定的存储空间,更新和维护
不创建:
1.频繁更新的字段或者经常增删改的表,不适合创建索引
2.表记录太少,不需要创建索引
3.如果某些数据包含大量重复数据,因此建立索引就没有太大的效果,例如性别字段,只有男(0)女(1),不适合建立索引
4.stu sex 01
sqlServer默认主键为聚集索引


sc表按学号升序和课程号降序建唯一索引

create unique index scno on sc (sno asc, cno desc)

删除索引

drop index scno on sc


游标:
用户数据缓冲区
声明游标:

declare my_cursor cursor for select mname from major
declare @mname varchar(30)

打开游标

open my_cursor


取数据(循环)

fetch next from my_cursor into @mname
while @@FETCH_STATUS= 0
begin
  select @mname as 'mname'
  fetch next from my_cursor into @mname
end

释放游标:

deallocate my_cursor

1.例子:
在SC 表添加字段sc_rank 作为成绩等级;

declare my_cursor cursor for select cno,sno,grade from sc
declare @cno varchar(13)
declare @sno varchar(13)
declare @grade decimal
open my_cursor
fetch next from my_cursor into @cno,@sno,@grade
while @@FETCH_STATUS = 0
begin
  if@grade>= 80
    update sc set sc_rank = 'A' where cno = @cno and sno = @sno
  else if @grade>=70
    update sc set sc_rank = 'B' where cno = @cno and sno = @sno
  else if @grade>=0
    update sc set sc_rank = 'C' where cno = @cno and sno = @sno
  fetch next from my_cursor into @cno,@sno,@grade
end
deallocate my_cursor
select * from sc


2.查询所有学生的专业名和姓名

--原来:select mname,sname from stu left outer join major on stu.mno=major.mno
declare my_cursor cursor for select mname,sname from stu left outer join major on stu.mno=major.mno
declare @sname varchar(30)
declare @mname varchar(30)
open my_cursor
fetch next from my_cursor into @sname,@mname
while @@FETCH_STATUS = 0
begin
  select @sname as 'sname' ,@mname as 'mname'
  fetch next from my_cursor into @sname,@mname
end
deallocate my_cursor      --close my_cursor关闭游标
原文地址:https://www.cnblogs.com/jf-ace/p/14700776.html