2013-10-30 74 views
3

我目前正在将具有VARCHAR列中的日期的表迁移到具有DATE列的新表中。我设法清理旧表格中的字符串值为“YYYY-MM-DD”,但是当我尝试执行插入操作时,出现了错误,日期为“2006-04-31”,只有30天(它是注册时的错字),MySQL STR_TO_DATE NULL在错误

我的问题是:如何在日期无效时将列设置为NULL而不会出现错误?我的SQL如下:

INSERT INTO newFancyTable (created_at) 
SELECT str_to_date(created, '%Y-%m-%d') FROM oldCrappyTable; 

和错误是:

Error Code: 1292. Incorrect date value: '2006-04-31' for column 'created_at' at row 1 

感谢

UPDATE

我用下面的方法也试过:

INSERT INTO newFancyTable (created_at) 
SELECT CAST(created AS DATE) FROM oldCrappyTable; 

有了同样的错误,并试图更新oldCrappyTable将返回相同的:

UPDATE oldCrappyTable SET created = CAST(created AS DATE); 

都返回:

Error Code: 1292. Incorrect datetime value: '2006-04-31' 

更新2

最后,我用多CASE s来隔离无效日期,总之它们只有5个, 尽管如此,这个问题可以通过下面的方法来复制:

CREATE TABLE dates_temp (
    test_date DATE DEFAULT NULL 
) ENGINE=MEMORY; 

INSERT INTO dates_temp 
SELECT STR_TO_DATE("2006-04-31", '%Y-%m-%d'); 

DROP TABLE dates_temp; 
+0

你为什么不为它写一个'CASE'或者只是将它过滤出来? – Kermit

+0

该表格有5000多行,我无法确定有多少日期无效..我知道“2006-04-31”是第一个,但不知道有多少人在那里.. –

+0

是你的专栏定义为非空?当传递给它的字符串表示非法日期时,'STR_TO_DATE()'默认会产生一个值为NULL的值。 –

回答

3

可能的解决方法是关闭整个服务器,特定会话或几条语句的严格模式。例如:

set @old_sql_mode = @@sql_mode; 
set sql_mode = ''; 
-- Run some statements which may result in error 
set sql_mode = @old_sql_mode; 

附加信息

MySQL Documentation

+1

解决方案的好主意,但这样做时感觉非常难看.. –

+0

嗯,这取决于,当我不得不这样做时,我只是想把所有的数据都放到数据库中。之后我会对数据进行必要的清理。 –

0

除了@EduardoDennis回答使用NULLIF过滤掉零个日期:

INSERT INTO newFancyTable (created_at) 
SELECT nullif(str_to_date(created, '%Y-%m-%d'), from_days(0)) FROM oldCrappyTable; 

看到我的完整的答案here