MySQL之存儲過程創建和調用
1.1存儲過程:SQL中的“腳本”
1.創建存儲過程
2.調用存儲過程
3.存儲過程體
4.語句標簽塊
二、MySQL存儲過程簡單介紹:
存儲過程(Stored Procedure):
提示:#SQL語句:先編譯後執行
一組可編程的函數,是為了完成特定功能的SQL語句集,經編譯創建並保存在數據庫中,用戶可通過指定存儲過程的名字並給定參數(需要時)來調用執行。
優點(為什麽要用存儲過程?):
①將重復性很高的一些操作,封裝到一個存儲過程中,簡化了對這些SQL的調用
②批量處理:SQL+循環,減少流量,也就是“跑批”
③統一接口,確保數據的安全
相對於oracle數據庫來說,MySQL的存儲過程相對功能較弱,使用較少。
三、存儲過程的創建和調用
說明:存儲過程就是具有名字的一段代碼,用來完成一個特定的功能。創建的存儲過程保存在數據庫的數據字典中。
3.1創建存儲過程
語法介紹:
CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ([proc_parameter[,...]]) [characteristic ...] routine_body proc_parameter: [ IN | OUT | INOUT ] param_name type characteristic: COMMENT ‘string‘ | LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } routine_body: Valid SQL routine statement [begin_label:] BEGIN [statement_list] …… END [end_label]
實例1演示:
創建測試表:
CREATE TABLE `test1_event` ( `id` int(8) NOT NULL AUTO_INCREMENT, `username` varchar(20) COLLATE utf8_unicode_ci NOT NULL, `password` varchar(20) COLLATE utf8_unicode_ci NOT NULL, `create_time` varchar(20) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) #主鍵ID ) ENGINE=innodb AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
插入數據:
mysql> INSERT INTO test1_event(username,password,create_time) values(‘tomcat‘, ‘xiaohuahua‘,now());
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO test1_event(username,password,create_time) values(‘tomcat‘, ‘xiaohuahua‘,now());
Query OK, 1 row affected (0.00 sec)
mysql> select * from test1_event;
+----+----------+------------+---------------------+
| id | username | password | create_time |
+----+----------+------------+---------------------+
| 1 | tomcat | xiaohuahua | 2018-09-12 17:18:01 |
| 2 | tomcat | xiaohuahua | 2018-09-12 17:18:39 |
| 3 | tomcat | xiaohuahua | 2018-09-12 17:18:45 |
+----+----------+------------+---------------------+
3 rows in set (0.00 sec)
#創建新表備份舊表的數據來用於示例操作:
mysql> create table test_event as select * from test.test1_event;
Query OK, 3 rows affected (0.04 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test_event;
+----+----------+------------+---------------------+
| id | username | password | create_time |
+----+----------+------------+---------------------+
| 1 | tomcat | xiaohuahua | 2018-09-12 17:18:01 |
| 2 | tomcat | xiaohuahua | 2018-09-12 17:18:39 |
| 3 | tomcat | xiaohuahua | 2018-09-12 17:18:45 |
+----+----------+------------+---------------------+
3 rows in set (0.00 sec)
示例二:創建一個存儲過程(給數據表中添加用戶和密碼並附加創建的時間)
DELIMITER // ### 將語句的結束符號從分號;臨時改為兩個//(可以是自定義)
DROP PROCEDURE IF EXISTS p_test1//
CREATE PROCEDURE p_test1()
BEGIN
INSERT INTO test_event(username,password,create_time) values(‘tomcat‘, ‘xiaohuahua‘,now());
END//
delimiter ; ####將語句的結束符號恢復為分號
查看創建的存儲過程詳細信息:
mysql> show procedure status;
+------+---------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+------+---------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| test | p_test1 | PROCEDURE | root@localhost | 2018-09-12 17:44:40 | 2018-09-12 17:44:40 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
| test | p_test2 | PROCEDURE | root@localhost | 2018-09-07 18:25:54 | 2018-09-07 18:25:54 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
+------+---------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
2 rows in set (0.00 sec)
刪掉創建的存儲過程:
mysql> drop procedure p_test2 ;
Query OK, 0 rows affected (0.00 sec)
mysql> show procedure status;
+------+---------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+------+---------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| test | p_test1 | PROCEDURE | root@localhost | 2018-09-12 17:44:40 | 2018-09-12 17:44:40 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
+------+---------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
查看存儲過程的創建代碼
mysql> show create procedure p_test1\G
*************************** 1. row ***************************
Procedure: p_test1
sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `p_test1`()
BEGIN
INSERT INTO test_event(username,password,create_time) values(‘tomcat‘, ‘xiaohuahua‘,now());
END
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8_general_ci
1 row in set (0.00 sec)
mysql>
解釋:
默認情況下,存儲過程和默認的數據庫相關聯,如果先想指定存儲過程創建在某個特定的數據庫下,那麽在過程前面加數據庫名做前綴;
在定義過程時,使用DELIMITER // 命令將語句的結束符號從分號 ; 臨時改為兩個//,使得過程體中使用的分號被直接傳遞到服務器,而不會被客戶端(如mysql)解釋。
3.2調用存儲過程:call sp_name[(傳參)];
實例三:創建一個MySQL定時器調用實例二創建的MySQL存儲過程p_test1
提示mysql定時器的創建可以參考此博文:
從2018-09-12 17點47分開始每60秒執行一次
DELIMITER //
CREATE EVENT e_test1
ON SCHEDULE EVERY 60 second STARTS TIMESTAMP ‘2018-09-12 17:47:00‘
ON COMPLETION PRESERVE
DO
BEGIN
CALL p_test1();
END//
delimiter ;
mysql> select * from test_event;
+----+----------+------------+---------------------+
| id | username | password | create_time |
+----+----------+------------+---------------------+
| 1 | tomcat | xiaohuahua | 2018-09-12 17:18:01 |
| 2 | tomcat | xiaohuahua | 2018-09-12 17:18:39 |
| 3 | tomcat | xiaohuahua | 2018-09-12 17:18:45 |
| 0 | tomcat | xiaohuahua | 2018-09-12 17:47:00 |
| 0 | tomcat | xiaohuahua | 2018-09-12 17:48:00 |
| 0 | tomcat | xiaohuahua | 2018-09-12 17:49:00 |
| 0 | tomcat | xiaohuahua | 2018-09-12 17:50:00 |
| 0 | tomcat | xiaohuahua | 2018-09-12 17:51:00 |
+----+----------+------------+---------------------+
21 rows in set (0.00 sec)
說明:
在創建的存儲過程中設置了需要傳參的變量時,調用存儲過程的時候,通過傳參將數值賦值給存儲工程中設置的變量,然後進行存儲過程裏的SQL操作。
3.3存儲過程體
存儲過程體包含了在過程調用時必須執行的語句,例如:dml、ddl語句,if-then-else和while-do語句、聲明變量的declare語句等
過程體格式:以begin開始,以end結束(可嵌套)
復制代碼
BEGIN
BEGIN
BEGIN
statements;
END
END
END
復制代碼
註意:每個嵌套塊及其中的每條語句,必須以分號結束,表示過程體結束的begin-end塊(又叫做復合語句compound statement),則不需要分號。
4、為語句塊貼標簽
[begin_label:] BEGIN
[statement_list]
END [end_label]
例如:
復制代碼
label1: BEGIN
label2: BEGIN
label3: BEGIN
statements;
END label3 ;
END label2;
END label1
復制代碼
標簽有兩個作用:
①增強代碼的可讀性
②在某些語句(例如:leave和iterate語句),需要用到標簽
MySQL之存儲過程創建和調用