将会用到的几个表
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 | |
+------------+--------------+------+-----+---------+----------------+
| 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 | |
+------------+-------------+------+-----+---------+----------------+
+------------+-------------+------+-----+---------+----------------+
| 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 | |
+------------+-------------+------+-----+---------+----------------+
+------------+-------------+------+-----+---------+----------------+
| 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;