09-17:触发器

2018-09-17  本文已影响0人  神坛下的我
  1. 主键约束 primary key
    实体完整性(唯一约束+非空约束),对象具有和同类对象区别唯一的特征
    (字段)。
  2. 外键约束 foreign key
    引用完整性 一个对象需要引用的对象存在来证明正确性。
  3. 检查约束 check
    域完整性 例如:身高在范围的约束内,性别在列表in的约束内,电话在like
    约束内;规则rule
  4. 自定义完整性

触发器(sqlserver)

基本语法1:
create trigger trg_admin
on admin
for insert
as
begin
 print '有插入发生'
end
基本语法2:
alter trigger trg_admin 
on admin 
for insert
as
begin
 declare @countno int 
 select @countno = count(*) from admin
 if @countno <= 4
 begin 
  print '有插入发生'
 end
 else
 begin
  -- 报错信息 参数1消息,参数2级别,参数3自编号
  raiserror('对不起,已经满员',16,10)
  -- 回滚操作
  rollback transaction
 end
end

insert into admin values('0005','123','aaa',1)
解题:
create trigger trg_changeroom_student 
on student 
for insert 
as 
begin
    declare @name varchar(20),@newroomno char(4),@countno int,@str varchar(100)
    -- 获取到该学生希望入住的寝室 
    select @name=name,@newroomno = bedno from inserted 
    select @countno = count(*) from student 
    where substring(bedno,1,4) = @newroomno
    -- 判断该学生入住后,寝室是否超员 
    if @countno > 4 
    begin
     set @str='您要入住的寝室'+@newroomno+'已经满员'
     raiserror(@str,16,20)
     rollback transaction
    end
    else 
    begin
      print '欢迎'+@name+'同学入住'+@newroomno+'寝室'
    end
end

insert  into student(sno,name,sex,high,birthday,jointime,homephone,bedno,address,avgscore,area,cno,imgsrc,pwd) 
values ('16010102','张三','女',172,'1989-03-01 00:00:00','2009-09-01 00:00:00','13931111112','0301','嘉陵区',73.3,'南充','090101','','123')

select * from studnt

-- 进阶上题
1.解决插入寝室是否满员
2.插入的寝室可以入住,编床位号的问题
3.插入寝室可以入住,找空床

create trigger trg_changeroom_student
on student
for insert,update
as
begin
 declare @insertno int,@deleteno int
 declare @name varchar(20),@sno char(8),
  @newroomno char(4),@countno int,@str varchar(100),@oldroomno char(6)
 
 select @insertno = count(*) from inserted
 select @deleteno = count(*) from deleted
 -- 如果插入临时表(幻表)数量 > 0 同时 删除幻表 数量 > 大于0 说明这是修改



-- 获取到该学生希望入住的寝室
  select @sno=sno,@name=name,@newroomno = bedno from inserted
  select @countno = count(*) from student
  where substring(bedno,1,4) = @newroomno
 -- 判断该学生入住后,寝室是否超员
  if @countno > 4
  begin
       set @str = '您要入住的寝室'+@newroomno + '已经满员'
       raiserror(@str,16,20)
     -- 对于成功入住 插入和修改逻辑一样
     if(@deleteno > 0 and @insertno > 0)
       begin -- 修改的拒绝处理
        select @sno=sno,@name=name,@newroomno = bedno from inserted
        select @oldroomno = bedno from deleted
        print @oldroomno
        update student
        set bedno = @oldroomno
        where sno = @sno 
        print @name + '同学被退回' +@oldroomno + '寝室'
       end
     else -- 插入的拒绝处理
      begin
        rollback transaction
      end
    
     end
 else
  begin
    declare @j int = 1,@temproomno char(4) = @newroomno,@tempbedno char(6)
    while @j <=4   -- 循环产生本寝室合理的床位号,查找该床位是否被使用,
               --如果没有被使用,退出循环
    begin
     set @tempbedno = @newroomno + '0' + convert(char(1),@j)
     if not exists(select  bedno from student
      where bedno = @tempbedno)
      begin
       print @tempbedno
       update student
       set bedno = @tempbedno
       where sno = @sno
       break
      end
 
    set @j = @j + 1
    end
    print '欢迎' + @name + '同学入住' + @newroomno +'寝室'
  end

end

insert  into student(sno,name,sex,high,birthday,jointime,homephone,bedno,address,avgscore,area,cno,imgsrc,pwd) 
values ('16010108','张三','女',172,'1989-03-01 00:00:00','2009-09-01 00:00:00','13931111112','0401','嘉陵区',73.3,'南充','090101','','123')


delete from student
where sno = '16010103'

update student
set bedno = '0301'
where sno = '16010108'

select * from student

步骤:
-- 1.通过幻表找出新的寝室
-- 2.统计新寝室的人数是否超员
-- 3.如果超员

--    3.1 判断是 插入引发触发,报异常回滚
--    3.2  修改引入触发 ,报异常 找到原来的寝室号 修改回原寝室(也可以通过回滚取消更新来做,如果不允许直接回床位 
           -- 只能在原寝室重新分配)
-- 4.不超员 欢迎入住,并计算出床位号
1.创建临时表,查询空床
create table tempbedno
(
 tempbedno char(8)
)
declare @i int = 1 
while(@i <= 4) 
begin
 insert into tempbedno values('0301'+'0'+convert(char(1),i))
 set @i = @i + 1
end

select * from tempbedno where tempbedno not in(
    select bedno from student 
    where substring(bedno,1,4) = '0301'
)

drop table tempbedno
2.循环查询空床
declare @j int = 1,@temproomno char(6) = '0301',@tempbedno char(6)
while @j <= 4 
begin
 set @tempbedno = '0301'+'0'+convert(char(1),@j)
 if not exists(select bedno from student 
 where bedno = @tempbedno)
 begin
  print @tempbedno
  break
 end
 set @j = @j+1
end

上一篇下一篇

猜你喜欢

热点阅读