1. 程式人生 > >MySQL之存儲過程創建和調用

MySQL之存儲過程創建和調用

可讀性 primary 數據表 刪掉 start dml lec 插入 ora

一、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之存儲過程創建和調用