掌握 MySQL 內建函數與存儲過程,能顯著提升 SQL 編寫效率、封裝業務邏輯、減少網路交互。本文系統整理數學、字符串、日期、系統、加密、流程控制六大類函數,並詳細講解存儲過程/函數的創建、調用、管理與優勢。
| 函數 | 說明 | 範例 | 結果 |
|---|---|---|---|
CEIL(x) | 向上取整 | CEIL(1.2) | 2 |
FLOOR(x) | 向下取整 | FLOOR(1.9) | 1 |
MOD(x,y) | 取餘(模運算) | MOD(3,8) | 3 |
POWER(x,y) | 冪運算 x^y | POWER(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,零返回 0 | SIGN(-5) | -1 |
EXP(x) | e 的 x 次方 | EXP(1) | 2.718... |
技巧: ORDER BY RAND() 可實現隨機排序,但大表慎用(全表掃描)。
| 函數 | 說明 | 範例 | 結果 |
|---|---|---|---|
LENGTH(str) | 字節長度 | LENGTH('開課吧') | 6 (UTF-8 中文佔 3 字節) |
CHAR_LENGTH(str) | 字符數 | CHAR_LENGTH('開課吧') | 3 |
CONCAT(s1,s2,...) | 拼接字符串,任一參數為 NULL 結果為 NULL | CONCAT('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 |
| 函數 | 說明 | 範例 |
|---|---|---|
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 |
VERSION():資料庫版本CONNECTION_ID():當前連線 IDDATABASE() / SCHEMA():當前資料庫USER() / CURRENT_USER() / SYSTEM_USER():當前用戶CHARSET(str):字符串字符集LAST_INSERT_ID():最後自增 IDMD5(str):MD5 雜湊(32 位十六進制)PASSWORD(str):MySQL 密碼加密算法(注意:5.7.6+ 已棄用,8.0 移除,僅供舊版兼容)| 函數 | 說明 | 範例 |
|---|---|---|
IF(cond, true_val, false_val) | 條件判斷 | IF(age>18,'成年','未成年') |
IFNULL(val, default) | val 為 NULL 返回 default,否則返回 val | IFNULL(NULL,'無') → '無' |
CASE WHEN ... THEN ... ELSE ... END | 多條件分支(標準 SQL) | 見下文存儲過程範例 |
DEFINER/INVOKER 權限模型控制訪問;避免直接暴露表結構。語法結構:
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 ;
函數必須有 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 ;
CALL sp_name([params...])。CALL sp_demo();、CALL age_from_user(1, @age); SELECT @age;SELECT username_from_user(3);| 操作 | 語句 |
|---|---|
| 查看過程狀態 | 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; |
DECLARE ... HANDLER 捕獲異常,避免事務殘留。SQL SECURITY DEFINER 並授予調用者僅 EXECUTE 權限。sp_、fn_)區分業務域。MySQL 內建函數涵蓋數學、字符串、日期、系統、加密、流程控制等日常開發高頻需求;存儲過程/函數提供了強大的服務端邏輯封裝能力。熟練掌握並遵循最佳實踐,能讓資料庫層承擔更多計算任務,釋放應用層壓力,構建更高效、安全、可維護的系統。