存儲過程 VS 存儲函數(函數)
| | 關鍵字 |調用語法 | 返回值 | 應用場景 |
|-存儲過程-|-procedure-|-call 存儲過程()-|-理解為0個或多個-|-一般用于更新-|
| 存儲函數 | function | select 函數() | 只能是一個 | 一般用于查詢結構為一個值并返回時|
存儲函數可以放在select語句中,存儲過程不行,反之,存儲過程的功能更加強大,包括能夠執行對表的操作(創建表、刪除表等)和事務操作,這些功能是存儲函數不具備的。
存儲過程和存儲函數的 查看、修改、刪除
查看
- show create 語句查看存儲過程和函數 創建信息
show create { procedure | function } 存儲過程名或函數名
2. show status 語句查看存儲過程和函數 狀態信息
show { procedure | function } status [ like 'xxx' ]--[ like 'xxx' ] 匹配存儲過程或函數的名稱,可以省略。當省略不寫時,會列出**MySQL數據庫**中存在的所有存儲過程和函數 狀態信息
3.從information_schema.routines 表中查看存儲過程和函數的信息
MySQL 中存儲過程和函數的信息存儲在information_schema數據庫下的Routines表中。可以通過查詢該表的記錄來查詢存儲過程和函數的信息。
select * from information_schema.Routines
where ROUTINE_NAME='存儲過程 | 函數名' [and ROUTINE_TYPE={'PROCEDURE | FUNCTION '}]\G
注意如果在mysql數據庫中存在存儲過程和函數名稱相同的情況,最好指定 ROUTINE_TYPE查詢條件是存儲過程還是函數。
修改
修改存儲過程、函數,不影響存儲過程、函數功能,只能修改相關特性,使用alter語句實現
alter {procedure | function} 存儲過程或函數名稱
[characteristic]
刪除
drop { procedure | function } [IF exists] 存儲過程或函數的名
IF exists : 如果函數或存儲過程,不存在,刪除就報錯, 加 IF exists 就可以防止發生錯誤,只是產生warning ,同時可以用 show warnings 查看警告信息。
關于存儲過程使用的爭議
優點
- 存儲過程可以一次編譯多次使用。 存儲過程只在創建時進行編譯,之后的使用都不需要重新編譯,所以提高了 SQL 的執行效率
- 可以減少開發工作量。 將代碼封裝成模塊,實際是是編程的核心思想之一,這樣可以把復雜的問題拆解成不同的模塊,然后模塊之間可以重復使用,在減少開發工作量的同時,還能保證代碼的結構清晰
- 存儲過程的安全性強。我們設定存儲過程可以在設置對用戶的使用權限,這樣就和視圖一樣具有較強的安全性
- 可以減少網絡傳輸量。 因為代碼封裝到存儲過程中,每次使用只需要調用存儲過程即可,這樣就減少網絡傳輸量。
- 良好的封裝性。在進行相對復雜的數據庫操作時,原本需要使用一條一條的SQL語句。可能需要連接多次數據庫才能完成的操作。現在變成一次存儲過程,只需要連接一次即可
缺點
- 可移植性差。 存儲過程不能跨數據庫移植,比如 在 MySQL、Oracle、SQL Server里編寫的存儲過程,在換成其他數據庫時需要重新編寫
- 調試困難。 只有少數DBMS支持存儲過程的調試,對于復雜的存儲過程來說,開發和維護都不容易。雖然也有些第三方工具可以對存儲過程進行調試,但要收費
- 存儲過程的版本管理困難。 比如數據表索引發生變化了,可能會導致存儲過程失效。我們在開發軟件的時候往往需要進行版本管理,但是存儲過程本身沒有版本控制,版本迭代更新的時候很麻煩
- 它不適合高并發的場景。 高并發的場景需要減少數據庫的壓力,有時數據庫會采用分表分庫的方式,而且對可擴展性要求很高,在這種情況下,存儲過程會變得難以維護,增加數據庫的壓力。