[英]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';
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.