zoukankan      html  css  js  c++  java
  • 视图、存储过程、触发器、函数、索引、游标

    表:
    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关闭游标
  • 相关阅读:
    Luogu1053 NOIP2005篝火晚会
    BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)
    Luogu1155 NOIP2008双栈排序(并查集)
    Luogu1092 NOIP2004虫食算(搜索+高斯消元)
    Codeforces Round#516 Div.1 翻车记
    Luogu1731 NOI1999生日蛋糕(搜索)
    洛谷 P1379 八数码难题 解题报告
    洛谷 P2501 [HAOI2006]数字序列 解题报告
    洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 解题报告
    洛谷 P2894 [USACO08FEB]酒店Hotel 解题报告
  • 原文地址:https://www.cnblogs.com/jf-ace/p/14700776.html
Copyright © 2011-2022 走看看