-- 存儲過程
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
-- 函數
CREATE FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
| 特性 | 存儲過程 | 函數 |
|---|---|---|
| 返回值 | 無(通過 OUT 參數) | 必須有 RETURNS |
| 參數模式 | IN/OUT/INOUT | 僅 IN |
| 調用方式 | CALL sp_name() | SELECT func_name() |
| 事務控制 | 可用 START/COMMIT/ROLLBACK | 不可顯式事務 |
| 動態 SQL | 可用 PREPARE | 不可用 PREPARE |
CREATE PROCEDURE Pro_Employee(IN pdepid VARCHAR(20), OUT pcount INT)
READS SQL DATA
SQL SECURITY INVOKER
COMMENT '按部門統計人數'
BEGIN
SELECT COUNT(id) INTO pcount FROM Employee WHERE depid = pdepid;
END;
CONTAINS SQL:不讀寫表數據NO SQL:不含 SQL 語句READS SQL DATA:只讀(如 SELECT)MODIFIES SQL DATA:有寫入(INSERT/UPDATE/DELETE)DEFINER:以創建者權限執行(默認)INVOKER:以調用者權限執行(更安全,推薦)SHOW PROCEDURE STATUS 可見主從複制環境開啟 log_bin,創建函數未顯式聲明確定性/數據訪問類型:
Error Code: 1418. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA
in its declaration and binary logging is enabled
函數在主庫執行結果可能與從庫不一致(如 UUID()、NOW()),導致主從數據漂移。MySQL 默認阻攔此類風險。
SET GLOBAL log_bin_trust_function_creators = 1;
-- 或配置文件 [mysqld] log_bin_trust_function_creators = 1
-- 主從雙方均需設置,重啟生效
CREATE FUNCTION fn_get_count(p_id INT)
RETURNS INT
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE cnt INT;
SELECT COUNT(*) INTO cnt FROM t WHERE id = p_id;
RETURN cnt;
END;
明確告知 MySQL:此函數確定性、只讀數據 → 主從執行結果必然一致 → 安全寫入 Binlog。
-- 狀態
SHOW PROCEDURE STATUS LIKE 'Pro_Employee'\G;
-- 創建語句
SHOW CREATE PROCEDURE Pro_Employee\G;
-- 詳細元數據
SELECT * FROM information_schema.ROUTINES
WHERE ROUTINE_NAME = 'Pro_Employee'\G;
ALTER PROCEDURE proc_name [characteristic ...];
DROP PROCEDURE [IF EXISTS] proc_name;
-- 函數同理:ALTER/DROP FUNCTION
DETERMINISTIC + 數據訪問類型SQL SECURITY INVOKER 實現最小權限mysqldump --routines 導出存檔