Mysql不得不用储存过程代替触发器

这是发在csdn的问题,没人回答,只好自己动手了。翻书后发现触发器的概念能很好地解决问题,但很快发现....

unique索引会先于触发器要触发,update数据时,如果引起索引冲突,直接就报错了,根本轮不到触发器。于是删除索引,但很快发现.....

mysql的触发器不能修改本表其他记录!!!mssql是可以的!!!这样对于删除的需求就没办法实现了,只好翻到储存过程,但很快发现....

mysql的储存过程语法实在太烦琐了,特别是组装带参数的执行语句时,一个语句最少要写四行,而mssql直接用类似于js的语法连起来就可以用了。执行后的结果集还不能直接使用,又要兜个圈用视图来保存结果集,再调用......是不是因为我太菜了,没法理解这样高深的用法。


其实很简单的逻辑,前后花了一整天的时间才解决了需求,贴出来以纪念菜鸟的时刻。


DROP PROCEDURE IF EXISTS `bookshelf_binding`;

CREATE DEFINER = `root`@`127.0.0.1` PROCEDURE `bookshelf_binding`(`shelf_type` varchar(30),`source_id` int,`admin_id` int)
BEGIN

declare done int default 0;
declare tmp_book_id int;
declare tmp_id INT;
declare tmp_status int;
declare cur cursor for( select id,book_id,status from bookshelf_view);
declare continue handler for not found set done=1;
-- 必须通知视图来保存查询结果集
drop view if exists bookshelf_view;
-- 保存待绑定账户的book_id集
set @sql_a=concat('create view bookshelf_view as select id,book_id,status from ',shelf_type,' where uid=',source_id);
prepare sql_a from @sql_a;
execute sql_a;
deallocate prepare sql_a;

drop view if EXISTS b_view;
-- 保存操作账户的book_id集
set @sql_b=concat('create view b_view as select book_id from ',shelf_type,' where uid=',admin_id);
prepare sql_b from @sql_b;
execute sql_b;
deallocate prepare sql_b;
-- 打开游标
open cur;
fetch cur into tmp_id,tmp_book_id,tmp_status;
while done<>1 do 
-- 用游标循环待绑定账号的book_id
if tmp_book_id in (select book_id from b_view) THEN
-- 如果待绑账号的book_id与操作账户冲突,进行下步判断
drop view if exists d_view;
set @sql_d=concat('create view d_view as select status from ',shelf_type,' where uid=',admin_id,' and book_id=',tmp_book_id);
prepare sql_d from @sql_d;
execute sql_d;
deallocate prepare sql_d;
-- 如果两者状态相同,直接删除待绑定的行
if tmp_status=(select status from d_view) THEN
set @sql_f=concat('delete from ',shelf_type,' where id=',tmp_id);
prepare sql_f from @sql_f;
execute sql_f;
deallocate prepare sql_f;
ELSE
-- 如果状态不同,则令操作账户的状态为1。
set @sql_e=concat("update ",shelf_type," set status='1' where uid=",admin_id," and book_id=",tmp_book_id);
prepare sql_e from @sql_e;
execute sql_e;
deallocate prepare sql_e;
-- 修改完状态,再删除待绑行
set @sql_g=concat('delete from ',shelf_type,' where id=',tmp_id);
prepare sql_g from @sql_g;
execute sql_g;
deallocate prepare sql_g;
end if;

ELSE  -- book_id无冲突,可直接更新
set @sql_c=concat('update ',shelf_type,' set uid=',admin_id,' where id=',tmp_id);
prepare sql_c from @sql_c;
execute sql_c;
deallocate prepare sql_c;
end if;

fetch cur into tmp_id,tmp_book_id,tmp_status;
end while;
close cur;

end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值