首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 存儲過程與常用函數完全指南

     編輯:MySQL 綜合教學

MySQL 存儲過程與常用函數完全指南

掌握 MySQL 內建函數與存儲過程,能顯著提升 SQL 編寫效率、封裝業務邏輯、減少網路交互。本文系統整理數學、字符串、日期、系統、加密、流程控制六大類函數,並詳細講解存儲過程/函數的創建、調用、管理與優勢。

一、常用內建函數速查

1. 數學函數

函數說明範例結果
CEIL(x)向上取整CEIL(1.2)2
FLOOR(x)向下取整FLOOR(1.9)1
MOD(x,y)取餘(模運算)MOD(3,8)3
POWER(x,y)冪運算 x^yPOWER(3,2)9
ROUND(x,d)四捨五入保留 d 位小數ROUND(123.456,2)123.46
TRUNCATE(x,d)截取 d 位小數(不四捨五入)TRUNCATE(123.456,2)123.45
ABS(x)絕對值ABS(-123)123
PI()圓周率PI()3.141593
RAND()0-1 隨機數RAND()0.123...
RAND(seed)指定種子的可重複隨機數RAND(2)固定值
SIGN(x)符號:正返回 1,負返回 -1,零返回 0SIGN(-5)-1
EXP(x)e 的 x 次方EXP(1)2.718...

技巧: ORDER BY RAND() 可實現隨機排序,但大表慎用(全表掃描)。

2. 字符串函數

函數說明範例結果
LENGTH(str)字節長度LENGTH('開課吧')6 (UTF-8 中文佔 3 字節)
CHAR_LENGTH(str)字符數CHAR_LENGTH('開課吧')3
CONCAT(s1,s2,...)拼接字符串,任一參數為 NULL 結果為 NULLCONCAT('S','S','M')SSM
CONCAT_WS(sep,s1,s2...)指定分隔符拼接,忽略 NULL 參數CONCAT_WS('#','S','w','M')S#w#M
UPPER/UCASE(str)轉大寫UPPER('abc')ABC
LOWER/LCASE(str)轉小寫LOWER('ABC')abc
LEFT(str,n)左側 n 字符LEFT('kaikeba',3)kai
RIGHT(str,n)右側 n 字符RIGHT('天天向上',2)向上
LPAD(str,len,pad)左填充至指定長度LPAD('KAI',5,'!')!!KAI
RPAD(str,len,pad)右填充RPAD('KAI',5,'!')KAI!!
TRIM(str)去除首尾空格TRIM(' AVC ')AVC
TRIM(rem FROM str)去除首尾指定字符TRIM('A' FROM 'ABCANA')BCAN
REPEAT(str,n)重複 n 次REPEAT('A',3)AAA
SPACE(n)產生 n 個空格CONCAT('+',SPACE(5),'+')+ +
REPLACE(str,from,to)替換所有匹配子串REPLACE('AAAASDDFO','A','R')RRRRSDDFO
STRCMP(s1,s2)比較:相等 0,s1大 1,s1小 -1,不區分大小寫STRCMP('A','a')0
SUBSTRING(str,pos,len)從 pos 截取 len 字符,pos 可為負(從末尾算起)SUBSTRING('KAIKEBA',-2,2)BA
REVERSE(str)反轉字符串REVERSE('ABCDE')EDCBA
ELT(n,str1,str2...)返回第 n 個字符串ELT(3,'a','b','c')c

3. 日期時間函數

函數說明範例
CURDATE() / CURRENT_DATE()當前日期2024-01-15
CURTIME() / CURRENT_TIME()當前時間14:30:00
NOW() / SYSDATE()當前日期時間2024-01-15 14:30:00
MONTH(date)月份數值MONTH('2024-12-16') → 12
MONTHNAME(date)月份英文名MONTHNAME(NOW()) → JANUARY
DAYNAME(date)星期幾英文名DAYNAME(NOW()) → MONDAY
DAYOFWEEK(date)星期數值(1=週日)DAYOFWEEK(NOW()) → 2
WEEKDAY(date)星期數值(0=週一)WEEKDAY(NOW()) → 0
WEEK(date)一年中的第幾週WEEK(NOW()) → 3
YEAR(date)年份YEAR(NOW()) → 2024
HOUR/MINUTE/SECOND(time)提取時/分/秒HOUR(NOW()) → 14
DATEDIFF(d1,d2)兩日期相差天數 (d1-d2)DATEDIFF('2024-01-15','2024-01-01') → 14

4. 系統/信息函數

  • VERSION():資料庫版本
  • CONNECTION_ID():當前連線 ID
  • DATABASE() / SCHEMA():當前資料庫
  • USER() / CURRENT_USER() / SYSTEM_USER():當前用戶
  • CHARSET(str):字符串字符集
  • LAST_INSERT_ID():最後自增 ID

5. 加密函數

  • MD5(str):MD5 雜湊(32 位十六進制)
  • PASSWORD(str):MySQL 密碼加密算法(注意:5.7.6+ 已棄用,8.0 移除,僅供舊版兼容)

6. 流程控制函數

函數說明範例
IF(cond, true_val, false_val)條件判斷IF(age>18,'成年','未成年')
IFNULL(val, default)val 為 NULL 返回 default,否則返回 valIFNULL(NULL,'無') → '無'
CASE WHEN ... THEN ... ELSE ... END多條件分支(標準 SQL)見下文存儲過程範例

二、存儲過程與函數詳解

核心優勢

  • 效能:預編譯緩存,減少解析優化開銷;批量操作減少網路往返。
  • 封裝:將業務邏輯封裝在資料庫層,應用端簡化。
  • 安全:通過 DEFINER/INVOKER 權限模型控制訪問;避免直接暴露表結構。
  • 維護:修改邏輯只需更新資料庫端,無需重新部署應用。

1. 創建存儲過程

語法結構:

CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic...]
routine_body

參數模式:IN(輸入)、OUT(輸出)、INOUT(輸入輸出)。

特性:LANGUAGE SQL、DETERMINISTIC(確定性)、READS SQL DATA、MODIFIES SQL DATA、SQL SECURITY {DEFINER|INVOKER}、COMMENT。

範例 1:無參數查詢

DELIMITER //
CREATE PROCEDURE sp_demo()
BEGIN
    SELECT * FROM user;
END //
DELIMITER ;

範例 2:帶輸入輸出參數

DELIMITER //
CREATE PROCEDURE age_from_user(IN user_id INT, OUT user_age INT)
READS SQL DATA
BEGIN
    SELECT age INTO user_age FROM user WHERE id = user_id;
END //
DELIMITER ;

2. 創建存儲函數

函數必須有 RETURNS 子句,體內需包含 RETURN 語句。

DELIMITER //
CREATE FUNCTION username_from_user(user_id INT)
RETURNS VARCHAR(20)
READS SQL DATA
BEGIN
    RETURN (SELECT username FROM user WHERE id = user_id);
END //
DELIMITER ;

3. 調用方式

  • 過程:CALL sp_name([params...])。
    例:CALL sp_demo();、CALL age_from_user(1, @age); SELECT @age;
  • 函數:在 SQL 表達式中直接調用。
    例:SELECT username_from_user(3);

4. 查看與管理

操作語句
查看過程狀態SHOW PROCEDURE STATUS LIKE 'sp_demo'\G
查看函數狀態SHOW FUNCTION STATUS LIKE 'username_from_user'\G
查看創建定義SHOW CREATE PROCEDURE sp_demo\G / SHOW CREATE FUNCTION username_from_user\G
查詢元數據表SELECT * FROM information_schema.ROUTINES\G
修改註釋/特性ALTER PROCEDURE sp_demo COMMENT '測試過程';
刪除DROP PROCEDURE [IF EXISTS] sp_demo; / DROP FUNCTION [IF EXISTS] username_from_user;

三、最佳實踐建議

  1. 合理使用:複雜業務邏輯、批量數據處理、報表統計適合用存儲過程;簡單計算、格式轉換用函數。
  2. 避免過度:不要將所有業務邏輯搬進資料庫,導致難以版本控制、測試、擴展。
  3. 參數驗證:過程內部優先驗證輸入參數合法性。
  4. 錯誤處理:使用 DECLARE ... HANDLER 捕獲異常,避免事務殘留。
  5. 權限最小化:採用 SQL SECURITY DEFINER 並授予調用者僅 EXECUTE 權限。
  6. 命名規範:採用統一前綴(如 sp_、fn_)區分業務域。

總結

MySQL 內建函數涵蓋數學、字符串、日期、系統、加密、流程控制等日常開發高頻需求;存儲過程/函數提供了強大的服務端邏輯封裝能力。熟練掌握並遵循最佳實踐,能讓資料庫層承擔更多計算任務,釋放應用層壓力,構建更高效、安全、可維護的系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved