如何为MySQL Datetime列设置默认值?
在SQL Server中为getdate()
。MySQL的等效项是什么?如果这是一个因素,我正在使用MySQL5.x。
如何为MySQL Datetime列设置默认值?
在SQL Server中为getdate()
。MySQL的等效项是什么?如果这是一个因素,我正在使用MySQL5.x。
Answers:
重要编辑: 自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 **
DATE
列设置默认值?(不是datetime
专栏)。
在版本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
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
MySQL(版本5.6.5之前的版本)不允许将函数用于默认的DateTime值。TIMESTAMP由于其奇怪的行为而不合适,因此不建议用作输入数据。(请参见MySQL数据类型默认值。)
也就是说,您可以通过创建一个Trigger来实现。
我有一个带有DateTime类型的DateCreated字段的表。我在“插入之前”和“ SET NEW.DateCreated=NOW()
” 该表上创建了一个触发器,它很好用。
希望对您有所帮助。
IF NEW.created_at IS NOT NULL
对我而言,触发方法效果最好,但我发现该方法存在障碍。考虑以下基本触发器,以便在插入时将日期字段设置为当前时间:
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());
这提供了两全其美的方法:您可以为date列提供一个值,它将使用,否则将默认为当前时间。相对于表定义中的DEFAULT GETDATE()这样的干净内容,它仍然是贫民窟,但我们之间的距离越来越近了!
NULL
。没有警告了。
dateAdded
将显示所有“ 0000-00-00 00:00:00”。使用这个方法可以达到目的:`如果NEW.dateAdded = 0,则逐行,然后设置NEW.dateAdded = NOW();。END IF;`
我可以使用表上有两个datetime字段的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 zones MODIFY created datetime NOT NULL DEFAULT 0;
ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
如果您已经创建了表格,则可以使用
将默认值更改为当前日期时间
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';
这确实是一个可怕的消息。这是对此的长期未决bug /功能请求。该讨论还讨论了时间戳数据类型的局限性。
我很想知道实现此问题有什么问题。
我正在运行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()设置日期时间列的值,但请记住,您不能将其用作默认值。
NOW()
以后再用于插入。对于5.6版,只需将其设置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 '。它具有不同的属性,具体取决于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 ;
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 ;
如果试图将默认值设置为NOW(),MySQL支持您必须更改该列的类型TIMESTAMP而不是DATETIME。TIMESTAMP具有当前日期和时间作为默认值。.我认为它将解决您的问题。
例如,如果我有一个名为“ site”的表,且表的created_at和update_at列均为DATETIME,并且需要现在的默认值,则可以执行以下sql来实现此目的。
ALTER TABLE`site` CHANGE`created_at``created_at` TIMESTAMP不为空默认值CURRENT_TIMESTAMP; ALTER TABLE`site` CHANGE`created_at``created_at` DATETIME NULL默认为NULL; ALTER TABLE`site` CHANGE`updated_at``updated_at` TIMESTAMP不为空默认值CURRENT_TIMESTAMP; ALTER TABLE`site`更改`updated_at``updated_at` DATETIME NULL默认为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();
与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;
您可以解析默认时间戳。首先考虑一下您正在使用哪个字符集,例如,如果您采用utf8,则该字符集支持所有语言;如果您采用了Laten1,则此字符集仅支持英语。下一个setp(如果您正在任何项目下工作),您应该知道客户端时区并选择您为客户端时区。此步骤是必需的。