MySQL Incorrect datetime value: '0000-00-00 00:00:00'

后端 未结 19 959
没有蜡笔的小新
没有蜡笔的小新 2020-11-29 15:51

I\'ve recently taken over an old project that was created 10 years ago. It uses MySQL 5.1.

Among other things, I need to change the default character set from latin1

相关标签:
19条回答
  • 2020-11-29 16:27

    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'

    0 讨论(0)
  • 2020-11-29 16:30

    My suggestion if it is the case that the table is empty or not very very big is to export the create statements as a .sql file, rewrite them as you wish. Also do the same if you have any existing data, i.e. export insert statements (I recommend doing this in a separate file as the create statements). Finally, drop the table and execute first create statement and then inserts.

    You can use for that either mysqldump command, included in your MySQL installation or you can also install MySQL Workbench, which is a free graphical tool that includes also this option in a very customisable way without having to look for specific command options.

    0 讨论(0)
  • 2020-11-29 16:31

    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
    
    0 讨论(0)
  • 2020-11-29 16:32

    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'
    
    0 讨论(0)
  • 2020-11-29 16:32
    SET sql_mode = 'NO_ZERO_DATE';
    UPDATE `news` SET `d_stop`='2038-01-01 00:00:00' WHERE `d_stop`='0000-00-00 00:00:00'
    
    0 讨论(0)
  • 2020-11-29 16:32

    I have this error as well after upgrading MySQL from 5.6 to 5.7

    I figured out that the best solution for me was to combine some of the solutions here and make something of it that worked with the minimum of input.

    I use MyPHPAdmin for the simplicity of sending the queries through the interface because then I can check the structure and all that easily. You might use ssh directly or some other interface. The method should be similar or same anyway.

    ...

    1.

    First check out the actual error when trying to repair the db:

    joomla.jos_menu Note : TIME/TIMESTAMP/DATETIME columns of old format have been upgraded to the new format.

    Warning : Incorrect datetime value: '0000-00-00 00:00:00' for column 'checked_out_time' at row 1

    Error : Invalid default value for 'checked_out_time'

    status : Operation failed

    This tells me the column checked_out_time in the table jos_menu needs to have all bad dates fixed as well as the "default" changed.

    ...

    2.

    I run the SQL query based on the info in the error message:

    UPDATE jos_menu SET checked_out_time = '1970-01-01 08:00:00' WHERE checked_out_time = 0
    

    If you get an error you can use the below query instead that seems to always work:

    UPDATE jos_menu SET checked_out_time = '1970-01-01 08:00:00' WHERE CAST(checked_out_time AS CHAR(20)) = '0000-00-00 00:00:00'
    

    ...

    3.

    Then once that is done I run the second SQL query:

    ALTER TABLE `jos_menu` CHANGE `checked_out_time` `checked_out_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP;
    

    Or in the case it is a date that has to be NULL

    ALTER TABLE `jos_menu` CHANGE `checked_out_time` `checked_out_time` DATETIME NULL DEFAULT NULL;
    

    ...

    If I run repair database now I get:

    joomla.jos_menu OK

    ...

    Works just fine :)

    0 讨论(0)
提交回复
热议问题