MySQL存储过程+游标+触发器
r1)通过把处理封装在容易使用的单元中,简化复杂的操作 ;r2)提高性能:因为使用存储过程比使用单独的SQL语句要快;r3)安全性:通过存储过程限制对基础数据的访问减少了数据讹误(无意识的或别的原因所导致的数据讹误)的机会;r4)存在一些只能用在单个请求中的MySQL 元素和特性,存储过程可以使用它们来编写 功能更强大更灵活的代码;
d1)存储过程的编写比基本SQL语句更加复杂,编写存储过程需要更高的技能,更更丰富的经验;d2)你可能没有创建存储过程的安全访问权限。许多 admin 限制存储过程的创建 权限,允许用户使用存储过程,但不允许他们创建存储过程 ;
problem:默认的MySQL 语句分隔符为;(分号),MySQL 命令行实用程序(mysql.exe)也使用;作为分隔符;如果命令行实用程序要解释存储过程自身内的; 字符,则它们最终不会称为存储过程 的一部分,这会使得存储过程中的SQL 出现句法错误;solution:解决方法是 临时更改命令行实用程序的语句分隔符,如下所示:delimiter // drop procedure if exists avg_price // create procedure avg_price() beginselect avg(price) as avg_price from product; end // delimiter ;
A1)delimiter // :告诉命令行实用程序使用 // 作为新的语句结束分隔符,可以看到标志存储过程结束的end 定义为 end // 而不是 end;A2)这样在存储过程体内的; 保持不动,并且正确地传递给数据库引擎。最后为恢复为原来的 分隔符,可以使用 delimieter;A3)除了 '\' 符号外,任何字符都可以用作语句分隔符;
delimiter //
drop procedure if exists min_avg_max_price //
create procedure min_avg_max_price(out p1 decimal(8,2),out p2 decimal(8,2),out p3 decimal(8,2)
)
beginselect min(price) into p1from product;select avg(price) into p2from product;select max(price) into p3from product;
end //
delimiter ;
A1)该存储过程接收3个参数: p1, p2, p3;A2)关键字out:指出了相应的参数用来从存储过程中传入一个值(返回给调用者);(也即是看做 参数的数据类型)A3)MySQL 支持3中参数类型: in(传递给存储过程),out(从存储过程传递给调用者) 和 inout (对存储过程传入和传出);A4)存储过程的执行代码: 位于 begin 和 end 语句内;
delimiter //
drop procedure if exists order_sum //
create procedure order_sum(in p_name varchar(30),in p_num int,out p_sum decimal(8,2)
)
beginselect p_num*p.price into p_sum from product p where p.name=p_name;
end //
delimiter ;
delimiter //
drop procedure if exists tax_order_sum //
create procedure tax_order_sum(in taxable boolean,in p_name varchar(30),in p_num int,out p_sum decimal(8,2)
)comment 'return order sum with and without tax'
begin-- declare variable for tax_order_sum.-- attention for the difference between variable and parameter.declare taxrate int default 6;select p_num*p.price into p_sum from product p where p.name=p_name;if taxable thenselect p_sum + p_sum*taxrate/100 into p_sum;end if;
end //
delimiter ;
A1)增加了注释 comment;A2)添加了另外一个参数 taxable,是否交税;(缴税)A3)declare用于声明局部变量;(干货——注意参数和变量的区别);A4)上述代码还使用到了 if end if 语句;A5)boolean 类型的参数:0表假,1表真;
supplement)检查存储过程: show create procedure tax_order_sum;
step1)在能够使用游标前,必须声明(定义)它;step2)一旦声明后,必须打开游标以供使用;step3)对于填有数据的游标,根据需要取出(检索)各行;step4)在结束游标使用时,必须关闭游标;
-- create a temp table.drop table if exists temp_sum_pricecreate table temp_sum_price(id int,sum_price decimal(8,2));
3)打开游标, 使用游标数据和关闭游标
-- open the cursor.open mycursor; -- declare variables.declare vendor_id int;declare sum_price decimal(8,2);-- use cursor data.
fetch mycursor into vendor_id,sum_price;-- close the cursor.close mycursor;
delimiter //
drop procedure if exists total_price_with_cursor;create procedure total_price_with_cursor(
) comment 'computing sum of price grouped by vendor'
begin-- declare variables.declare vendor_id int;declare sum_price decimal(8,2);declare done boolean; -- declare the cursor.(highlight line)declare mycursor cursor forselect v.id, sum(price) from product p,vendor v where p.vendor=v.id group by vendor;-- declare continue handler.declare continue handler for sqlstate '02000' set done=1; -- create a temp table.drop table if exists temp_sum_price;create table temp_sum_price(vendor_id int ,sum_price decimal(8,2)); -- open the cursor.open mycursor; -- repeat to call fetch clauserepeatfetch mycursor into vendor_id,sum_price; -- (highlight line)insert into temp_sum_price values(vendor_id,sum_price);until done end repeat;-- close the cursor.close mycursor;
end //
delimiter ;
A1)declare continue handler for sqlstate '02000' set done=1;这条语句定义了一个 continue handler, 它是在条件出现时被执行的代码。A2)上述代码指出当,SQLSTATE ‘02000’出现时,set done=1。SQLSTATE ‘02000’ 是一个未找到的条件,当repeat 由于没有更多的行提供循环而不能继续时,出现这个条件;A3)declare 语句的次序:用declare 语句定义的局部变量必须在定义任意游标或句柄前定义,而句柄必须在游标后定义,不遵循此顺序将产生错误消息;
i1)唯一的触发器名;i2)触发器关联的表;i3)触发器应该响应的活动(delete,insert或update);i4)触发器何时执行(处理前或处理后);
drop trigger if exists t_insert_product;
delimiter //
create trigger t_insert_product after insert on productfor each row
begininsert into temp_auto_increment values(null,new.id);
end //
delimiter ;
A1)create trigger 用来创建名为 product的新触发器;触发器可以在一个操作发生之前或之后执行;这里给出了 after insert,所以此触发器将在insert 语句成功执行后执行;A2)这个触发器还指定了 for each row,因此代码对每个插入行执行;
A1)触发器按照每个表每个事件每次地定义,每个表每个事件每次只允许一个触发器。因此,每个表最多支持6个触发器(每条insert, update,deleter的之前和之后);A2)单一触发器不能与多个事件或多个表关联,所以,如果你需要一个对 insert 和 update 操作执行的触发器,则应该定义两个触发器;
drop trigger if exists t_insert_product;
p1)在insert触发器代码内,可以引用一个名为 new 的虚拟表,访问被插入的行;p2)在 before insert 触发器内,new 中的值也可以被更新(允许更改被插入的值);p3)对于 auto_increment列,new 在 insert执行之前包含0,在insert执行后包含新的自动生成值;
drop trigger if exists after_insert_product;
delimiter //
create trigger after_insert_product after insert on productfor each row
begininsert into temp_auto_increment values(null,new.id);
end //
delimiter ;
p1)在delete触发器代码内,你可以引用一个名为 old 的虚拟表,访问被删除的行;p2)old中的值全部是只读的,不能更新;drop trigger if exists after_delete_product; delimiter // create trigger after_delete_product after delete on productfor each row begininsert into temp_auto_increment values(null,old.id); end // delimiter ;
A1)上面的代码定义了一个触发器 after_delete_trigger,用于在 delete 后触发;A2)触发事件的工作是向 temp_auto_increment 表中插入 删除行的id;
p1)在update 触发器代码内,你可以引用一个名为 old的虚拟表访问以前(update之前)的值,引用一个名为 new的虚拟表访问新更新的值;p2)在before update 触发器内,new 中的值可能也被更新(允许更改将要用于 update 语句中的值);p3)old中的值 全都是只读的,不能更新;drop trigger if exists before_update_product; delimiter // create trigger before_update_product before update on productfor each row beginset new.name=upper(new.name); end // delimiter ;
A1)以上代码的定义了一个触发器before_update_product ,在update 前触发;A2)触发事件的工作是 将update的所在行的name设置为 大写;
A1)与其他DBMS相比,MySQL5 中支持的触发器相当初级;A2)创建触发器可能需要特殊的安全访问权限,但是,触发器的执行是自动的。如果insert,update和delete语句能够执行,则相关的触发器也能执行;A3)应该用触发器来保证数据的一致性(大小写,格式等)。在触发器中执行这些类型的处理的优点是它总是进行这种处理,而且是透明地进行,与client 引用无关;A4)触发器的一种非常有意义的 使用是创建审计跟踪。使用触发器,把更改记录到另一个表非常容易;A5)MySQL触发器不支持call 语句,表明 不能从触发器内调用存储过程;(干货——MySQL触发器内不能调用存储过程)
MySQL存储过程+游标+触发器相关推荐
- mysql 动态传入表名 存储过程_面试再问MySQL存储过程和触发器就把这篇文章给他...
Mysql存储过程及触发器trigger 存储过程 一.一个简单的存储过程 1,一个简单的存储过程 delimiter $$create procedure testa()begin Select * ...
- MySQL存储过程 游标
MySQL存储过程 游标 如何在存储过程中使用MySQL游标来遍历SELECT语句返回的结果集 MySQL游标简介 要处理存储过程中的结果集,请使用游标.游标允许您迭代查询返回的一组行,并相应地处理 ...
- mysql存储过程-游标
-- 2022-05-03 星期二 1924 mysql存储过程-游标 -- 参考:https://wenku.baidu.com/view/4cc6c15b158884868762caaedd338 ...
- MySQL存储过程和触发器的实现--数据库学习笔记
从MySQL5.0版本开始就对存储过程和触发器进行了支持,在MySQL进行学习前,先查看您所使用的版本吧,方法有: 1.$mysql -V //linux终端下 2.select version() ...
- mysql 存储过程游标删除_mysql数据库存储过程游标循环,提前退出
需求:向trade这个数据库中的每一个表增加多个字段 遇到问题:存储过程,游标,循环,动态sql执行 注意: mysql 存储过程在我所使用的5.5版本中不能使用 show 的命令,利用 inform ...
- MySQL必知必会笔记(六)存储过程 游标 触发器
第二十三章 使用存储过程 MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成 ...
- MySQL存储过程及触发器
一.存储过程 存储过程的基本格式如下: -- 声明结束符 -- 创建存储过程 DELIMITER $ -- 声明存储过程的结束符 CREATE PROCEDURE pro_test() --存储过程名 ...
- mysql 存储过程 预处理语句_用于预处理语句的MySQL存储过程游标
我有一些坏消息和好消息 . 首先是坏消息 . MySQL手册说游标不能用于使用PREPARE和EXECUTE准备和执行的动态语句 . 在游标创建时检查游标的语句,因此该语句不能是动态的 . 所以到目前 ...
- mysql存储过程与触发器的例题
1.创建存储过程 (1)创建一个存储过程,查询女同学选修的课程信息. #创建学生表 create table st_table(id int auto_increment primary key,na ...
最新文章
- linux 分析磁盘性能,03.分析性能瓶颈 - 3.4.磁盘瓶颈 - 《Linux性能调优指南》 - 书栈网 · BookStack...
- php 字符串处理
- 武汉首座无人驾驶电动汽车充电站投入使用
- 用IIS怎样在局域网内建网站
- 类与类之间关系,用C#和JavaScript体现
- 【渝粤教育】国家开放大学2018年春季 0688-21T老年精神障碍护理 参考试题
- HTML5中Web Worker技术的使用实例
- gossip 区块链_区块链中的P2P
- 老男孩Shell企业面试题30道 [答案]
- hive mysql 字符集_创建Hive表会自动更改mysql Metastore的字符集设置
- 印度打车软件Ola将登陆伦敦,或将取代被吊销伦敦执照的Uber
- 张珺 2015/07/13 个人文档
- Windows10下鼠标跳屏问题——Microsoft Serial Ballpoint
- ctags 的最简单使用
- c语言给vbs传递一组字符串,调用VBS脚本引擎,执行VBS代码。字符串的四则运算 TC...
- 406个银英稀有精英名称
- 这几天加班熬夜把所有Python库整理了一遍,非常全面!
- Android-安卓Canvas画小黄人
- 处理器后面的字母含义_CPU后面的数字和字母都是什么意思?全面解答。
- C# 实现像QQ一样隐藏窗体
热门文章
- Codeforces Round #700 (Div. 2) C. Searching Local Minimum 交互二分
- 【BZOJ3684】大朋友和多叉树【生成函数】【拉格朗日反演】【多项式幂函数】
- ARC078F - Mole and Abandoned Mine(状压DP)
- 牛客网【每日一题】5月18日 「土」秘法地震
- BZOJ4504. K个串(主席树+优先队列)
- 树哈希判断同构无根同构问题转有根同构问题
- 洛谷P4322 最佳团伙(树上dp)
- jzoj3895-数字对【RMQ,GCD,二分答案,单调队列】
- 【DP】【递归】分离与合体
- 计蒜客 91 地铁 HDU 5263 平衡大师(二分+网络流)