史上最简单MySQL教程详解(进阶篇)之存储过程(一)
史上最簡單MySQL教程詳解(進階篇)之存儲過程(一)
- 史上最簡單MySQL教程詳解(進階篇)之存儲過程(一)
- 什么是存儲過程
- 存儲過程的作用
- 如何使用存儲過程
- 創(chuàng)建存儲過程
- DELIMITER改變分隔符
- 可使用的控制語句
- 開始創(chuàng)建存儲過程
- 確認存儲過程
- 使用存儲過程
- 刪除存儲過程
- 創(chuàng)建存儲過程
什么是存儲過程
SQL基本是一個命令實現(xiàn)一個處理的,是不能編寫處理流程的。雖然通過子查詢、多表連接等方式能實現(xiàn)一些高級的功能,但是具有很大的局限性。對于SQL本身是很難實現(xiàn)針對不同條件進行不同的處理或者循環(huán)等功能。即使能夠?qū)崿F(xiàn),也是十分復(fù)雜或者對于性能有極大的影響。存儲過程(Stored Procedure)就應(yīng)運而生,它可以由SQL語句和各種條件判斷、循環(huán)控制等語句組成,簡單的說:存儲過程像相互之間有聯(lián)系的SQL語句組成的“小程序”。因為SQL的執(zhí)行是需要經(jīng)歷一個:解析->編譯->執(zhí)行的過程的。存儲過程是提前經(jīng)過解析和編譯存儲在數(shù)據(jù)庫中的,用戶通過指定存儲過程的名字并給定參數(shù)(如果該存儲過程帶有參數(shù))來調(diào)用執(zhí)行它。
存儲過程的作用
提高執(zhí)行性能:
因為存儲過程是提前創(chuàng)建并保存在數(shù)據(jù)庫中的,當執(zhí)行命令時,就能免去解析和編譯的過程,能減輕數(shù)據(jù)庫的負擔,提高執(zhí)行性能。
可減輕網(wǎng)絡(luò)負擔:
因為存儲過程的執(zhí)行,只需要客戶端傳遞對應(yīng)的參數(shù)即可,并不需要多次傳遞SQL命令本身,可以大大的減輕網(wǎng)絡(luò)負擔,減少彼此之間的通信量,整體提高數(shù)據(jù)庫性能。
提高數(shù)據(jù)庫的安全性:
存儲過程禁止了對表本身的訪問,只賦予用戶對相關(guān)存儲過程的訪問權(quán)限。同時存儲過程將數(shù)據(jù)處理部分“黑匣子化”后,程序本身的可讀性和簡潔性都會有所增加。用戶不需要考慮存儲過程的內(nèi)部實現(xiàn),只需要知道應(yīng)該調(diào)用哪個存儲過程即可。
如何使用存儲過程
創(chuàng)建存儲過程
創(chuàng)建存儲過程使用的是【CREATE】語句,具體語法如下:
CREATE PROCEDURE 存儲過程名(參數(shù)1的種類 參數(shù)名1 參數(shù)1的數(shù)據(jù)類型,參數(shù)2的種類 參數(shù)名2 參數(shù)2的數(shù)據(jù)類型 ) BEGIN 數(shù)據(jù)處理過程 END上面提到的參數(shù)種類,主要分為下面三種類型:
| IN | 輸入?yún)?shù)(可省略) |
| OUT | 輸出參數(shù) |
| INOUT | 既是輸出參數(shù),也是輸入?yún)?shù) |
對于參數(shù)的數(shù)據(jù)類型,可參考這篇博文: 史上最簡單MySQL教程詳解(基礎(chǔ)篇)之常用表操作和表參數(shù)介紹
在創(chuàng)建存儲過程之前呢,還有下面幾個要點需要掌握。
DELIMITER改變分隔符
【DELIMITER】是MySQL用來改變監(jiān)視器中分離符的命令。默認的分隔符是【;】,但是,存儲過程本身就是命令的集合,所以一定還會含有其他的分隔符。那么它們彼此之間沖突和混淆,所以在創(chuàng)建存儲過程之前,我們需要將默認符換成一個完全無關(guān)的符號,只要不與其他關(guān)鍵字發(fā)生歧義即可,通常使用的是【//】。在完成創(chuàng)建之后,我們再將其回復(fù)即可。但需要提醒的是:分隔符的改變只會在啟動期間有效,重新啟動后,會自動恢復(fù)到默認狀態(tài)。
可使用的控制語句
簡單分支
IF 條件表達式1 條件表達式1為TRUE時執(zhí)行的命令 [ELSEIF 條件表達式N條件表達式N為TRUE時執(zhí)行的命令 ] [ELSE全部為False時執(zhí)行的命令 ] END IF多重分支
CASE 表達式1 WHEN 值1 THEN 表達式1 = 值1時執(zhí)行的命令 ... WHEN 值N THEN 表達式1 = 值N時執(zhí)行的命令 [ELSE 上述所有值以外執(zhí)行的命令] END CASE循環(huán)控制(后置判斷)
REPEAT 直至條件表達式為True時執(zhí)行的命令 UNTIL 條件表達式 END REPEAT循環(huán)控制(前置判斷)
WHILE 條件表達式 DO 系列命令 END WHILE開始創(chuàng)建存儲過程
mysql> DELIMITER //-> CREATE PROCEDURE sp_student (IN p_name VARCHAR(20))-> BEGIN-> IF p_name IS NULL OR p_name = "" THEN -> SELECT * FROM student ;-> ELSE -> SELECT * FROM student WHERE studentName LIKE p_name;-> END IF ;-> END -> // Query OK, 0 rows affected mysql> DELIMITER ;這樣我們就創(chuàng)建了一個【sp_student】的存儲過程。如果我們傳入?yún)?shù)【p_name】,那么他就會進行模糊查詢,否則就無條件查詢。
確認存儲過程
我們確認存儲過程使用的是【SHOW】語句,具體語法如下:
SHOW PROCEDURE STATUS \G例如:
mysql> SHOW PROCEDURE STATUS \G *************************** 27. row ***************************Db: test1Name: sp_studentType: PROCEDUREDefiner: root@localhostModified: 2018-09-13 12:03:13Created: 2018-09-13 12:03:13Security_type: DEFINERComment: character_set_client: utf8 collation_connection: utf8_general_ciDatabase Collation: utf8_unicode_ci 27 rows in set (0.00 sec)結(jié)果集參數(shù)解釋:
| Db | 所屬數(shù)據(jù)庫名 |
| Name | 存儲過程名 |
| Type | 種類(PROCEDURE:存儲過程/FUNCTION:函數(shù)) |
| Definer | 創(chuàng)建者 |
| Modified | 最終更新時間 |
| Created | 創(chuàng)建時間 |
| Security_type | 安全種類(DEFINER:存儲過程權(quán)限與創(chuàng)建用戶權(quán)限一致) |
| Comment | 備注 |
| character_set_client | 從客戶端發(fā)送過來查詢的字符編碼 |
| collation_connection | 當前連接中使用的校對順序 |
| Database Collation | 數(shù)據(jù)庫的校對順序 |
除此之外,還能使用下面的語句確認:
SHOW CREATE PROCEDURE 存儲過程名\G例如:
mysql> SHOW CREATE PROCEDURE sp_student\G *************************** 1. row *************************** Procedure: sp_student sql_mode: STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USERCreate Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_student`(IN p_name VARCHAR(20)) BEGINIF p_name IS NULL OR p_name = "" THENSELECT * FROM student ;ELSESELECT * FROM studnet WHERE studentName LIKE p_name;END IF ;END character_set_client: utf8 collation_connection: utf8_general_ci Database Collation: utf8_unicode_ci 1 row in set (0.00 sec)這個會返回一些安全的設(shè)置信息,并且名稱都會被單引號(‘ ’)括起來。
使用存儲過程
使用存儲過程,使用的是【CALL】命令,具體語法如下:
CALL 存儲過程名(參數(shù)1,...);例如:
mysql> CALL sp_student('路人%'); //提交了參數(shù) +-----------+-------------+--------------+----------------+ | studentId | studentName | studentPhone | studentAddress | +-----------+-------------+--------------+----------------+ | 4 | 路人甲 | 132 | 廣州 | | 5 | 路人乙 | 118 | 深圳 | +-----------+-------------+--------------+----------------+ 2 rows in setQuery OK, 0 rows affectedmysql> CALL sp_student(''); //未提交參數(shù) +-----------+-------------+--------------+----------------+ | studentId | studentName | studentPhone | studentAddress | +-----------+-------------+--------------+----------------+ | 1 | 張三 | 140 | 重慶 | | 2 | 李四 | 137 | 北京 | | 3 | 王五 | 135 | 上海 | | 4 | 路人甲 | 132 | 廣州 | | 5 | 路人乙 | 118 | 深圳 | +-----------+-------------+--------------+----------------+ 5 rows in set Query OK, 0 rows affected刪除存儲過程
刪除已經(jīng)創(chuàng)建的存儲過程使用【DROP】語句,具體語法如下:
DROP PROCEDURE 存儲過程名;例如:
mysql> DROP PROCEDURE sp_student; Query OK, 0 rows affected (0.00 sec)參考文獻:
MySQL存儲過程詳解
《MySQL高效編程》
別忘了關(guān)注博主的個人公眾號,有更多精彩內(nèi)容、資源分享~轉(zhuǎn)載于:https://www.cnblogs.com/newtol/p/10159087.html
總結(jié)
以上是生活随笔為你收集整理的史上最简单MySQL教程详解(进阶篇)之存储过程(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用WeexSDK,网络请求信任证书的问
- 下一篇: Linux终端操作MySQL常用命令