CREATE TABLE seckill (
`seckill_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '商品库存id',
`name` VARCHAR(120) NOT NULL COMMENT '商品名称',
`number` INT NOT NULL COMMENT '库存数量',
`start_time` TIMESTAMP NOT NULL COMMENT '开始时间',
`end_time` TIMESTAMP NOT NULL COMMENT '结束时间',
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (seckill_id),
KEY idx_start_time(start_time),
KEY idx_end_time(end_time),
KEY idx_create_time(create_time)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒杀库存表';
When I try to create the table with the previous query, this is the error I get:
ERROR 1067 (42000): Invalid default value for 'end_time'
How can I solve this issue?
MySQL treats timestamp in a special way, that is a little hard to find in the documentation when you don't know what you are looking for:
In MySQL, the TIMESTAMP data type differs in nonstandard ways from other data types:
TIMESTAMP columns not explicitly declared with the NULL attribute are assigned the NOT NULL attribute. (Columns of other data types, if not explicitly declared as NOT NULL, permit NULL values.) Setting such a column to NULL sets it to the current timestamp.
The first TIMESTAMP column in a table, if not declared with the NULL attribute or an explicit DEFAULT or ON UPDATE clause, is automatically assigned the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes.
TIMESTAMP columns following the first one, if not declared with the NULL attribute or an explicit DEFAULT clause, are automatically assigned DEFAULT '0000-00-00 00:00:00' (the “zero” timestamp). For inserted rows that specify no explicit value for such a column, the column is assigned '0000-00-00 00:00:00' and no warning occurs.
Those nonstandard behaviors remain the default for TIMESTAMP but as of MySQL 5.6.6 are deprecated and this warning appears at startup:
[Warning] TIMESTAMP with implicit DEFAULT value is deprecated.
Please use --explicit_defaults_for_timestamp server option
(see documentation for more details).
That means your second timestamp not null column will get an implicit default value of '0000-00-00 00:00:00', which is not allowed in combination with the NO ZERO DATE and strict sql mode (which is by default enabled in MySQL 5.7) and results in your error.
To solve your problem, enable the option --explicit_defaults_for_timestamp. It treats the timestamp columns as you expected (and will be the default behaviour in some future MySQL release anyway), or allow them to be null.
To solve your problem:
set ##session.explicit_defaults_for_timestamp=on;
Related
In fact there are so many similar questions, I could not solve this problem.
I am using codeigniter framework. When I call insert method of ActiveRecord by passing a php object, it send all properties either by its value or as null. It causes cannot be null. error.
Table Structure:
CREATE TABLE `scheduledTasks` (
`id` int(11) NOT NULL,
`type` varchar(255) COLLATE utf8_bin NOT NULL,
`createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`executionTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ownerUserId` int(11) DEFAULT NULL,
`subjectUserId` text COLLATE utf8_bin,
`detail` text COLLATE utf8_bin,
`isExecuted` int(1) DEFAULT '0'
);
ALTER TABLE `scheduledTasks`
ADD PRIMARY KEY (`id`);
ALTER TABLE `scheduledTasks`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
Query I tried:
INSERT INTO `scheduledTasks` (`id`, `type`, `createTime`, `executionTime`, `ownerUserId`, `detail`, `isExecuted`)
VALUES (NULL, 'QuoteRequest', NULL, NULL, '926', NULL, NULL)
Mysql Version:
+-------------------------+
| VERSION() |
+-------------------------+
| 5.7.17-0ubuntu0.16.04.1 |
+-------------------------+
I have
explicit_defaults_for_timestamp | OFF
and sql mode is
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ##SESSION.sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
Discussion
The MySQL 5.7 manual states that...
In addition, you can initialize or update any TIMESTAMP column to the
current date and time by assigning it a NULL value, unless it has been
defined with the NULL attribute to permit NULL values.
The manual does not say you can do this for DATETIME fields. The best thing to do would be to supply no values in your INSERT query for the createTime and executionTime fields. That should give you the DEFAULT_TIMESTAMP. If that fails, well, I tried.
INSERT INTO `scheduledTasks` (`id`, `type`, `createTime`, `executionTime`, `ownerUserId`, `detail`, `isExecuted`)
VALUES (NULL, 'QuoteRequest', , , '926', NULL, NULL)
Also, keep this in mind about MySQL default values, even though your DATETIME columns do have an explicit DEFAULT clause.
For data entry into a NOT NULL column that has no explicit DEFAULT
clause, if an INSERT or REPLACE statement includes no value for the
column, or an UPDATE statement sets the column to NULL, MySQL handles
the column according to the SQL mode in effect at the time:
If strict SQL mode is enabled, an error occurs for transactional tables and the statement is rolled back. For nontransactional tables,
an error occurs, but if this happens for the second or subsequent row
of a multiple-row statement, the preceding rows will have been
inserted.
If strict mode is not enabled, MySQL sets the column to the implicit default value for the column data type.
Finally, about strict mode in the MySQL Manual:
For STRICT_TRANS_TABLES, MySQL converts an invalid value to the
closest valid value for the column and inserts the adjusted value. If
a value is missing, MySQL inserts the implicit default value for the
column data type. In either case, MySQL generates a warning rather
than an error and continues processing the statement. Implicit
defaults are described in Section 12.7, “Data Type Default Values”.
Conclusion
In summary, if you are in strict mode (which you are, STRICT_TRANS_TABLES) and have DATETIME columns set to NOT NULL DEFAULT CURRENT_TIMESTAMP, and then you supply NULL values during an INSERT, and then subsequently you get a "cannot be NULL" error, ... next time around do not supply values to the DATETIME fields.
If your framework cannot be setup to omit values during INSERT, and changing the SQL mode does not work, then altering the table to use (gasp) TIMESTAMP may be your only option to use NULL in strict mode and have a DEFAULT TIMESTAMP appear.
I have a table with two timestamp fields. They are not nullable. The problem is that whenever I insert null into those fields, the current date is automatically saved, instead of throwing an error saying "Column 'first_data_dt' cannot be null", just like it happens when I insert a value into another non-nullable field.
There are no triggers associated to this table.
Does anybody know why this is happening?
EDIT to add table definition:
CREATE TABLE `ui_mytable` (
`id` int(11) NOT NULL,
`first_data_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`last_data_dt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I understand now why first_data_dt is updated to the current timestamp anytime I insert null. But what about last_data_dt?
That's what a TIMESTAMP column does:
The TIMESTAMP data type offers automatic initialization and updating to the current date and time (that is, the current timestamp). [...] You can initialize or update any TIMESTAMP column to the current date and time by assigning it a NULL value, unless it has been defined with the NULL attribute to permit NULL values.
Source: MySQL documentation
Maybe you want to use a DATETIME instead?
why do i get invalid default value error for the variable "last_updated"?
note i am getting this error while i run the following code in MySQL console in phpmyadmin
CREATE TABLE IF NOT EXISTS `articles` (
`article_id` int(10) NOT NULL AUTO_INCREMENT,
`content_id` int(10) NOT NULL,
`article_body` text NOT NULL,
`last_updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=532 ;
You need to change the last_updated column's data type to timestamp rather than datetime. This will allow the use of CURRENT_TIMESTAMP as a default value.
As it happens, these two data types are represented in the same format YYYY-MM-DD HH:MM:SS. So if/when you use the data, you shouldn't run into any troubles.
Check your MySQL server version, CURRENT_TIMESTAMP is allowed since version 5.6.5 as DEFAULT for DATETIME type, otherwise you should use either TIMESTAMP type or maintain it outside.
Following is my SQL query, it throws an error:-
CREATE TABLE IF NOT EXISTS USER_PROFILE(Id INT PRIMARY KEY AUTO_INCREMENT, date DATETIME NOT NULL DEFAULT NOW) ;
It says Invalid default value for 'date'.
I've tried synonyms for NOW() as well, namely CURRENT_TIMESTAMP, but still the same error.
How can I create a column date with default value current time?
On the documentation page, it says to assign this way
CREATE TABLE t1 (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
dt DATETIME DEFAULT CURRENT_TIMESTAMP
);
From the document
The DEFAULT value clause in a data type specification indicates a
default value for a column. With one exception, the default value must
be a constant; it cannot be a function or an expression. This means,
for example, that you cannot set the default for a date column to be
the value of a function such as NOW() or CURRENT_DATE. The exception
is that you can specify CURRENT_TIMESTAMP as the default for TIMESTAMP
and DATETIME columns
So no function is allowed in the default value hence the first query is failing.
Again from the document
As of MySQL 5.6.5, TIMESTAMP and DATETIME columns can be automatically
initializated and updated to the current date and time (that is, the
current timestamp). Before 5.6.5, this is true only for TIMESTAMP, and
for at most one TIMESTAMP column per table. The following notes first
describe automatic initialization and updating for MySQL 5.6.5 and up,
then the differences for versions preceding 5.6.5.
Before 5.6.5, this is true only for TIMESTAMP
So your mysql version is less than 5.6.5 hence the 2nd query is failing too.
So you need to create the table as
CREATE TABLE IF NOT EXISTS
USER_PROFILE
(
Id INT PRIMARY KEY AUTO_INCREMENT,
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ;
It might be that DATE, as a reserved word, is confusing it by the time it gets to the DEFAULT clause. Try a different name and if that works, try quoting "date".
I have a table that has two TIMESTAMP columns (Creation_Date and Edit_date) that auto fill on INSERT (both columns get CURRENT_TIMESTAMP) and UPDATE (only the Edit_date column is changed)
The action is done by this code:
... CreationDate timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
EditDate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP, ...
I need to change the type from TIMESTAMP to DATE and have tried:
...
`CREATED_DATE` date NOT NULL DEFAULT '0000-00-00',
`EDITED_DATE` date NOT NULL DEFAULT CURRENT_DATE ON UPDATE CURRENT_DATE,
...
How can I get the same behavior. Any responses would be appreciated.
No its not possible unless you are using mysql 5.6.5
The only option was available until 5.6.5 is to use field type as timestamp and then set a default which is not constant.
The DEFAULT value clause in a data type specification indicates a
default value for a column. With one exception, the default value must
be a constant; it cannot be a function or an expression. This means,
for example, that you cannot set the default for a date column to be
the value of a function such as NOW() or CURRENT_DATE. The exception
is that you can specify CURRENT_TIMESTAMP as the default for a
TIMESTAMP
If you are using mysql 5.6.5 then you can set this behaviour for DATETIME datatype
http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html