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

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

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

1548067 次浏览

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

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

重要编辑: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_TIMESTAMPON,您需要始终为该列指定一个值,否则该值将在更新时自动重置为“now()”。这意味着如果您不想更改该值,您的UPDATE语句必须包含“[您的列名]=[您的列名]”(或其他一些值),否则该值将变为“now()”。很奇怪,但确实如此。我使用的是5.5.56-MariaDB

这确实是一个可怕的消息。这是一个长期悬而未决的bug /feature请求。该讨论还讨论了时间戳数据类型的限制。

我真的很想知道实施这个东西有什么问题。

MySQL(版本5.6.5之前)不允许函数用于默认的DateTime值。TIMESTAMP由于其奇怪的行为而不适合,并且不推荐用作输入数据。(参见MySQL数据类型默认值。)

也就是说,你可以做到这一点通过创建一个触发器

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

我希望这对某人有所帮助。

我能够解决这个问题,使用我的表上有两个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()函数的工作方式相同。插入空值或忽略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]_[插入]

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

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

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

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

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 dateSET new.CreationDate = now();
-- Set the udpate dateSet new.UpdateDate = now();END;
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`FOR EACH ROW BEGIN-- Set the udpate dateSet new.UpdateDate = now();END;

在定义多行触发器时,必须更改分隔符,因为分号将被MySQL编译器作为触发器的结束并产生错误。例如

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

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

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语句--yuck!要在提供值时覆盖此行为,请使用IFNULL运算符尝试这个稍微修改的触发器:

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

这是两全其美的:你可以为你的日期列提供一个值,它将接受,否则它将默认为当前时间。相对于表定义中的DEFAULT GETDATE()等干净的东西,它仍然是贫民窟,但我们越来越接近了!

对于那些试图在mysql中设置默认数据值而失去信心的人,我确切地知道你的感受/感受。所以这里是:

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

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

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

虽然您不能在默认定义中使用DATETIME执行此操作,但您可以简单地将选择语句合并到插入语句中,如下所示:

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

注意桌子周围没有引号。

对于MySQL 5.5

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

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

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

在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

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

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的默认值

MySQL 5.6已经修复了这个问题

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

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

这是我的触发器示例:

/************ 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 inserton `role`for each rowset new.`date_created` = now();

我正在运行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')。

使用以下代码

DELIMITER $$
CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROWBEGINSET new.datefield = NOW();END $$
DELIMITER ;

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

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

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中很简单,因为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;

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

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