普通的SQL執行過程:
SQL命令要通過MySQL引擎的語法分析,若是語法正確,就會進行編譯,編譯成mysql引擎能夠識別的命令。可識別命令再執行,將執行的結果返回給客戶端。java
試想若是把語法分析與編譯的環節去掉,mysql的執行效率就能夠提升,所以要用到存儲過程。mysql
存儲過程:
存儲過程是SQL語句和控制語句的預編譯集合,以一個名稱存儲並做爲一個單元處理。存儲過程的效率要比單一的SQL執行效率高。spring
以往咱們寫兩個SQL語句,mysql引擎會對這兩個SQL語句逐一進行語法分析,逐一編譯,再逐一執行。而採用存儲過程之後,只有在建立時會進行語法分析與編譯,之後客戶端再調用,直接調用編譯後的結果,這樣就直接省略了兩個環節。sql
優勢:數據庫
- 加強了SQL語句的功能與靈活性(存儲過程寫控制語句能夠完成複雜的判斷加強了靈活性)
- 實現較快的執行速度(存儲過程在建立的時候就進行了編譯,未來使用的時候不用再從新編譯。通常的SQL語句每執行一次就須要編譯一次,因此使用存儲過程提升了效率。存儲過程也能夠理解爲預先編寫的sql子程序,在程序中直接調用這一子過程顯然要比逐條運行sql語句效率高)
- 減小網絡流量(客戶端每次直接發送複雜SQL語句到mysql服務器引擎執行時,經過http協議所提交的數據量相對而言較大。但經過存儲過程只要提交存儲過程的名字以及相關參數便可,所以存儲過程的名字也要儘可能精簡)
建立無參存儲過程:
- CREATE PROCEDURE 是建立存儲過程的關鍵字
- 調用存儲過程:CALL 存儲過程名字(參數1,參數2);
建立帶有IN類型參數的存儲過程:
- DELIMITER // 將分隔符(本來是分號)改爲//
- IN fade_id SMALLINT UNSIGNED表明存儲過程傳入的參數,注意寫上參數數據類型,最好跟數據庫中定義該字段時相同
- 注意不能是IN id SMALLINT UNSIGNED,若這樣寫,在下面的SQL語句就是WHERE id = id。雖然咱們認爲第一個id是字段,第二個id是參數,可是mysql會認爲兩個id都是字段,這樣執行會所有記錄都被刪除!
- BEGIN … END內是執行的合法SQL語句!
- 在調用存儲過程時注意先將分隔符轉換爲分號
- 能夠看到成功刪除了id爲10對應的記錄
建立帶有 IN 和 OUT 類型參數的存儲過程:安全
- OUT clientNums SMALLINT UNSIGNED 一樣要規定返回數據的類型
- INTO 關鍵字將SELECT 查詢的結果賦予clientNums參數
- 在調用存儲過程時OUT對應的參數用@nums代替,即定義了一個變量存儲返回的數據。SELECT @nums;就能查看返回的數據
- 能夠看到數據表中id爲8對應的記錄被刪除並返回了刪除後正確的記錄數目
建立帶有多個OUT類型參數的存儲過程:
先看看如今client表中的數據(共有11條數據記錄,其中有3個年齡爲100的數據記錄):服務器
建立存儲過程:網絡
- ROW_COUNT()查看的是SQL影響的記錄條數,不須要加表名
運行並查看結果:spa
- 查看返回的兩個OUT類型的值,確實是3條記錄被刪除(年齡爲100的記錄有三條)。剩下的數據記錄共有8條
- 數據表中再也不有age = 100的記錄
總結:
有關存儲過程,這裏只講到怎麼使用與簡單的數據庫執行效率,網絡流量問題。還有不少關於存儲過程的知識例如:權限安全,結合數據庫事務處理SQL邏輯以及實際開發中的適當運用(與spring的事務比較)還有待完善。.net