萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL DELIMITER 完整解析:預存程序、觸發器、函數定義必備

MySQL DELIMITER 深度解析:為什麼需要、怎麼用、常見坑

DELIMITER 是 MySQL 客戶端指令,非 SQL 標準。它定義「語句結束符號」,讓客戶端知道何時將輸入的多行文字送往 Server 執行。預存程序、觸發器、函數定義包含多個 ;,**必須**暫時變更分隔符。

為什麼需要 DELIMITER?


-- 不改分隔符,直接輸入:
mysql> CREATE FUNCTION shorten(s VARCHAR(255), n INT)
    -> RETURNS VARCHAR(255)
    -> BEGIN
    ->   IF ISNULL(s) THEN
    ->     RETURN '';    -- 這裡的 ; 會被誤判為語句結束!
    ->   END IF;
    -> END;
-- 錯誤:過早執行,語法不完整

正確用法


mysql> DELIMITER //          -- 將結束符改為 //
mysql> CREATE FUNCTION shorten(s VARCHAR(255), n INT)
    -> RETURNS VARCHAR(255)
    -> BEGIN
    ->   IF ISNULL(s) THEN
    ->     RETURN '';      -- 這裡的 ; 只是函數體一部分
    ->   ELSEIF n < 15 THEN
    ->     RETURN LEFT(s, n);
    ->   ELSE
    ->     IF CHAR_LENGTH(s) <= n THEN
    ->       RETURN s;
    ->     ELSE
    ->       RETURN CONCAT(LEFT(s, n-10), '...', RIGHT(s, 5));
    ->     END IF;
    ->   END IF;
    -> END                -- 無分號
    -> //                 -- 這裡的 // 才是真正結束
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;        -- **務必恢復預設分隔符**

常用分隔符選擇

分隔符優點缺點適用場景
//簡短、不易衝突註釋 // 衝突預存程序/函數/觸發器
$$PostgreSQL 風格、不衝突較長複雜程序、遷移專案
;;雙分號極少衝突極少見

完整範例:預存程序 + 觸發器 + 函數

預存程序


DELIMITER //
CREATE PROCEDURE simpleproc (OUT param1 INT)
BEGIN
    SELECT COUNT(*) INTO param1 FROM t;
END //
DELIMITER ;

CALL simpleproc(@a);
SELECT @a;  -- 結果: 3

觸發器


DELIMITER //
CREATE TRIGGER trg_ins BEFORE INSERT ON test
FOR EACH ROW
BEGIN
    SET NEW.created_at = NOW();
END //
DELIMITER ;

函數


DELIMITER //
CREATE FUNCTION get_full_name(first VARCHAR(50), last VARCHAR(50))
RETURNS VARCHAR(101)
DETERMINISTIC
BEGIN
    RETURN CONCAT(first, ' ', last);
END //
DELIMITER ;

SELECT get_full_name('John', 'Doe');  -- John Doe

客戶端工具差異

工具DELIMITER 支援備註
mysql CLI完整支援標準方式
MySQL Workbench腳本區支援執行腳本 (Ctrl+Shift+Enter) 自動處理
Navicat物件編輯器無需手寫 DELIMITER,UI 直接編輯
phpMyAdminSQL 分頁支援大 SQL 區塊自動識別
DBeaver腳本支援@set delimiter // 支援
JDBC/應用程式**不支援**應用層無需 DELIMITER,直接傳完整 SQL 字串

常見錯誤與避坑

  • 忘記恢復 DELIMITER ;:後續所有指令失效,需重新連線
  • 分隔符衝突:程式碼中包含 // 註釋 → 改用 $$
  • 應用程式中使用:JDBC/ORM/遷移工具**不需要** DELIMITER,直接傳完整建立語句
  • DELIMITER **不支援**在預存程序/函數/觸發器內部使用

原理補充

  • DELIMITER 只影響**客戶端解析器**,不送往 Server
  • Server 端只收到完整的 CREATE PROCEDURE ... END 字串
  • 資料庫中儲存的程式碼**不包含** DELIMITER
  • SHOW CREATE PROCEDURE 顯示的定義中無 DELIMITER
copyright © 萬盛學電腦網 all rights reserved