代码之家  ›  专栏  ›  技术社区  ›  Brian Boatright

如何设置mysql datetime列的默认值?

  •  799
  • Brian Boatright  · 技术社区  · 17 年前

    如何设置mysql datetime列的默认值?

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

    24 回复  |  直到 7 年前
        1
  •  781
  •   Community Mohan Dere    8 年前

    重要编辑: 现在可以用datetime字段实现这一点,因为 MySQL 5.6 ,看看 other post 在下面…

    以前的版本不能用datetime来实现这一点…

    但您可以使用时间戳:

    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>
    

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

        2
  •  525
  •   Gustav Bertram    13 年前

    在版本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

        3
  •  139
  •   Bradley Slavik    12 年前

    MySQL before version 5.6.5 )不允许将函数用于默认的日期时间值。时间戳因其行为古怪而不适用,不建议用作输入数据。(见 MySQL Data Type Defaults )

    也就是说,你可以做到这一点 by creating a Trigger .

    我有一个表,其中的日期创建字段类型为datetime。我在“插入前”和“插入前”表上创建了一个触发器 SET NEW.DateCreated=NOW() “而且效果很好。

    我希望这对某人有帮助。

        4
  •  129
  •   John Larson    15 年前

    对我来说,触发方法是最有效的,但我发现了一个障碍。考虑使用基本触发器将日期字段设置为插入时的当前时间:

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

    发生的情况是,触发器会立即覆盖为字段提供的值,因此设置非当前时间的唯一方法是使用后续更新语句--yuck!若要在提供值时重写此行为,请使用ifnull运算符尝试此稍微修改的触发器:

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

    这两个方面都是最好的:您可以为日期列提供一个值,它需要,否则它将默认为当前时间。它仍然是相对于表定义中的默认getDate()之类的干净东西的贫民区,但是我们越来越接近了!

        5
  •  23
  •   community wiki 2 revs, 2 users 74% user188217    16 年前

    我可以使用表中的这个alter语句来解决这个问题,该语句有两个datetime字段。

    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()函数正常工作一样。插入空值或忽略创建的和更新的字段会在两个字段中产生一个完美的时间戳值。行的任何更新都会更改更新后的日期。如果您通过MySQL查询浏览器插入记录,则还需要一个步骤,即用新的时间戳处理创建的日期的触发器。

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

    触发器可以是你想要的任何东西,我只是喜欢命名约定[trig]uuuu table_u name]uuu[insert]

        6
  •  22
  •   Josh Lee ZZ Coder    15 年前

    你可以用触发器来做这类事情。

    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;
    
        7
  •  16
  •   Augiwan Sarju Palukashi    10 年前

    为所有那些失去信心的人设置一个默认值 日期时间 价值在 MySQL 我很清楚你的感受。所以这里是:

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

    仔细观察 我没有添加单引号/双引号 周围

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

        8
  •  13
  •   Hauleth    13 年前

    MySQL 5.6 has fixed this problem .

    ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
    
        9
  •  12
  •   Kinjal Dixit    17 年前

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

    我真的很想知道实现这一点有什么问题。

        10
  •  8
  •   Saveendra Ekanayake    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';
    
        11
  •  7
  •   Fabian    15 年前

    对于所有使用timestamp列作为解决方案的用户,我希望在手册中遵循以下限制:

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

    “时间戳数据类型的范围是‘1970-01-01 00:00:01’UTC到’ 2038年1月19日03:14:07 UTC。它有不同的属性,这取决于MySQL版本和服务器运行的SQL模式。这些属性将在本节后面介绍。“

    所以这显然会在28年内破坏你的软件。

    我相信数据库方面唯一的解决方案是使用类似于其他答案中提到的触发器。

        12
  •  7
  •   Drawin Kumar    15 年前

    定义多行触发器时,必须将分隔符更改为分号,MySQL编译器将使用分号作为触发器的结尾并生成错误。 例如

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

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

        14
  •  6
  •   Evhz    9 年前

    我运行的是MySQLServer5.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 :

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

    即使他们也说:

    无效的日期、日期时间或时间戳值将转换为相应类型的“0”值(“0000-00-00”或“0000-00-00 00 00:00:00”)。

        15
  •  5
  •   Udo Held    14 年前

    但你不能这么做 DATETIME 在默认定义中,您可以简单地将select语句合并到insert语句中,如下所示:

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

    注意表中没有引号。

    对于MySQL 5.5

        16
  •  4
  •   Udo Held    14 年前

    下面是如何在MySQL5.1上执行此操作:

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

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

        17
  •  3
  •   Vijesh VP    17 年前

    如果您试图将默认值设置为now(),我认为MySQL不支持该设置。在MySQL中,除了timestamp数据类型列之外,不能将函数或表达式用作任何类型的列的默认值,您可以将当前的时间戳指定为默认值。

        18
  •  2
  •   Fathah Rehman P    13 年前
    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

        19
  •  2
  •   Rana Aalamgeer    9 年前

    使用以下代码

    DELIMITER $$
    
        CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
        BEGIN
          SET new.datefield = NOW();
        END $$
    
        DELIMITER ;
    
        20
  •  2
  •   Deepak N    7 年前

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

    所以您的查询应该类似

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

    谢谢您。

        21
  •  0
  •   Dhrumil Shah    13 年前

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

        22
  •  0
  •   Joseph Persico    12 年前

    例如,如果我有一个名为“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

        23
  •  0
  •   Lucas Moyano Angelini    11 年前

    这是我的触发器示例:

    /************ 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();
        24
  •  -2
  •   David Sykes    15 年前

    您可以解析默认时间戳。首先考虑您正在使用的字符集,例如,如果采用utf8,则此字符集支持所有语言;如果采用laten1,则此字符集仅支持英语。下一个SETP如果您在任何项目下工作,您应该知道客户机时区并选择您是客户机区域。此步骤是必需的。