DELIMITER 是 MySQL 客戶端程序(mysql、mysqladmin 等)**而非服務器**的指令,用於**重新定義 SQL 語句的結束標識符**。默認終結符為分號 ;。
在定義**存儲過程**、**觸發器**、**函數**、**事件**等複合語句時,語句體內部包含多條以 ; 結束的子語句。若保持默認 ;,客戶端會在第一個 ; 處提交執行,導致語法錯誤或定義不完整。
-- 1. 修改終結符為自定義字符(常用 // 或 $$)
DELIMITER //
-- 2. 編寫複合語句,內部自由使用 ;,結尾使用新終結符
CREATE PROCEDURE simpleproc(OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t;
END //
-- 3. 恢復默認終結符
DELIMITER ;
-- 4. 調用驗證
CALL simpleproc(@a);
SELECT @a;
DELIMITER //
DROP PROCEDURE IF EXISTS pr_stat_agent //
CREATE PROCEDURE pr_stat_agent (
IN pi_date_from DATE,
IN pi_date_to DATE
)
BEGIN
-- 參數校驗與默認值
IF pi_date_from IS NULL THEN
SET pi_date_from = CURRENT_DATE();
END IF;
IF pi_date_to IS NULL THEN
SET pi_date_to = pi_date_from;
END IF;
-- 統計下一天 0 點為邊界(左閉右開)
SET pi_date_to = DATE_ADD(pi_date_from, INTERVAL 1 DAY);
-- 核心統計查詢
SELECT agent, COUNT(*) AS cnt
FROM apache_log
WHERE request_time >= pi_date_from
AND request_time < pi_date_to
GROUP BY agent
ORDER BY cnt DESC;
END //
DELIMITER ;
-- 調用示例
CALL pr_stat_agent('2023-01-01', '2023-01-07');
| 工具 | DELIMITER 支持 | 備註 |
|---|---|---|
mysql (官方命令行) | 完美支持 | 標準交互環境 |
MySQL Workbench | 支持 | SQL 編輯器工具欄有 Delimiter 輸入框 |
Navicat | 支持 | 查詢編輯器 → 設置 → Delimiter |
DBeaver | 支持 | 腳本執行模式自動識別 |
phpMyAdmin | 部分支持 | 需在 SQL 標籤頁手動輸入 DELIMITER //,易遺漏恢復 |
SQLyog | 歷史版本有 Bug | 早期版本不識別 DELIMITER,導致存儲過程創建失敗,建議升級或用命令行 |
| JDBC/ODBC/程序驅動 | **不支持** | 驅動層直接發送完整語句,無需 DELIMITER,單條提交 |
//** 作為 DELIMITER,文件頭尾必配對-- file: create_proc_stat.sql
DELIMITER //
DROP PROCEDURE IF EXISTS pr_xxx //
CREATE PROCEDURE pr_xxx (...) BEGIN ... END //
DELIMITER ;
-- 单行注釋 或 /* 多行 */,注意 -- 後需有空格OUT/INOUT 參數或 SELECT 返回結果,**不能使用 RETURN**(僅函數可用)DELIMITER 是**客戶端層面**的語句邊界標識,解決「語句中包含語句終結符」的歧義問題。**核心口訣:定義前改 //,定義後改 ;,驅動層不用,工具裡配好**。規範腳本文件結構、統一團隊習慣、區分交互與程序化調用場景,即可避開 90% 的存儲過程創建失敗坑。