I have a table with date values stored as strings, like '2012-01-15'. Some of them are invalid, like '2012-04-31'. I would like to insert the valid dates into a DATE type column in another table, and default the day to 1 if it is too large for the month.
DAYNAME seems to be the only function in MySQL that will check whether a date is valid. However, it issues a warning for an invalid date (in addition to returning NULL), which upgrades to an error in an INSERT or UPDATE statement.
So I'd like to do something like
INSERT INTO date_tbl (date_value)
SELECT IF(DAYNAME(date_string) IS NOT NULL, date_string, CONCAT(LEFT(date_string, 8), '1')
FROM date_string_table;
This fails with Data truncation: Incorrect datetime value: '2010-04-31' even though I am not actually inserting invalid data.
The problem with using INSERT IGNORE is running the risk of actually inserting invalid data, which I would really like to avoid.
EDIT Oct 5:
This problem can be reproduced without creating the intermediate table simply as
CREATE TABLE date_tbl (
date_val DATETIME
);
INSERT INTO date_tbl (date_val)
SELECT IF(DAYNAME('2012-04-31') IS NOT NULL, '2012-04-31', NULL);
I would like the above INSERT to insert NULL for that invalid date, instead of failing.
You can compare days of the proper date and last day for that month with LAST_DAY and STR_TO_DATE.
So your query would be:
INSERT INTO date_tbl (date_val)
SELECT IF(DAY(STR_TO_DATE('2012-02-30','%Y-%m-%d')) > DAY(LAST_DAY(STR_TO_DATE('2012-02-30','%Y-%m-%d'))), NULL,'2012-02-30');
DB Fiddle
A workaround is to use INSERT IGNORE and then validate after the fact:
SELECT date_value
FROM date_tbl
WHERE DAYNAME(date_value) IS NULL;
Should return zero rows.
Related
Why does cast as date work on SELECT, but not when this select is used within an insert?
A column of type varchar contains dates as string, but other strings as well.
I would like to cast the string into a date if it is a date. Else it can be just null.
Sample data:
'2022-10-14' -> date
'1.1.2021' -> date
'01.05.2018' -> date
'as soon as possible' -> null
'start' -> null
NULL -> null
'2015-02-30' -> date
and so on
So there are several data-types. This is why I cannot simply use STR_TO_DATE.
On SELECT simply using cast as date does a great job.
But when using this SELECT as INSERT it seems to be ignored.
I need to fix that somehow. Thanks for any ideas.
You can reproduce the behavior with this SQL:
drop table if exists source_table;
drop table if exists date_table;
create table source_table(
string_date_col varchar(255) null
);
create table date_table(
date_col date null
);
insert into source_table (string_date_col) values ('1.1.23'); -- -> date
insert into source_table (string_date_col) values ('31.12.2021'); --> date
insert into source_table (string_date_col) values (null); --> null
insert into source_table (string_date_col) values ('start'); --> null
-- works just fine
-- gives either a valid date or null else
select cast(string_date_col as date) from source_table
;
-- SQL-Error [1292] [22001]: Data truncation: Incorrect datetime value: 'start'
insert into date_table (date_col)
select cast(string_date_col as date) from source_table
;
thanks to #Akina for the explanation
Im writing this as answer for better visibility
As Akina said on SELECT the cast produces a warning which is ignored so far and the CAST is done more or less correctly.
The warning can be seen in the log.
When doing an INSERT the warning becomes an error (due to the fact that its an insert and not a select any more). Due to the error the process aborts.
CREATE TABLE orders(
order_id INTEGER PRIMARY KEY,
customer_id INTEGER,
order_date DATE,
ship_date DATE
);
INSERT INTO orders
VALUES
(1, 1200, '2013-23-10', '2013-28-10');
Is there anything wrong with the above code?
You are using 'YYYY-dd-MM' format whereas you need to use 'YYYY-MM-dd', try the following:
INSERT INTO orders VALUES (1, 1200, '2013-10-23', '2013-10-28');
Date format is 'YYYY-MM-DD'.
23 and 28 are not valid values for MM month component.
The error returned by MySQL is expected behavior.
Nothing necessarily wrong with what you are doing, if you are want MySQL to return an error message.
If you are wanting the statement execution to be successful, and to add a row to orders table, supply valid date values for the DATE columns.
Either change the literal values to match the format expected by MySQL, or use STR_TO_DATE function to convert the string from a specified format.
... , '2013-10-23' , ...
or
... , STR_TO_DATE('2013-23-10','%Y-%d-%m') , ...
I have an INSERT query in ruby and I'm passing parameters from another table. One of the parameters is a timestamp value, for example: 2015-11-22 12:57:06 +0000 which is stored in a variable name created_at (of type Time)
insert into my_tbl set
name = '#{name}',
created_at = #{created_at}
and I'm always getting errors while trying to insert it.
I've tried to convert it to string, and to use str_to_date function, but the problem is that I have a timestamp value.
How can I insert the value to the table?
INSERT INTO my_tbl (name, created_at)
VALUES (name, created_at.to_s.split(' +').first)
Format the input in mysql from chat and from ruby program insert and format in this chat with the sale format
Update:
In mysql :
Select to_date('"+varchar+"','dd/mm/yyyy'......
In Ruby:
Varchar='01/12/2015"
Of course with format
I'm an experience MS-SQL programmer, but new to MySQL.
I create a table:
create table temp
(
Col1 DateTime NOT NULL
)
I try to insert into the table:
insert into temp select '1/1/2014';
I get an error "Incorrect datetime value". Last I check, that was a valid date.
Your date format is not valid when inserted in MySQL. The correct way is to insert it in 'YYYY-MM-DD' or 'YY-MM-DD'
Please see http://dev.mysql.com/doc/refman/5.6/en/date-and-time-literals.html
I have tried to insert date and time string formatted into mysql timestamp field by using following two methods but both shows me 0000-00-00 00:00:00
INSERT INTO test VALUES ( UNIX_TIMESTAMP('2013-08-05 18:19:03') )
INSERT INTO test VALUES ( UNIX_TIMESTAMP(STR_TO_DATE('2013-08-05 18:19:03', '%Y-%m-%d %H:%i:%s')) )
I believe first one should work as I am expecting but not sure why isn't parsing date and time?
The problem is that your field is defined as TIMESTAMP but UNIX_TIMESTAMP returns an int. Use INSERT INTO test VALUES ('2013-08-05 18:19:03' ) instead.