MySQL存储过程总结(二)
1. 存儲過程例子:
DELIMITER $$ DROP PROCEDURE IF EXISTS HelloWorld$$ CREATE PROCEDURE HelloWorld() BEGIN SELECT "Hello World!"; END$$ DELIMITER ;2. 變量聲明
?使用DECLARE來聲明,DEFAULT賦默認值,SET賦值?
DECLARE counter INT DEFAULT 0; SET counter = counter+1;3. 參數
IN為默認類型,值必須在調用時指定,值不能返回(值傳遞)
out值可以返回(指針傳遞)
INOUT值必須在調用時指定,值可以返回
CREATE PROCEDURE test(a INT, OUT b FLOAT, INOUT c INT)4. 條件判斷
IF THEN、ELSEIF、ELSE、END IF?
DELIMITER $$ DROP PROCEDURE IF EXISTS discounted_price$$ CREATE PROCEDURE discunted_price(normal_price NUMERIC(8, 2), OUT discount_price NUMERIC(8, 2)) BEGIN IF (normal_price > 500) THEN SET discount_price = normal_price * .8; ELSEIF (normal_price > 100) THEN SET discount_price = normal_price * .9; ELSE SET discount_price = normal_price; END IF; END$$ DELIMITER ;5. 循環?
DELIMITER $$ DROP PROCEDURE IF EXISTS simple_loop$$ CREATE PROCEDURE simple_loop(OUT counter INT) BEGIN SET counter = 0; my_simple_loop: LOOP SET counter = counter+1; IF counter = 10 THEN LEAVE my_simple_loop; END IF; END LOOP my_simple_loop; END$$ DELIMITER ;6. WHILE DO、END WHILE?
DELIMITER $$ DROP PROCEDURE IF EXISTS simple_while$$ CREATE PROCEDURE simple_while(OUT counter INT) BEGIN SET counter = 0; WHILE counter != 10 DO SET counter = counter+1; END WHILE; END$$ DELIMITER ;7. REPEAT、UNTILL?
DELIMITER $$ DROP PROCEDURE IF EXISTS simple_repeat$$ CREATE PROCEDURE simple_repeat(OUT counter INT) BEGIN SET counter = 0; REPEAT SET counter = counter+1; UNTIL counter = 10 END REPEAT; END$$ DELIMITER ;8. 異常處理?
如果用cursor獲取SELECT語句返回的所有結果集時應該定義NOT FOUND error handler來防止存儲程序提前終結?
如果SQL語句可能返回constraint violation等錯誤時應該創建一個handler來防止程序終結?
9. 數據庫交互?
INTO用于存儲單行記錄的查詢結果?
10. CURSOR用于處理多行記錄的查詢結果?
DELIMITER $$ DROP PROCEDURE IF EXITS cursor_example$$ CREATE PROCEDURE cursor_example() READS SQL DATA BEGIN DECLARE l_employee_id INT; DECLARE l_salary NUMERIC(8,2); DECLARE l_department_id INT; DECLARE done INT DEFAULT 0; DECLARE cur1 CURSOR FOR SELECT employee_id, salary, department_id FROM employees; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; OPEN cur1; emp_loop: LOOP FETCH cur1 INTO l_employee_id, l_salary, l_department_id; IF done=1 THEN LEAVE emp_loop; END IF; END LOOP emp_loop; CLOSE cur1; END$$ DELIMITER ;11. unbounded SELECT語句用于存儲過程返回結果集?
DELIMITER $$ DROP PROCEDURE IF EXISTS sp_emps_in_dept$$ CREATE PROCEDURE sp_emps_in_dept(in_employee_id INT) BEGIN SELECT employee_id, surname, firstname, address1, address2, zipcode, date_of_birth FROM employees WHERE department_id=in_employee_id; END$$ DELIMITER ;12. UPDATE、INSERT、DELETE、CREATE TABLE等非查詢語句也可以嵌入存儲過程里?
DELIMITER $$ DROP PROCEDURE IF EXITS sp_update_salary$$ CREATE PROCEDURE sp_update_salary(in_employee_id INT, in_new_salary NUMERIC(8,2)) BEGIN IF in_new_salary < 5000 OR in_new_salary > 500000 THEN SELECT "Illegal salary: salary must be between $5000 and $500, 000"; ELSE UPDATE employees SET salary=in_new_salary WHERE employee_id=in_employee_id; END IF: END$$ DELIMITER ;13. 使用CALL調用存儲程序
DELIMITER $$ DROP PROCEDURE IF EXISTS call_example$$ CREATE PROCEDURE call_example(employee_id INT, employee_type VARCHAR(20)) NO SQL BEGIN DECLARE l_bonus_amount NUMERIC(8,2); IF employee_type='MANAGER' THEN CALL calc_manager_bonus(employee_id, l_bonus_amount); ELSE CALL calc_minion_bonus(employee_id, l_bonus_amount); END IF; CALL grant_bonus(employee_id, l_bonus_amount); END$$ DELIMITER ;14. 一個復雜的例子?
CREATE PROCEDURE putting_it_all_together(in_department_id INT) MODIFIES SQL DATA BEGIN DECLARE l_employee_id INT; DECLARE l_salary NUMERIC(8,2); DECLARE l_department_id INT; DECLARE l_new_salary NUMERIC(8,2); DECLARE done INT DEFAULT 0; DECLARE cur1 CURSOR FOR SELECT employee_id, salary, department_id FROM employees WHERE department_id=in_department_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; CREATE TEMPORARY TABLE IF NOT EXISTS emp_raises (employee_id INT, department_id INT, new_salary NUMERIC(8,2)); OPEN cur1; emp_loop: LOOP FETCH cur1 INTO l_employee_id, l_salary, l_department_id; IF done=1 THEN /* No more rows */ LEAVE emp_loop; END IF; CALL new_salary(1_employee_id, l_new_salary); /* Get new salary */ IF (l_new_salary <> l_salary) THEN /* Salary changed */ UPDATE employees SET salary=l_new_salary WHERE employee_id=l_employee_id; /* Keep track of changed salaries */ INSERT INTO emp_raises(employee_id, department_id, new_salary) VALUES (l_employee_id, l_department_id, l_new_salary); END IF: END LOOP emp_loop; CLOSE cur1; /* Print out the changed salaries */ SELECT employee_id, department_id, new_salary from emp_raises ORDER BY employee_id; END;15. 存儲方法?
存儲方法與存儲過程的區別?
1,存儲方法的參數列表只允許IN類型的參數,而且沒必要也不允許指定IN關鍵字?
2,存儲方法返回一個單一的值,值的類型在存儲方法的頭部定義?
3,存儲方法可以在SQL語句內部調用?
4,存儲方法不能返回結果集?
各參數說明見CREATE PROCEDURE and CREATE FUNCTION Syntax?
DELIMITER $$ DROP FUNCTION IF EXISTS f_discount_price$$ CREATE FUNCTION f_discount_price (normal_price NUMERIC(8,2)) RETURNS NUMERIC(8,2) DETERMINISTIC BEGIN DECLARE discount_price NUMERIC(8,2); IF (normal_price > 500) THEN SET discount_price = normal_price * .8; ELSEIF (normal_price >100) THEN SET discount_price = normal_price * .9; ELSE SET discount_price = normal_price; END IF; RETURN(discount_price); END$$ DELIMITER ;16. 觸發器
觸發器在INSERT、UPDATE或DELETE等DML語句修改數據庫表時觸發?
觸發器的典型應用場景是重要的業務邏輯、提高性能、監控表的修改等?
觸發器可以在DML語句執行前或后觸發?
轉自:http://fyb613.blog.163.com/blog/static/325460922010044417672/
轉載于:https://www.cnblogs.com/xyxy/p/3886526.html
總結
以上是生活随笔為你收集整理的MySQL存储过程总结(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构和算法设计专题之---判断单链表
- 下一篇: pslq常用操作