To avoid the incorrect datetime value error, you can use the STR_TO_DATE() method. As we know the datetime format is YYYY-MM-DD and if you won't insert in the same format, the error would get generated.
Here is the query to convert from datetime to date in MySQL. mysql> select cast(ArrivalDatetime as Date) as Date from ConvertDateTimeToDate; The following is the output.
I wasn't able to do this:
UPDATE users SET created = NULL WHERE created = '0000-00-00 00:00:00'
(on MySQL 5.7.13).
I kept getting the Incorrect datetime value: '0000-00-00 00:00:00'
error.
Strangely, this worked: SELECT * FROM users WHERE created = '0000-00-00 00:00:00'
. I have no idea why the former fails and the latter works... maybe a MySQL bug?
At any case, this UPDATE query worked:
UPDATE users SET created = NULL WHERE CAST(created AS CHAR(20)) = '0000-00-00 00:00:00'
Changing the default value for a column with an ALTER TABLE
statement, e.g.
ALTER TABLE users MODIFY created datetime NULL DEFAULT '1970-01-02'
... doesn't change any values that are already stored. The "default" value applies to rows that are inserted, and for which a value is not supplied for the column.
As to why you are encountering the error, it's likely that the sql_mode
setting for your session includes NO_ZERO_DATE
.
Reference: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
When you did the "import", the SQL statements that did the INSERT into that table were run in a session that allowed for zero dates.
To see the sql_mode setting:
SHOW VARIABLES LIKE 'sql_mode' ;
-or-
SELECT @@sql_mode ;
As far as how to "fix" the current problem, so that the error won't be thrown when you run the ALTER TABLE
statement.
Several options:
1) change the sql_mode
to allow zero dates, by removing NO_ZERO_DATE
and NO_ZERO_IN_DATE
. The change can be applied in the my.cnf file, so after a restart of MySQL Server, sql_mode
variable will be initialized to the setting in my.cnf.
For a temporary change, we can modify the setting with a single session, without requiring a global change.
-- save current setting of sql_mode
SET @old_sql_mode := @@sql_mode ;
-- derive a new value by removing NO_ZERO_DATE and NO_ZERO_IN_DATE
SET @new_sql_mode := @old_sql_mode ;
SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_DATE,' ,','));
SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_IN_DATE,',','));
SET @@sql_mode := @new_sql_mode ;
-- perform the operation that errors due to "zero dates"
-- when we are done with required operations, we can revert back
-- to the original sql_mode setting, from the value we saved
SET @@sql_mode := @old_sql_mode ;
2) change the created
column to allow NULL values, and update the existing rows to change the zero dates to null values
3) update the existing rows to change the zero dates to a valid date
We don't need to run individual statements to update each row. We can update all of the rows in one fell swoop (assuming it's a reasonably sized table. For a larger table, to avoid humongous rollback/undo generation, we can perform the operation in reasonably sized chunks.)
In the question, the AUTO_INCREMENT
value shown for the table definition assures us that the number of rows is not excessive.
If we've already changed the created
column to allow for NULL
values, we can do something like this:
UPDATE `users` SET `created` = NULL WHERE `created` = '0000-00-00 00:00:00'
Or, we can set those to a valid date, e.g. January 2, 1970
UPDATE `users` SET `created` = '1970-01-02' WHERE `created` = '0000-00-00 00:00:00'
(Note that a datetime value of midnight Jan 1, 1970 ('1970-01-01 00:00:00'
) is a "zero date". That will be evaluated to be '0000-00-00 00:00:00'
I got it fixed by doing this before the query
SET SQL_MODE='ALLOW_INVALID_DATES';
According to MySQL 5.7 Reference Manual:
The default SQL mode in MySQL 5.7 includes these modes: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION.
Since 0000-00-00 00:00:00
is not a valid DATETIME
value, your database is broken. That is why MySQL 5.7 – which comes with NO_ZERO_DATE
mode enabled by default – outputs an error when you try to perform a write operation.
You can fix your table updating all invalid values to any other valid one, like NULL
:
UPDATE users SET created = NULL WHERE created < '0000-01-01 00:00:00'
Also, to avoid this problem, I recomend you always set current time as default value for your created
-like fields, so they get automatically filled on INSERT
. Just do:
ALTER TABLE users
ALTER created SET DEFAULT CURRENT_TIMESTAMP
Instead of
UPDATE your_table SET your_column = new_valid_value where your_column = '0000-00-00 00:00:00';
Use
UPDATE your_table SET your_column = new_valid_value where your_column = 0;
Here what my solution PhpMyAdmin / Fedora 29 / MySQL 8.0 (for example):
set sql_mode='SOMETHING';
doesn't work, command call successful but nothing was change.
set GLOBAL sql_mode='SOMETHING';
change global configuration permanent change.
set SESSION sql_mode='SOMETHING';
change session configuration SESSION variable affects only the current client.
https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html
So I do this :
SHOW VARIABLES LIKE 'sql_mode';
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
NO_ZERO_IN_DATE,NO_ZERO_DATE
set GLOBAL SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
You can remove or add other mode in the same way.
This is helpful to change global for using and testing frameworks or sql_mode must be specified in each file or bunch of queries.
Adapted from a question ask here : how-can-i-disable-mysql-strict-mode
Example : install latest Joomla 4.0-alpha content.
Edit:
In PhpMyadmin, if you have the control of the server, you can change the sql_mode
(and all others parameters) directly in Plus > Variables > sql_mode
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With