簡體   English   中英

如何為 MySQL 日期時間列設置默認值?

[英]How do you set a default value for a MySQL Datetime column?

如何為 MySQL 日期時間列設置默認值?

在 SQL Server 中,它是getdate() MySQL 的等價物是什么? 如果這是一個因素,我正在使用 MySQL 5.x。

重要編輯:MySQL 5.6.5 開始,現在可以使用 DATETIME 字段來實現這一點,請查看下面的其他帖子...

以前的版本不能用 DATETIME 做到這一點......

但是你可以用 TIMESTAMP 來做到:

mysql> create table test (str varchar(32), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)

mysql> desc test;
+-------+-------------+------+-----+-------------------+-------+
| Field | Type        | Null | Key | Default           | Extra |
+-------+-------------+------+-----+-------------------+-------+
| str   | varchar(32) | YES  |     | NULL              |       | 
| ts    | timestamp   | NO   |     | CURRENT_TIMESTAMP |       | 
+-------+-------------+------+-----+-------------------+-------+
2 rows in set (0.00 sec)

mysql> insert into test (str) values ("demo");
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+---------------------+
| str  | ts                  |
+------+---------------------+
| demo | 2008-10-03 22:59:52 | 
+------+---------------------+
1 row in set (0.00 sec)

mysql>

警告:如果您定義一個默認為 CURRENT_TIMESTAMP ON 的列,您將需要始終為此列指定一個值,否則該值將在更新時自動重置為“now()”。 這意味着如果您不想更改該值,則您的 UPDATE 語句必須包含“[您的列名] = [您的列名]”(或某些其他值),否則該值將變為“now()”。 很奇怪,但確實如此。 我正在使用 5.5.56-MariaDB

在 5.6.5 版本中,可以在日期時間列上設置默認值,甚至可以創建一個在行更新時更新的列。 類型定義:

CREATE TABLE foo (
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
)

參考: http : //optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

MySQL( 版本 5.6.5 之前)不允許將函數用於默認 DateTime 值。 TIMESTAMP 由於其奇怪的行為而不適合,不建議用作輸入數據。 (請參閱MySQL 數據類型默認值。)

也就是說,您可以通過創建 Trigger來完成此操作。

我有一個帶有 DateTime 類型的 DateCreated 字段的表。 我在該表“插入前”和“ SET NEW.DateCreated=NOW() ”上創建了一個觸發器,效果很好。

我希望這對某人有幫助。

對我來說,觸發方法效果最好,但我發現這種方法有一個障礙。 考慮在插入時將日期字段設置為當前時間的基本觸發器:

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = NOW();

這通常很好,但假設您想通過 INSERT 語句手動設置字段,如下所示:

INSERT INTO tblMyTable(name, dateAdded) VALUES('Alice', '2010-01-03 04:30:43');

發生的情況是觸發器立即覆蓋您為該字段提供的值,因此設置非當前時間的唯一方法是跟進 UPDATE 語句 - 哎呀! 要在提供值時覆蓋此行為,請嘗試使用 IFNULL 運算符稍微修改此觸發器:

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());

這提供了兩全其美的好處:您可以為日期列提供一個值,它將需要,否則它將默認為當前時間。 相對於表定義中的 DEFAULT GETDATE() 等干凈的東西,它仍然是貧民窟,但我們越來越近了!

我能夠在有兩個日期時間字段的表上使用這個 alter 語句來解決這個問題。

ALTER TABLE `test_table`
  CHANGE COLUMN `created_dt` `created_dt` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  CHANGE COLUMN `updated_dt` `updated_dt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

這就像您期望 now() 函數工作一樣工作。 插入空值或忽略 created_dt 和 updated_dt 字段會在兩個字段中產生完美的時間戳值。 對該行的任何更新都會更改 updated_dt。 如果您通過 MySQL 查詢瀏覽器插入記錄,您還需要一個步驟,即使用新時間戳處理 created_dt 的觸發器。

CREATE TRIGGER trig_test_table_insert BEFORE INSERT ON `test_table`
    FOR EACH ROW SET NEW.created_dt = NOW();

觸發器可以是任何你想要的我就像命名約定 [trig]_[my_table_name]_[insert]

您可以使用觸發器來執行此類操作。

CREATE TABLE `MyTable` (
`MyTable_ID`  int UNSIGNED NOT NULL AUTO_INCREMENT ,
`MyData`  varchar(10) NOT NULL ,
`CreationDate`  datetime NULL ,
`UpdateDate`  datetime NULL ,
PRIMARY KEY (`MyTable_ID`)
)
;

CREATE TRIGGER `MyTable_INSERT` BEFORE INSERT ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the creation date
    SET new.CreationDate = now();

        -- Set the udpate date
    Set new.UpdateDate = now();
END;

CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END;

對於所有試圖在MySQL 中設置默認DATETIME值而失去信心的人,我確切地知道您的感受/感受。 所以這里是:

ALTER TABLE  `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0

仔細觀察我沒有0周圍添加單引號/雙引號

解決這個問題后,我真的要跳起來了:D

如果您已經創建了表,那么您可以使用

將默認值更改為當前日期時間

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

將默認值更改為“2015-05-11 13:01:01”

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT '2015-05-11 13:01:01';

MySQL 5.6 已經修復了這個問題

ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'

這確實是個可怕的消息。 這是一個長期未決的錯誤/功能請求 該討論還討論了時間戳數據類型的限制。

我很想知道實現這件事有什么問題。

我正在運行 MySql Server 5.7.11 和這句話:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

工作。 但以下內容:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

只是工作

作為旁注,它在mysql 文檔中提到:

DATE 類型用於具有日期部分但沒有時間部分的值。 MySQL 以 'YYYY-MM-DD' 格式檢索和顯示 DATE 值。 支持的范圍是“1000-01-01”到“9999-12-31”。

即使他們也說:

無效的 DATE、DATETIME 或 TIMESTAMP 值被轉換為適當類型的“零”值('0000-00-00' 或 '0000-00-00 00:00:00')。

您可以使用 now() 來設置日期時間列的值,但請記住,您不能將其用作默認值。

對於所有使用 TIMESTAMP 列作為解決方案的人,我想從手冊中補充以下限制:

http://dev.mysql.com/doc/refman/5.0/en/datetime.html

“TIMESTAMP 數據類型的范圍是 '1970-01-01 00:00:01 ' UTC 到 ' 2038-01-19 03:14:07 ' UTC。它具有不同的屬性,具體取決於 MySQL 版本和 SQL服務器運行的模式。這些屬性將在本節后面描述。”

因此,這顯然會在大約 28 年內破壞您的軟件。

我相信數據庫方面的唯一解決方案是使用其他答案中提到的觸發器。

在定義多行觸發器時,必須更改分隔符,因為 MySQL 編譯器會將分號作為觸發器的結尾並生成錯誤。 例如

DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END//
DELIMITER ;

雖然您不能在默認定義中使用DATETIME執行此操作,但您可以簡單地在插入語句中加入一個 select 語句,如下所示:

INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))

請注意桌子周圍缺少引號。

對於 MySQL 5.5

如果您嘗試將默認值設置為 NOW(),我認為 MySQL 不支持。 在 MySQL 中,您不能使用函數或表達式作為任何類型列的默認值,但 TIMESTAMP 數據類型列除外,您可以將 CURRENT_TIMESTAMP 指定為默認值。

以下是如何在 MySQL 5.1 上執行此操作:

ALTER TABLE `table_name` CHANGE `column_name` `column_name` 
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

我不知道為什么你必須輸入兩次列名。

我認為在 mysql 中很簡單,因為 mysql 內置函數調用 now() 給出當前時間(插入的時間)。

所以你的查詢應該類似

CREATE TABLE defaultforTime(
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME default now()
);

謝謝你。

與 MySQL 8.x 配合良好

CREATE TABLE `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `dateCreated` datetime DEFAULT CURRENT_TIMESTAMP,
      `dateUpdated` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      UNIQUE KEY `mobile_UNIQUE` (`mobile`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `testtable` (
    `id` INT(10) NULL DEFAULT NULL,
    `colname` DATETIME NULL DEFAULT '1999-12-12 12:12:12'
)

在上面創建'testtable'的查詢中,我使用'1999-12-12 12:12:12'作為DATETIME列colname默認值

使用以下代碼

DELIMITER $$

    CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
    BEGIN
      SET new.datefield = NOW();
    END $$

    DELIMITER ;

如果您設置ON UPDATE CURRENT_TIMESTAMP ,則表中的行數據更新將占用當前時間。

 CREATE TABLE bar(
        `create_time` TIMESTAMP CURRENT_TIMESTAMP,
        `update_time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    )

如果您嘗試將默認值設置為 NOW(),MySQL 支持您必須更改該列的類型 TIMESTAMP 而不是 DATETIME。 TIMESTAMP 將當前日期和時間作為默認值..我認為它會解決您的問題..

舉個例子,如果我有一個名為“site”的表,其中一個 created_at 和一個 update_at 列都是 DATETIME 並且需要現在的默認值,我可以執行以下 sql 來實現這一點。

ALTER TABLE `site` CHANGE `created_at` `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE `created_at` `created_at` DATETIME  NULL DEFAULT NULL;

ALTER TABLE `site` CHANGE `updated_at` `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE `updated_at` `updated_at` DATETIME NULL DEFAULT  NULL;

語句的順序很重要,因為一個表不能有兩列類型為 TIMESTAMP 且默認值為 CUREENT TIMESTAMP 的列

這是我的觸發器示例:

 /************ ROLE ************/ drop table if exists `role`; create table `role` ( `id_role` bigint(20) unsigned not null auto_increment, `date_created` datetime, `date_deleted` datetime, `name` varchar(35) not null, `description` text, primary key (`id_role`) ) comment=''; drop trigger if exists `role_date_created`; create trigger `role_date_created` before insert on `role` for each row set new.`date_created` = now();

您可以解析默認時間戳。 首先考慮您使用的是哪種字符集,例如,如果您使用 utf8 此字符集支持所有語言,如果您使用 laten1 此字符集僅支持英語。 接下來設置如果您在任何項目下工作,您應該知道客戶時區並選擇您是客戶時區。 這一步是強制性的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM