Ignore date conversion warnings (MySQL) - mysql

I have CSV file, contains date field that has either:
1. %Y-%m-%d
2. %m/%d/%Y
3. empty string
The code I use for importing:
LOAD DATA INFILE ...
SET EpStartDate = IFNULL (DATE(#v_EpStartDate), STR_TO_DATE(#v_EpStartDate, '%m/%d/%Y')),
...
But this code throws warning about every %m/%d/%Y date, and about each empty cell.
It's very important to me to show only crucial warnings, when the data is wrong, like if the date is 03/18/20095.
Any idea how to do that?

It's doable using custom function:
DROP FUNCTION IF EXISTS PARSE_DATE;
DELIMITER //
CREATE FUNCTION PARSE_DATE ( str VARCHAR(255) ) RETURNS DATE
BEGIN
IF str in ('',' ','.') THEN RETURN null;
ELSEIF str like '__/__/____' THEN RETURN STR_TO_DATE(str, '%m/%d/%Y');
ELSEIF str like '__-__-____' THEN RETURN STR_TO_DATE(str, '%m-%d-%Y');
ELSE RETURN DATE(str); /*may throw a warning*/
END IF;
END//
DELIMITER ;

Read the IFNULL function details here.enter link description here. The code
IFNULL(expr1, expr2)
returns expr1 if expr1 is NOT null, and expr2 if expr1 IS null.
So when the date variable is not empty, it is returned as it is (without checking for format, as that is done in expr2 in your code above) and when it is empty, it is checked against the date format.
Thus your program gives you warnings because you are checking for date formats on empty strings and at the same time input the non-empty strings without checking for their date format.

Related

I Getting error when run this below query : RETURN statements in scalar valued functions must include an argument

I am getting this error message
RETURN statements in scalar valued functions must include an argument
when run this query:
create function gender(#gender nvarchar(40))
returns nvarchar(40)
as
begin
(select name,cast(DOB as date) as DOB from datenames where gender = #gender)
return
end
The write way to create a function in mysql for your example is as follows:
DELIMITER \\
create function gender(Igender nvarchar(40))
returns nvarchar(40)
begin
DECLARE customerLevel NVARCHAR(40);
IF EXISTS (select name,cast(DOB as date) as DOB from datenames where gender = Igender) THEN
SET customerLevel = 'SOMETHING1';
ELSE
SET customerLevel = 'SOMETHING2';
END IF;
RETURN (customerLevel);
end
No need to as
No need to # before input
You need to return something.
Don't forget to use DELIMITER.
If you use phpmyadmin and has problem with nvarchar read this post: Unrecognize data type nvarchar in database or simply change it to to varchar.

Truncated Inccorrect date value while calling nested function

I have two function.
fn_validate_date
fn_validation
fn_validate_date code:
CREATE DEFINER=`root`#`localhost` FUNCTION `fn_validate_date`(
`dt_date` DATE
)
RETURNS date
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Returns the associated value of given attribute for given employee for a particular date.'
BEGIN
SET dt_date = IF(dt_date IS NULL OR dt_date ='', CURRENT_DATE, dt_date);
RETURN dt_date;
END
fn_validation code:
CREATE DEFINER=`root`#`localhost` FUNCTION `fn_validation`(
`dt_date` DATE
)
RETURNS date
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
RETURN fn_validate_date(dt_date);
END
Now when I am calling fn_validate_date as below
SELECT `fn_validate_date`(null);
It's working well but when I calling fn_validation it's giving me an error.
SELECT `fn_validation`(null);
My question is why I didn't get error while calling fn_validate_date?
In fn_validate_date, the dt_date-parameter is type of date and you are comparing it to a string datatype. No need for that. Date datatype cannot contain ''. It either is NULL or has a date value in it.
So instead of:
SET dt_date = IF(dt_date IS NULL OR dt_date ='', CURRENT_DATE, dt_date);
You can simply use:
return ifnull( dt_date, current_date() );
I disable strict mode and it's working well.
SET sql_mode =''
To disable strict mode in MySQL. I am not sure why MySql short-circuited IF condition as I am passing NULL in the input parameter of fn_validation.

PostgreSQL Date Conversion Function

I have one challenge:
I have the following code in SQL Server and I want to move it to PostgreSQL DBMS.
I adapted it to PostgreSQL just like the following:
CREATE function public.SEMANA_ISO (fecha date) returns integer as $$
DECLARE
semana_ISO int= date_part ('week',fecha)+1
-date_part('week',CAST(date_part('year',fecha) as CHAR(4)) + '0104');
BEGIN
IF (semana_ISO=0)
THEN
semana_ISO=public.SEMANA_ISO(CAST(date_part('year',fecha)-1
AS CHAR(4)) + '12' + CAST(24 + date_part('day',fecha) AS CHAR(2)))+1;
ELSIF ((date_part('month',fecha)=12) AND ((date_part('day',fecha)-date_part('day',fecha))>=28))
THEN
semana_ISO=1;
END IF;
RETURN semana_ISO;
END;
$$ LANGUAGE plpgsql;
As you may see, I tried to make it look the most similar as in SQL Server is.
However when I try to run this function and test it:
Select public.SEMANA_ISO('28/12/2014');
The DMBS shows many errors:
ERROR: operator does not exist: character + unknown
LINE 2: ...rt('week',CAST(date_part('year',fecha) as CHAR(4)) + '0104')
HINT: No operator matches the name and type of the arguments. You may need to add explicit type casts.
QUERY: SELECT date_part ('week', date) +1
-date_part ('week', CAST (date_part ('year', date) as CHAR (4)) + '0104')
CONTEXT: PL / pgSQL function semana_iso (date) at line 5 during initialization of local variables in the statement block
What I try to do is the following.
From the following input date format: dd/mm/yyyy I want to use the function above to show it as the next output format:mm-dd-yyyy
I have thought in doing a simpler function that could receive the date in the format given (dd/mm/yyyy) and using the set datestyle = mdy statement change it in the body of the function and finally print it or return it.
What do you suggest folks?
Your help & time is always appreciated!
A guess you may need a Function like below
CREATE function a_date_conv (fecha date) returns text as $$
select to_char(fecha, 'mm-dd-yyyy');
$$ LANGUAGE sql;
select a_date_conv('08/10/2014')
Result
-------
10-08-2014

How to validate input date in YYYY-MM-DD format inside the MySQL procedure

I have one DATE input parameter for a procedure ex: IN p_date DATE.I want to validate this input DATE parameter format inside a procedure which should be in YYYY-MM-DD format. If the input parameter is having characters or date format is wrong it should through an exception using SIGNAL.
Please find the below code what i written
CREATE PROCEDURE `validation_check`(IN pdate_time DATE)
BEGIN
DECLARE InputValidation CONDITION FOR SQLSTATE '45000';
DECLARE dateValidation CONDITION FOR SQLSTATE '45000';
/* Doing NULL validation */
IF pdate_time IS NULL THEN
SIGNAL InputValidation
SET MESSAGE_TEXT='pdate_time should not be empty.';
END IF;
/* Doing Date format validation
IF STR_TO_DATE(pdate_time,'%Y-%m-%d') != pdate_time THEN
SIGNAL dateValidation
SET MESSAGE_TEXT='Input Date format should be in YYYY-MM-DD.';
END IF;
*/
/* Doing Date format validation */
IF pdate_time NOT REGEXP '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/' THEN
SIGNAL dateValidation
SET MESSAGE_TEXT='Input Date format should be in YYYY-MM-DD.';
END IF;
SELECT pdate_time;
END
Thanks,
Sagar
TL;DR
Regular expression will fail in this case, because they may only check date format, but not if it is a valid date (as, for example, '2014-02-30' has correct format but invalid data for date)
Use string functions
Concept
The solution is - yes, use string functions. However, regular expressions will also be useful - to check if format was good, you still need to check date itself. Since validation of date is a single separated issue - you should create a function for it. That function will accept string and return result as boolean value - so either date is ok or not. This will be re-usable and, therefore, more flexible.
Code
Here we go with the function:
CREATE FUNCTION VALIDATE_DATE(d VARCHAR(255))
RETURNS INT
BEGIN
DECLARE date_year VARCHAR(255) DEFAULT '';
DECLARE date_month VARCHAR(255) DEFAULT '';
DECLARE date_day VARCHAR(255) DEFAULT '';
DECLARE ym_delim INT DEFAULT 0;
DECLARE md_delim INT DEFAULT 0;
-- First, if it's just not xxx-yyy-zzz format:
SET ym_delim = LOCATE('-', d);
SET md_delim = LOCATE('-', d, ym_delim+1);
IF !ym_delim || !md_delim THEN
RETURN FALSE;
END IF;
-- Second, if resulted members are not YYYY, MM or DD:
SET date_year = SUBSTR(d, 1, ym_delim-1);
SET date_month = SUBSTR(d, ym_delim+1, md_delim-ym_delim-1);
SET date_day = SUBSTR(d, md_delim+1);
IF date_year NOT REGEXP '^[0-9]{4}$'
|| date_month NOT REGEXP '^[0-9]{2}$'
|| date_day NOT REGEXP '^[0-9]{2}$' THEN
RETURN FALSE;
END IF;
-- Finally, check if date itself is ok, like 2014-02-30 isn't ok:
IF DATE(CONCAT(date_year, '-', date_month, '-', date_day)) IS NULL THEN
RETURN FALSE;
END IF;
RETURN TRUE;
END//
DELIMITER ;
As you can see, we have three cases, when date validating fails:
First, if there are no proper delimiters (which are -). Then year, month and day just can't be found
Second, if extracted year, month and day part are just bad (for instance, date was foo-bar-baz). That's why we can't use date functions to extract those parts and so we have to use string functions.
Third - finally, if our date parts seems to be good, there still may be false result because of invalid combination (2014-13-01 has wrong month, for example).
Seems to be a solution
There is, however, STR_TO_DATE() function which may look like solution. Unfortunately, it will pass date parts which are not in corresponding format (such as 2014-1-1) - thus, it can't be used for direct format validation. That is why I used separate stored function instead.
What will be passed
All YYYY-MM-DD dates, which are correct in terms of MySQL, will be passed. That is, early dates, such as '0001-01-01' are correct :
mysql> SELECT VALIDATE_DATE('0001-01-01');
+-----------------------------+
| VALIDATE_DATE('0001-01-01') |
+-----------------------------+
| 1 |
+-----------------------------+
1 row in set (0.00 sec)
And, in fact, they should be correct, because they are valid for MySQL. However, such things as 001-01-01 won't be passed even despite fact, that such strings are correct for MySQL dates too:
mysql> SELECT VALIDATE_DATE('001-01-01'), DATE('001-01-01');
+----------------------------+-------------------+
| VALIDATE_DATE('001-01-01') | DATE('001-01-01') |
+----------------------------+-------------------+
| 0 | 0001-01-01 |
+----------------------------+-------------------+
1 row in set (0.00 sec)
And that is derived from your format expectations - you should filter all the things, which do not have YYYY-MM-DD format exactly, thus, you'll have such results.

Simple T-SQL function to convert date to displayable format

I have a strange bug that I cannot resolve (with a one line function).
This code works:
DECLARE #TestDate datetime = '2013-05-01 23:15:11'
select IsNull(convert(varchar(max), #TestDate, 120), 'null') as 'test1'
Displays: 2013-05-01 23:15:11
CREATE FUNCTION [dbo].[DateOrNullToChar] (#InputDate date)
RETURNS VARCHAR(40)
BEGIN
return ISNULL(convert(varchar(40),#InputDate, 120),'null');
END
select dbo.DateOrNullToChar('2013-05-01 23:15:11') as 'result'
Returns: 2013-05-01 (no time)
I have also tried varchar(max).
The purpose of the function is for something like this:
Set #ErrorMessage = ' #ArrivalDate=' + dbo.DateOrNullToChar(#ArrivalDate) +
' #DepartureDate=' + dbo.DateOrNullToChar(#DepartureDate);
If any one value is null, the whole value becomes null. So I want to see the string 'null' when a date has a null value.
#InputDate should be datetime or datetime2 if you want time to be shown
The clues are in the code...
#TestDate datetime
#InputDate date
You need to make the parameter type to be datetime instead of date:
CREATE FUNCTION [dbo].[DateOrNullToChar] (#InputDate datetime)
It's silently converting the string to your date parameter type and thus dropping the time portion.