STR_TO_DATE() Returning NULL - mysql

I've looked at the other questions regarding STR_TO_DATE() and their solutions aren't working for my case. I've also read up and searched elsewhere to no avail.
I'm importing many rows of the following XML:
<Game>
<id>21</id>
<GameTitle>Final Fantasy XIII</GameTitle>
<ReleaseDate>03/09/2010</ReleaseDate>
</Game>
<Game>
<id>31</id>
<GameTitle>Heavenly Sword</GameTitle>
<ReleaseDate>09/12/2007</ReleaseDate>
</Game>
With the following SQL statement:
USE test;
LOAD XML LOCAL INFILE 'C:\\xampp\\mysql\\data\\test.xml'
REPLACE
INTO TABLE games
ROWS IDENTIFIED BY '<Game>'
SET ReleaseDate = STR_TO_DATE(#ReleaseDate, '%c/%e/%Y');
GameTitle and ID are importing perfectly. I've tried using %m and %d and have ensured that the ReleaseDate column is the DATE datatype. All rows are writing NULL in the ReleaseDate column.
MySql is returning
2466 row(s) affected, 64 warning(s): 1265 Data truncated for column 'ReleaseDate'
at row 1 1265
Thank you in advance for you help. StackOverflow has solved every problem I've really ever had without even having to ask.

You'd need to assign something to the variable you're using with STR_TO_DATE, something like
LOAD XML LOCAL INFILE 'C:\\xampp\\mysql\\data\\test.xml'
REPLACE
INTO TABLE games (id, GameTitle, #var1)
ROWS IDENTIFIED BY '<Game>'
SET ReleaseDate = STR_TO_DATE(#var1, '%c/%e/%Y');
Note that the syntax for SET in LOAD XML is described in the syntax for LOAD DATA

Related

Truncated incorrect integer value MySQL

I have a table ABC that has many columns, two of which are:
ID - VARCHAR(10) and ROLE VARCHAR(10).
Now I have been trying to update the column ROLE using the ID and this is the query:
UPDATE TABLE ABC
SET ROLE='READ_ONLY'
WHERE ID='AB234PQR'
Now for some unknown reason, i have been getting the error - truncated incorrect integer value. I have no idea where I am going wrong.I have been banging my head over this for a while now.
I have visited other questions with the similar title.All use convert or some other function in where clause, But I have not used any such thing, still it gives me the same error.
I checked the table description and it seems fine. Where can I be going wrong? Any help is appreciated.
Can you please try this:
UPDATE ABC
SET ROLE='READ_ONLY'
WHERE ID='AB234PQR'
The correct syntax to update table entries is:
UPDATE `table_name`
SET `column_name` = 'value'
WHERE `column_name2` = 'value2';
It is as well recommended to use backticks around table names and column names, just like the way you can see in my snippet above.
Therefore using
UPDATE `ABC`
SET `ROLE` = 'READ_ONLY'
WHERE `ID` = 'AB234PQR'
should do the trick.

How to import time in HH:MM format in MySQL?

I have a dataset as follows,
Date,Time,ID,Name,Count
01-MAY-2009,00:00,4,Town Hall (West),209
01-MAY-2009,02:00,17,Collins Place (South),28
01-MAY-2009,23:00,18,Collins Place (North),36
For this I have created table with following schema,
CREATE TABLE table_name(date DATE, time TIME, id int, name VARCHAR(50), count int);
And for loading the table from ".csv" file as,
LOAD DATA INFILE '/home/cloudera/dataset.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(#var1, #var2, id, name, count)
SET date = STR_TO_DATE(#var1, '%d-%b-%Y')
SET time = TIME(#var2, "%H:%i");
But I get an error as,
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET time = TIME(#var2, "%H:%i")' at line 1
I can't understand what the error is. I have tried going through MySQL website and documentation, but can't make out what the correct format is. Can anyone please me. Thanks in advance.
I don't think that you even need to be using the TIME function here. Your current hour:minute string time literals should be good enough, q.v. the documentation:
Be careful about assigning abbreviated values to a TIME column. MySQL interprets abbreviated TIME values with colons as time of the day. That is, '11:12' means '11:12:00', not '00:11:12'
As valid literals, your times would be interpreted as having a zero second component. So, if you just insert those time strings as is, I think it should work. Try the following code:
LOAD DATA INFILE '/home/cloudera/dataset.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(#var1, Time, id, name, count)
SET date = STR_TO_DATE(#var1, '%d-%b-%Y');
Tim is right in pointing out that you do not need to convert your time data in the load data infile statement.
Just to answer why you get a syntax error: load data infile can only have a single set clause, in which assignments to multiple columns are separated by comma. Your code has multiple set clauses, hence it fails.
Also, the time() function does not have a 2nd parameter for a pattern. The function you need to use is called str_to_date().
So, it should look like as follows:
...
SET date = STR_TO_DATE(#var1, '%d-%b-%Y'), time = TIME(str_to_date(#var2, "%H:%i"));

Make Laravel use MySQL default value on insert/update

I've noticed that, in Laravel, (when using $model->fill(Input::all()), not that it matters how the data comes in), empty fields (empty in a form) come through as an empty string (''). That makes sense, as that's how it's delivered from browser to HTTP server to PHP.
The problem is that if the column is numeric and has a DEFAULT value, or is NULLable, the generated query from Eloquent has '' for the column's value and so MySQL interprets that and enters the value as 0 rather than the default column value or NULL. Is it something I'm doing wrong here, or will I need to put extra work in (e.g. a mutator) to detect this empty string and convert to null to achieve what I actually want?
Of course I understand that from a technical point of view, Laravel, without knowing how your columns work, can't just assume that empty string means pass NULL to the INSERT query, because sometimes you actually want to set a field (specifically a character-based one) to an empty string rather than NULL.
That said, I'd rather not have to define mutators for all my models just because I'm using $model->fill(), but is there anything I don't know about that I can do?
For the MySQL people reading this - is it correct behaviour to set a numeric field to 0 if passed ''? Seems like it should be seen as NULL as it's not explicitly 0, but I guess it's maybe weak typing equating '' to 0 rather than the more distant NULL.
There is a very simple way to do this, and that is by using an array_filter.
$input = array_filter(Input::all(), 'strlen');
$model->fill($input);
The array_filter will return all of the keys that have something assigned to them.
There are some caveats with this solution:
strlen has been used, and not empty. This is because empty will cause other items (such as the number 0) to also be unset.
this means that edits that are made with an update, such as a text box being completely emptied, will not be fulfilled by your application, so use wisely!
EDIT: As for the MySQL question, yes, this is normal.
mysql> SELECT CAST("tim?" AS SIGNED);
+------------------------+
| CAST("tim?" AS SIGNED) |
+------------------------+
| 0 |
+------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'tim?' |
+---------+------+-------------------------------------------+
For the default values to be inserted on some fields then do not set values for those fields explicitly.
When you receive form data, process each of the fields and decide for which of them you want to insert the default values. Then remove them from insert into ... statement.
Example:
Form fields: field1_1, field_2.
If valid input is given for both of them, then you can write sql statement like:
insert into my_table values( field_1_value, field_2_value );
If one of the fields, say field_2 does not have valid input and you still want the record go into the database table. Then write the sql statement like:
insert into my_table( field_1 ) values( field_1_value );
When you do this, SQL engine will use the default valued defined on the omitted fields in the insert statement.
Note: This only works when you have set default someValue on the columns at the time of creating or altering them in a database table.

How do I convert german dates to MySQL standard dates?

I'm importing a CSV file with dotted german dates into a MySQL database. I want the dates in the CSV to automatically be formatted correctly to the correct data type fields used by MySQL.
I'm using Sequel Pro for the import. I gather I'm supposed to use the STR_TO_DATE function, but I just can't wrap my head around how to use Add Value or Expression in the program.
German date
Here are the dates in the CSV file:
DD.MM.YYYY e.g.: 28.01.1978
MySQL date
Here is what I want to end up with in the database:
YYYY-MM-DD
e.g.: 1978-01-28
Here's what I've tried
I put in STR_TO_DATE('$5', '%d.%m.%Y'); into Add Value or Expression, but this only gives the following error message:
[ERROR in row 1] You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near '06.04.1997'', '%d.%m.
%Y');,'2KMX','43354997')' at line 2
Any ideas?
You need import the date field in a varchar fields (temp_varchar_field) first, after that, you can use something like:
update table_name set final_date=STR_TO_DATE(temp_varchar_field,'%d.%m.%Y');
You should do something like:
Create a temporary field: alter table table_name add column temp_varchar_field varchar(10);
Import, using Sequel Pro, the CVS file but using the temp_varchar_field for the date.
update table_name set final_date=STR_TO_DATE(temp_varchar_field,'%d.%m.%Y');
Delete the temp field if everything was imported properly. Using: alter table_name drop column temp_varchar_field;
I just got it to work with this piece of SQL-code:
load data local infile 'myfile.csv' into table `mytable`
fields terminated by ','
enclosed by '"'
lines terminated by '\n'
(surname, name, #germandate, telephone, etc)
set birthyear = STR_TO_DATE(#germandate , "%d.%m.%Y")
;
The clue here being the #germandate variable which is turned into the default MySQL date by setting the respective column with STR_TO_DATE(). No hacks needed! :)
It is easier if your CSV import would contain a date as a MySQL string, but it can be done otherwise too:
Step 1:
Define a varchar(10) for your german dates and import the data.
Step 2:
Add another field to your table:
ALTER TABLE `yourtable`
ADD COLUMN `your_mysql_date` DATE NULL;
Step 3:
Move the data:
UPDATE yourtable
SET your_mysql_date = CONCAT(
RIGHT(your_german_date,4),
'-',
MID(your_german_date,4,2),
'-',
LEFT(your_german_date,2)
);
...done!
There might be an easier way to solve this, but this way you have alot of control over the data and the formatting.

MySQL: Insert datetime into other datetime field

I have a table with a DATETIME column.
I would like to SELECT this datetime value and INSERT it into another column.
I did this (note: '2011-12-18 13:17:17' is the value the former SELECT gave me from the DATETIME field):
UPDATE products SET former_date=2011-12-18 13:17:17 WHERE id=1
and get
1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near '13:17:17 WHERE itemid=1' at line 1
Ok, I understand it's wrong to put an unquoted string in there, but is DATETIME just a string in the first place?
What do I put in there?
All I want is reliably transfer the existing value over to a new datetime field...
EDIT:
The reason I ask is: I have this special definition, DATETIME, and somehow I thought it gives me some security and other advantages when handling dates. Now it seems it is simply a specialized VARCHAR, so to speak.
Thanks for your answers, it seems this is indeed the intended behaviour.
According to MySQL documentation, you should be able to just enclose that datetime string in single quotes, ('YYYY-MM-DD HH:MM:SS') and it should work. Look here: Date and Time Literals
So, in your case, the command should be as follows:
UPDATE products SET former_date='2011-12-18 13:17:17' WHERE id=1
Try
UPDATE products SET former_date=20111218131717 WHERE id=1
Alternatively, you might want to look at using the STR_TO_DATE (see STR_TO_DATE(str,format)) function.
for MYSQL try this
INSERT INTO table1(myDatetimeField)VALUES(STR_TO_DATE('12-01-2014 00:00:00','%m-%d-%Y %H:%i:%s');
verification-
select * from table1
output- datetime= 2014-12-01 00:00:00
If you don't need the DATETIME value in the rest of your code, it'd be more efficient, simple and secure to use an UPDATE query with a sub-select, something like
UPDATE products SET t=(SELECT f FROM products WHERE id=17) WHERE id=42;
or in case it's in the same row in a single table, just
UPDATE products SET t=f WHERE id=42;