如何为MySQL Datetime列设置默认值?

时间:2008-10-03 20:24:31

标签: mysql datetime

如何为MySQL Datetime列设置默认值?

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

26 个答案:

答案 0 :(得分:796)

重要编辑: 现在可以使用DATETIME字段实现这一点,因为 MySQL 5.6.5 ,请看下面的other post ...

以前的版本无法使用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>

** CAVEAT:如果您默认定义CURRENT_TIMESTAMP为ON的列,则需要始终为此列指定值,否则该值将在更新时自动重置为“now()”。这意味着如果您不希望更改该值,则您的UPDATE语句必须包含“[您的列名] = [您的列名]”(或其他一些值),否则该值将变为“now()”。很奇怪,但也是如此。我希望这有帮助。我使用5.5.56-MariaDB **

答案 1 :(得分:541)

在5.6.5版本中,可以在datetime列上设置默认值,甚至可以创建一个在更新行时更新的列。类型定义:

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

答案 2 :(得分:140)

MySQL(before version 5.6.5)不允许将函数用于默认的DateTime值。 TIMESTAMP由于其奇怪的行为而不适用,因此不建议用作输入数据。 (见MySQL Data Type Defaults。)

那就是说,你可以完成这个by creating a Trigger

我有一个DateTime类型的DateCreated字段的表。我在该表“插入前”和“SET NEW.DateCreated=NOW()”上创建了一个触发器,它运行良好。

我希望这有助于某人。

答案 3 :(得分:129)

对我而言,触发方法效果最好,但我发现了这种方法的障碍。考虑在插入时将日期字段设置为当前时间的基本触发器:

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()这样干净的东西,它仍然是贫民窟,但我们越来越近了!

答案 4 :(得分:26)

我能够在我的桌子上使用这个包含两个日期时间字段的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]

答案 5 :(得分:22)

您可以使用触发器来执行此类操作。

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;

答案 6 :(得分:16)

对于那些在 MySQL 中设置默认 DATETIME 价值的人而言,我确切地知道您的感受/感受。所以这是:

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

仔细观察我没有在 0 附近添加单引号/双引号

在解决这个问题之后我真的跳了起来:D

答案 7 :(得分:13)

MySQL 5.6 has fixed this problem

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

答案 8 :(得分:12)

这确实是一个可怕的消息。here is a long pending bug/feature request for this。该讨论还讨论了时间戳数据类型的限制。

我真的很想知道实现这个问题是什么问题。

答案 9 :(得分:9)

如果您已经创建了表格,那么可以使用

将默认值更改为当前日期时间

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';

答案 10 :(得分:7)

在定义多行触发器时,必须更改分隔符,因为MySQL编译器将使用分号作为触发结束并生成错误。 e.g。

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

答案 11 :(得分:7)

对于所有使用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年后破坏你的软件。

我认为数据库方面的唯一解决方案是使用其他答案中提到的触发器。

答案 12 :(得分:6)

您可以使用now()来设置日期时间列的值,但请记住,您不能将其用作默认值。

答案 13 :(得分:6)

我正在运行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 docs中提及:

  

DATE类型用于具有日期部分但没有时间部分的值。 MySQL在&#39; YYYY-MM-DD&#39;中检索并显示DATE值。格式。支持的范围是&#39; 1000-01-01&#39;到&#39; 9999-12-31&#39;。

即使他们也说:

  

无效的DATE,DATETIME或TIMESTAMP值将转换为相应类型的“零”值(&#39; 0000-00-00&#39;或者00:00:00: 00&#39;。)

答案 14 :(得分:5)

虽然您无法在默认定义中使用DATETIME执行此操作,但您可以在insert语句中简单地包含select语句,如下所示:

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

请注意表格周围缺少引号。

对于MySQL 5.5

答案 15 :(得分:4)

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

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

我不知道你为什么要输入两次列名。

答案 16 :(得分:3)

如果您尝试将默认值设置为NOW(),我认为MySQL不支持。在MySQL中,除了TIMESTAMP数据类型列之外,您不能将函数或表达式用作任何类型列的默认值,您可以将CURRENT_TIMESTAMP指定为默认值。

答案 17 :(得分:2)

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

答案 18 :(得分:2)

使用以下代码

DELIMITER $$

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

    DELIMITER ;

答案 19 :(得分:2)

我认为在mysql中这很简单,因为mysql的内置函数now()给出了当前时间(该插入时间)。

因此您的查询应类似于

import { Component } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',
  template: `
  <ul>
    <li *ngFor="let item of items | async">
       {{ item | json }}
    </li>
  </ul>
  `,
})
export class AppComponent {
  items: Observable<any[]>;
  constructor(db: AngularFireDatabase) {
    this.items = db.list('items').valueChanges();
  }
}

谢谢。

答案 20 :(得分:1)

与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;

答案 21 :(得分:0)

以示例为例如果我有一个名为'site'的表,其中created_at和update_at列都是DATETIME并且需要默认值now,我可以执行以下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

答案 22 :(得分:0)

这是我的触发示例:

&#13;
&#13;
/************ 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();
&#13;
&#13;
&#13;

答案 23 :(得分:0)

如果您尝试将默认值设置为NOW(),MySQL支持您必须更改该列TIMESTAMP而不是DATETIME的类型。 TIMESTAMP默认使用当前日期和时间。我认为它将解决您的问题..

答案 24 :(得分:0)

如果设置ON UPDATE CURRENT_TIMESTAMP,则表中行数据更新将花费当前时间。

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

答案 25 :(得分:-3)

您可以解析默认时间戳。首先考虑你正在使用哪个字符集,例如,如果你采用utf8这个字符集支持所有语言,如果你采用laten1这个字符集只支持英语。如果你在任何项目下工作,你应该知道客户时区并选择你是客户区。这一步是强制性的。