將會用到的幾個表
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;
