Remove all null dates from MySQL database in all tables

I have many tables in MySQL that contain a zero date in the dateTime column 0000-00-00 00:00:00

Using any administrator settings. Is it possible to disable zero dates and replace all zero with a static say value 1-1-1900?

EDIT:

I am working on a database migration that involves moving over 100 MySQL tables to SQL Server.

Can I avoid manually executing scripts in each table by setting the database mode?

+4
source share
9 answers

To change the values ​​of creatures, you can use the following query:

UPDATE tablename SET date_column = '1900-01-01' WHERE date_column = '0000-00-00';

If you want to automate the UPDATE query, you can use a prepared statement:

SET @sql_update=CONCAT_WS(' ', 'UPDATE', CONCAT(_schema, '.', _table),
                               'SET', _column, '=', '\'1900-01-01\'',
                               'WHERE', _column, '=', '\'0000-00-00\'');

PREPARE stmt FROM @sql_update;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

, :

SELECT
  table_schema,
  table_name,
  column_name
FROM
  information_schema.columns
WHERE
  table_schema=DATABASE() AND data_type LIKE 'date%'

, :

DELIMITER //
CREATE PROCEDURE update_all_tables() BEGIN
  DECLARE done BOOLEAN DEFAULT FALSE;
  DECLARE _schema VARCHAR(255);
  DECLARE _table VARCHAR(255);
  DECLARE _column VARCHAR(255);
  DECLARE cur CURSOR FOR SELECT
                           CONCAT('`', REPLACE(table_schema, '`', '``'), '`'),
                           CONCAT('`', REPLACE(table_name, '`', '``'), '`'),
                           CONCAT('`', REPLACE(column_name, '`', '``'), '`')
                         FROM
                           information_schema.columns
                         WHERE
                           table_schema=DATABASE() AND data_type LIKE 'date%';

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;

  OPEN cur;

  columnsLoop: LOOP
    FETCH cur INTO _schema, _table, _column;
    IF done THEN
      LEAVE columnsLoop;
    END IF;   

    SET @sql_update=CONCAT_WS(' ', 'UPDATE', CONCAT(_schema, '.', _table),
                                   'SET', _column, '=', '\'1900-01-01\'',
                                   'WHERE', _column, '=', '\'0000-00-00\'');

    PREPARE stmt FROM @sql_update;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

  END LOOP columnsLoop;

  CLOSE cur;
END//
DELIMITER ;

. .

+5

,

update your_table
set date_column = '1900-01-01'
where date_column = '0000-00-00'

specfic null,

ALTER TABLE your_table 
CHANGE date_column date_column date NOT NULL DEFAULT '1900-01-01'
+1

.

1. ( ):

  • INFORMATION_SCHEMA, , COLUMNS , , , ..

-

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS 
WHERE COLUMN_NAME='date' AND TABLE_SCHEMA='<YOUR DB NAME>'

, ,

SELECT TABLE_NAME,COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 
WHERE COLUMN_NAME in ('timestamp','date','datetime')
AND TABLE_SCHEMA='<YOUR DB NAME>'
  • , . . MySQL, , AKA:

-

@string = CONCAT("UPDATE ", @table_name, " SET ", @column_name, "='1-1-1900' WHERE ", @column_name, "=0000-00-00 00:00:00");

PREPARE stmt FROM @string; EXECUTE stmt;

.

. , , . mysqldump . Vim 0000-00-00 00:00:00 1-1-1900. , , , . !

+1

update , , 0, .

0

ALTER TABLE `test_table`
  CHANGE COLUMN `created_dt` `created_dt` date NOT NULL DEFAULT '1900-01-01';

juergen d said

update test_table
set created_dt= '1900-01-01'
where created_dt= '0000-00-00'
0

: ETL DataWareHousing, , , Open Source, Kettle/Pentaho.

, , SQL-. perl, php java :

#!/usr/bin/perl

use strict;
use warnings;
use DBI;

my $user='geheim';
my $pass='secret';

my $dbh = DBI->connect( "dbi:mysql:host=localhost:database=to_convert:port=3306", $user, $pass ) or die $DBI::errstr;

# Prints out all the statements needed, might be checked before executed
my @tables = @{ $dbh->selectall_arrayref("show tables") };
  foreach my $tableh ( @tables){
    my $tabname = $tableh->[0];
    my $sth=$dbh->prepare("explain $tabname");
    $sth->execute();
    while (my $colinfo = $sth->fetchrow_hashref){
      if ($colinfo->{'Type'} =~ /date/i && $colinfo->{'Null'} =~ /yes/i){
        print ("update \`$tabname\` set \`" . $colinfo->{'Field'} . "\` = '1990-01-01' where \`" . $colinfo->{'Field'} . "\` IS NULL; \n");
        print ("alter table \`$tabname\` change column \`" . $colinfo->{'Field'} . "\`  \`" . $colinfo->{'Field'} . "\` " . $colinfo->{'Type'} . " not null default '1990-01-01'; \n");
      }
    }
  }

, :

localmysql [localhost]> explain dt;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| a     | date | YES  |     | NULL    |       |
+-------+------+------+-----+---------+-------+
1 row in set (0.00 sec)

localmysql [localhost]> explain tst
    -> ;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | YES  |     | NULL    |       |
| atime | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

:

update `dt` set `a` = '1990-01-01' where `a` IS NULL; 
alter table `dt` change column `a`  `a` date not null default '1990-01-01'; 
update `tst` set `atime` = '1990-01-01' where `atime` IS NULL; 
alter table `tst` change column `atime`  `atime` datetime not null default '1990-01-01'; 

.

, !

0

, , , . MySQL postgress, .

:

CREATE VIEW migration_mytable AS 
SELECT field1, field2, 
    CASE field3
         WHEN '0000-00-00 00:00:00' 
         THEN '1900-01-01 00:00:00' 
         ELSE field3
    END CASE AS field3
FROM mytable;

script, , , .

SqlServer ( , this) ;

INSERT INTO sqlserver.mytable SELECT * FROM mysql.migration_mytable;
0

-, :

select
concat('UPDATE ',TABLE_NAME,' SET ',COLUMN_NAME,'=NULL WHERE ',COLUMN_NAME,'=0;')
from information_schema.COLUMNS 
where TABLE_SCHEMA = 'DATABASE_NAME' and DATA_TYPE in ('datetime', 'date', 'time');

DATABASE_NAME .

0
source

This is an old question, but ran into a similar problem, except that I was trying to set 0000-00-00 to NULL.

tried to request this

UPDATE tablename SET date_column = NULL WHERE date_column = '0000-00-00';

and got the following error:

Invalid date value: '0000-00-00' for column 'date_column' in row 1

Turns off the next request without '' about 0000-00-00!

 UPDATE tablename SET date_column = NULL WHERE date_column = 0000-00-00;
0
source

Source: https://habr.com/ru/post/1538708/


All Articles