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

MySQL 欄位預設值無法直接使用 NOW()?解決方案全覽

     編輯:MySQL 綜合教學

核心結論

MySQL 5.6.5 之前版本:不支援將函數(如 NOW()、CURRENT_TIMESTAMP)直接作為欄位預設值(`DEFAULT` 子句),僅允許常數值。

版本演進

版本支援情況
< 5.6.5僅 TIMESTAMP 型別可用 DEFAULT CURRENT_TIMESTAMP;DATETIME、DATE 均不支援函數預設值
5.6.5+DATETIME、TIMESTAMP、DATE 均支援 DEFAULT CURRENT_TIMESTAMP 及 ON UPDATE CURRENT_TIMESTAMP
8.0.13+進一步支援 DEFAULT (expr) 語法,允許任意非決定性函數(如 UUID()、NOW())作為預設值

歷史版本變通方案

方案 1:使用 TIMESTAMP 型別(舊版常用)

CREATE TABLE t (
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

缺點:TIMESTAMP 範圍 1970-2038,受時區影響,5.6.6 前一張表僅能有一個自動更新的 TIMESTAMP 欄位。

方案 2:應用層寫入(推薦)

-- 應用程式插入時顯式指定
INSERT INTO t (create_time) VALUES (NOW());
-- 或由 ORM/框架自動填充(如 Hibernate @CreationTimestamp、MyBatis Plus fillStrategy)

優點:邏輯集中、跨資料庫可移植、避免觸發器效能開銷。

方案 3:觸發器(BEFORE INSERT)

CREATE TRIGGER t_bi BEFORE INSERT ON t
FOR EACH ROW
BEGIN
    IF NEW.create_time IS NULL THEN
        SET NEW.create_time = NOW();
    END IF;
    IF NEW.update_time IS NULL THEN
        SET NEW.update_time = NOW();
    END IF;
END;

缺點:增加寫入延遲、維護成本高、複雜業務易出錯。

方案 4:視圖 + INSTEAD OF 觸發器(MySQL 不支援 INSTEAD OF,故不適用)

現代最佳實踐(MySQL 5.7+ / 8.0)

CREATE TABLE orders (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
    -- 8.0.13+ 更多彈性
    trace_id CHAR(36) DEFAULT (UUID()) COMMENT '追蹤 ID'
);

避坑提醒

  • DEFAULT NOW() 在舊版會報錯 Invalid default value for 'col'。
  • CURRENT_TIMESTAMP 與 NOW() 語義相同,但前者為標準 SQL 關鍵字,移植性更好。
  • ON UPDATE CURRENT_TIMESTAMP 僅在 UPDATE 實際修改該行時觸發,REPLACE、INSERT ... ON DUPLICATE KEY UPDATE 亦會觸發。
  • 複寫環境下,主從時區不一致會導致 TIMESTAMP 值不同步,建議統一使用 DATETIME + 應用層寫入 UTC 時間。

總結

舊版 MySQL 確實不支援 DEFAULT NOW(),但透過 TIMESTAMP、應用層賦值、觸發器均可解決。現代版本(5.6.5+)已原生支援 DATETIME DEFAULT CURRENT_TIMESTAMP,8.0 更開放任意運算式。**強烈建議升級至 8.0 並採用原生語法**,簡潔且效能最優。

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