MySQL 存储过程/游标/触发器/事务

来源:http://www.cnblogs.com/zhuyp1015/p/3575823.html

将会用到的几个表

mysql> DESC products;

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| prod_id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| vend_id    | int(11)      | YES  |     | NULL    |                |
| prod_name  | varchar(100) | YES  |     | NULL    |                |
| prod_price | int(11)      | YES  |     | NULL    |                |
| prod_desc  | varchar(300) | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

mysql> DESC orders;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| order_num  | int(11)     | NO   | PRI | NULL    | auto_increment |
| order_date | date        | YES  |     | NULL    |                |
| cust_id    | varchar(20) | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

mysql> DESC orderitems;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| order_num  | int(11)     | NO   | PRI | NULL    | auto_increment |
| order_item | varchar(20) | YES  |     | NULL    |                |
| prod_id    | varchar(20) | YES  |     | NULL    |                |
| quantity   | int(11)     | YES  |     | NULL    |                |
| item_price | int(11)     | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

创建存储过程:参数需要指定 OUT / IN / INOUT

CREATE PROCEDURE productpricing(

OUT pl DECIMAL(8,2),

OUT ph DECIMAL(8,2),

OUT pa DECIMAL(8,2)

)

BEGIN

SELECT Min( prod_price)

INTO pl

FROM products;

SELECT Max( prod_price)

INTO ph

FROM products;

SELECT Avg( prod_price)

INTO pa

FROM products;

END;

调用存储过程:

CALL productpricing( @pricelow, @pricehigh, @priceaverage);

选择返回的值:

SELECT @pricelow;

SELECT @pricelow,@pricehigh,@priceaverage  --选择多个

删除存储过程:

DROP PROCEDURE productpricing;

-------------------------------------------------

CREATE PROCEDURE ordertotal(

INT onumber INT,

OUT ototal DECIMAL(8,2)

)

BEGIN

SELECT sum(item_price * quantity)

FROM orderitems

WHERE order_num = onumber

INTO ototal;

END;

调用:

CALL ordertotal(20005, @total);

SELECT @total;

存储过程实际场景:需要获得以前一样的订单合计,但需要对合计增加营业税,不过只针对某些顾客,那么需要做:

1. 获得合计

2. 把营业税有田间的添加到合计

3. 返回合计(带或不带税)

CREATE PROCEDURE ordertotal(

IN onumber INT,

IN taxable BOOLEAN,

OUT octoal DECIMAL(8,2)

)

BEGIN

-- 注释 Declare variable for total

DECLARE total DECIMAL(8,2);

DECLARE taxrate INT DEFAULT 6;

-- Get the order total

SELECT Sum( item_price * quantity)

FROM orderitems

WHERE order_num = onumber

INTO total;

-- Is this taxable ?

IF taxable THEN

SELECT total + (tatal / 100 *taxrate) INTO total;

END IF;

SELECT total INTO ototal;

END;

CALL ordertotal(2005, 0, @total);

SELECT @total;

检查存储过程:

SHOW CREATE PROCEDURE ordertoal;

--------------------------------------------------

--------------------------------------------------

SELECT 返回的是一个结果集,可能含有多行数据,有时候需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标(CURSOR) 是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被语句检索出来的结果集。在存储了游标之后应用程序可以根据需要滚动或浏览其中的数据。

游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或作出更改。

MySQL游标只能用于存储过程。

使用游标的步骤:

1. 定义游标(针对某个SELECT语句)

2. 打开游标

3. 对填有数据的游标,根据需要取出各行

4. 关闭游标

简单示例:

CREATE PROCEDURE processorders()

BEGIN

DECLARE ordernumbers CURSOR

FOR

SELECT order_num FROM orders;

OPEN ordernumbers;

CLOSE ordernumbers;

END;

---------------- 使用游标数据

CREATE PROCEDURE processorders()

BEGIN

DECLARE o INT;

DECLARE ordernumbers CURSOR

FOR

SELECT order_num FROM orders;

OPEN ordernumbers;

 FETCH ordernumbers INTO o;

CLOSE ordernumbers;

END;

----------------循环检索数据

CREATE PROCEDURE processorders()

BEGIN

DECLARE o INT;

DECLARE done BOOLEAN DEFAULT 0;

DECLARE ordernumbers CURSOR

FOR

SELECT order_num FROM orders;

-- Declare continue handler

DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000‘ SET done = 1;

-- SQLSTATE ‘02000‘ 是一个未找到条件,当没有更多行可读的时候设置 done = 1 然后退出

OPEN ordernumbers;

REPEAT

      FETCH ordernumbers INTO o;

UNTIL done END REPEAT;

CLOSE ordernumbers;

END;

-----------------------------------------------------

-----------------------------------------------------

------使用table 记录CURSOR FETCH 出来的值

CREATE PROCEDURE processorders()

BEGIN

DECLARE o INT;

DECLARE done BOOLEAN DEFAULT 0;

DECLARE t DECIMAL(8,2);

DECLARE ordernumbers CURSOR

FOR

SELECT order_num FROM orders;

-- Declare continue handler

DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000‘ SET done = 1;

-- SQLSTATE ‘02000‘ 是一个未找到条件,当没有更多行可读的时候设置 done = 1 然后退出

-- 创建table

CREATE TABLE IF NOT EXISTS ordertotals(

order_num INT, total DECIAML(8,2)

);

OPEN ordernumbers;

REPEAT

      FETCH ordernumbers INTO o;

CALL ordertotal(o,1,t); -- 调用过程

-- 插入table

INSERT INTO ordertotals(order_num, total)

VALUES(o,t);

UNTIL done END REPEAT;

CLOSE ordernumbers;

END;

-----------------------------------------------------

-----------------------------------------------------

触发器:在事件发生的时候自动执行

创建触发器时,需要给出4条信息:

1.唯一的触发器名

2.触发器关联的表

3.触发器应该响应的活动(DELETE/ INSERT / UPDATE)

4.触发器何时执行

--------------------

CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT ‘Product added‘;

--该例子触发器在每次插入之后显示 Product added 消息

---删除触发器

DROP TRIGGER newproduct;

--------------------------------------------------

--------------------------------------------------

事务处理( transaction processing) 可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么不执行。

几个术语:

事务:transaction 指一组SQL语句

回退:rollback 指撤销指定SQL语句过程

提交:commit 指将为存储的SQL语句结果写入数据库表

保留点:savepoint 指事务处理中设置的临时占位符,你可以对它发布退回

-------------

SELECT * FROM ordertotals;

START TRANSACTION;

DELETE FROM ordertotals; --删除表

SELECT * FROM ordertotals; -- 确认删除

ROLLBACK; -- 回滚

SELECT * FROM ordertotal; -- 再次显示

--------------commit

一般的MySQL语句都是直接针对数据库表进行操作,进行隐含的提交,即提交操作是自动执行的。

在 事务处理中,提交不会隐含执行,需要使用COMMIT语句。

START TRANSACTION;

DELETE FROM orderitems WHERE order_num = 20010;

DELETE FROM orders WHERE order_num = 20010;

COMMIT;

时间: 2024-08-10 21:29:53

MySQL 存储过程/游标/触发器/事务的相关文章

mysql存储过程和触发器的应用

***********[mysql 存储过程和触发器 -- 别安驹]********************* 1.什么情况下使用存储过程? 完成一些比较麻烦的逻辑,比如多表在mysql端的cpu很空闲的情况下,用存储过程是不错的选择, 1.1.简单的存储过程示例:简单写入 DELIMITER $$ USE `curl_test`$$ DROP PROCEDURE IF EXISTS `data_s`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `

mysql存储过程中使用事务

1 DROP PROCEDURE IF EXISTS test_sp1 2 CREATE PROCEDURE test_sp1( ) 3 BEGIN 4 DECLARE t_error INTEGER DEFAULT 0; 5 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; 6 7 START TRANSACTION; 8 INSERT INTO test VALUES(NULL, 'test sql 001'); 9 INSER

MySql 中游标,事务,终止存储过程方法总结

最近在项目开发中,有段逻辑处理,需要在网站,app,后台分别运行,这样给后期的维护带来了很大的不方便,容易遗漏app端或者后台,所以讲java代码转换成存储过程,把逻辑处理写在了mysql端,其中遇到游标,事务的处理.问题并不困难,只是容易忘记,做了一下总结: DECLARE err INT DEFAULT 0;#声明一个整形变量err,默认值是0 DECLARE orderDone INT DEFAULT FALSE;-- 遍历游标结束标识 DECLARE cur_order CURSOR F

mysql 存储过程 函数 触发器

mysql存储过程与函数 存储过程demo mysql> delimiter // -- 这里//为修改默认分隔符: mysql> CREATE PROCEDURE simpleproc (OUT param1 INT) -> BEGIN -> SELECT COUNT(*) INTO param1 FROM t; -> END// Query OK, 0 rows affected (0.00 sec) mysql> delimiter ; // -- 改回来这里的默

Mysql之视图 触发器 事务 存储过程 函数

视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用 #两张有关系的表 mysql> se

MySQL拓展 视图,触发器,事务,存储过程,内置函数,流程控制,索引,慢查询优化

视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view teacher2course as select * from teacher inner join course on teacher.tid = course.teacher_id; 强调: (1)在硬盘中,视图只有表结构文件,没有表结构数据 (2)视图通常是用于查询,尽量不要修改视图中的数据 dro

Oracle数据库PL/SQL存储过程游标触发器

创建一个添加FOOD的存储过程 create or replace procedure add_food_pro (name in varchar,price in number,description in varchar) as  begin insert into food (f_name,f_price,description)values(name,price,description); commit; end; --下面的代码是调用存储过程 begin add_food_pro('糖

MySQL存储过程及触发器

一.存储过程 存储过程的基本格式如下: -- 声明结束符 -- 创建存储过程 DELIMITER $ -- 声明存储过程的结束符 CREATE PROCEDURE pro_test() --存储过程名称(参数列表) BEGIN -- 可以写多个sql语句; -- sql语句+流程控制 SELECT * FROM employee; END $ -- 结束 结束符 -- 执行存储过程 CALL pro_test(); -- CALL 存储过程名称(参数); -- 删除存储过程 DROP PROCE

mysql存储过程 --游标的使用 取每行记录 (多字段)

delimiter $ create PROCEDURE phoneDeal() BEGIN DECLARE id varchar(64); -- id DECLARE phone1 varchar(16); -- phone DECLARE password1 varchar(32); -- 密码 DECLARE name1 varchar(64); -- id -- 遍历数据结束标志 DECLARE done INT DEFAULT FALSE; -- 游标 DECLARE cur_acco