7-22 存储过程、触发器、事务

select * from Fruit
select * from Login
select * from OrderDetails
select * from Orders
select * from Info
select * from Family
go
--创建存储过程格式:
--create procedure存储过程名
--@变量名 数据类型
--as
--begin
--要执行的过程
--end

--存储过程,实现用户购买水果的操作,要判断购买数量和库存之间的关系,购买总价和余额之间的关系,如果购买成功修改4个表

create procedure BuyFriut--创建存储过程
@Uid varchar(50),--定义用户名变量
@Fcode varchar(50),--定义水果代号变量
@Sl int--定义购买数量
as
begin
    declare @kc int,@price float
    select @kc=Numbers,@price=Price from Fruit where Ids=@Fcode
    if @Sl>@kc
    begin
        print '库存不足!'
    end
    else
    begin
        declare @ye float
        select @ye=Account from Login where UserName=@Uid
        if @ye>= @price*@Sl
        begin
            update Fruit set Numbers=Numbers-@Sl where Ids=@Fcode
            update Login set Account=Account-@price*@Sl where UserName=@Uid
            declare @sj int
            set @sj = cast(rand()*10000    as int)                
            insert into Orders values(@sj,@Uid,GETDATE())
            insert into OrderDetails values(@sj,@Fcode,@Sl)        
        end
        else
        begin
            print '余额不足!'
            
        end
    end    
end

go
--使用存储过程
declare @s int
execute  @s = BuyFriut 'wangwu','k001',20--execute执行成功,返回值为0
print @s
--删除存储过程 drop proc BuyFriut


触发器

触发器是一类特殊的存储过程,在对表进行update、insert、delete语句时自动执行。

--触发器,特殊的存储过程,执行的时间和存储过程不一样,存储过程在调用的时候执行,触发器是在执行某种操作的时候触发执行,相当于C#里面的事件

--inserted表和deleted表,临时表,作用是为了恢复数据
--创建触发器
--关键字 trigger
--格式:
--create trigger TR_要进行触发的表_要执行的操作(触发器名称一般用大写)
--on 要进行触发的表
--for/after/instead of delete
--as
--begin
--要执行的操作
--end
--go--执行触发器
--delete from 要触发的表 where 列名=select * from Loginone
select * from biandong
go


create trigger TR_LOGINONE_DELETE
on Loginone
for delete --删除的时候执行
--after delete --删除之后执行
--instead of delete --替代执行

as
begin
    declare @uid varchar(50),@name varchar(50)
    select @uid=UserName,@name=Name from deleted
    insert into biandong values(@uid,@name,'删除')
end
go
--在对表loginnoe进行删除的时候触发器执行
delete from Loginone where UserName='aaa'

go
--instead of触发器
--删除student里面的数据的时候用另外两条语句替代,先删从表再删主表

create trigger TR_STUDENT_DELETE
on Student
instead of delete
as
begin
    declare @sno varchar(20)
    select @sno=sno from deleted
    delete from score where sno=@sno
    delete from student where sno=@sno
end
--执行删除的时候触发
delete from student where sno='101'
select * from student
select * from score
select * from course
select * from teacher

事务:
概念:事务指完成用户一个特定工作的一组命令的一次执行,也可称为任务,或者说事务是构成单一逻辑工作单元的操作集合

性质(ACID特性):原子性、一致性、隔离性、持久性

     事务是一个逻辑工作单元,是一个整体,是不可分割的,一个事务所包含的操作,要么全做,要么全不做。

  一旦事务成功完成,则该事务对数据库所施加的所有更新都是永久的,即在事务成功后,任何系统故障都不能破坏已经完成的事务对数据库的操作结果。

  当没有发生错误的时候便可以将事务进行提交(CIMMIT TRANSACTION),而查看有没有SQL语句的执行错误,可以用 @@ERROR来进行查看。

    当发生错误的时候便使用(ROLL BACK TRANSACTION)将SQL语句回滚到最最之前,没有执行SQL语句那时候。

--事务
--开始事务 begin tran(transaction)
--提交 commit
--回滚 rollback

select * from Car
select * from Brand

begin transaction --开始事务
delete from Car where Code='c005'
delete from Brand where Brand_Code='b002'
 if @@ERROR=0--判断是否出错,如果执行没错@@ERROR为0
begin
    commit -- 提交事务
end
else
begin
    rollback--回滚事务
end

--try catch
begin transaction --开始事务
begin try --try里面写要执行的代码
    delete from Car where Code='c005'
    delete from Brand where Brand_Code='b002'
    commit
end try
begin catch
    rollback
end catch