Given this date format:
"15.03.2016"
How to convert it into ISO8601 yyyy-MM-dd.
You can try something like this
DECLARE MyDate DATE;
SET MyDate = DATE '15.03.2016';
DECLARE newDate CHARACTER;
SET newDate = CAST(CURRENT_DATE AS CHARACTER FORMAT 'dd-MM-yyyy');
The answer from Omar is missing the parsing of the input string. When using the DATE keyword, the string must be in the form 'yyyy-MM-dd'. (See: https://www.ibm.com/docs/en/app-connect/12.0?topic=types-esql-date-data-type) Thats why it can't be used in this case.
You should rather use the CAST function to cast the input String to a Date and in a second step cast it to a character in your desired format.
The possible formats are listed here: https://www.ibm.com/docs/en/app-connect/12.0?topic=function-formatting-parsing-datetimes-as-strings
So the snippet should look like this:
DECLARE inputDate DATE;
SET inputDate = CAST ('15.03.2016' AS DATE FORMAT 'dd.MM.yyyy');
DECLARE outputDate CHARACTER;
SET outputDate = CAST(inputDate AS CHARACTER FORMAT 'yyyy-MM-dd');
Related
can anyone suggest be if there is any other option to do this have its saying' failed: 'In function 'formatdatetime', the value provided for date time string '' was not valid. The datetime string must match ISO 8601 format.'.
"ETA": "2022-11-16T10:03:00.000Z",
-- desired output i need
"ETA" : "16-11-2022 10:03:00"
I did use the function
formatdatetime(item()?['ETA'], 'dd-MM-yyyy HH:mm:ss')
-- desired output i need
"ETA" : "16-11-2022 10:03:00"
then I need to save the output in csv file.
It looks like on of your ETA rows in the Table is empty.
You could add error handling to your expression. Try something like below:
if(empty(item()?['ETA']), '', formatdatetime(item()?['ETA'], 'dd-MM-yyyy HH:mm:ss'))
I am trying to create function of existing SELECT query.
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = 353
AND uta.Approved = 1
AND DATE '2020-06-06' BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
When I execute this query, I get correct result in output StartDate and EndDate.
But problem is when I write function and try to compile I get error
Error(724,8): PL/SQL: ORA-00936: missing expression
FUNCTION GET_AVAILABE_USER_PER_DATES(p_userId IN INT,p_dateFormat IN VARCHAR2)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = p_userId
AND uta.Approved = 1
AND DATE p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY;
RETURN rc;
END GET_AVAILABE_USER_PER_DATES;
Compiler gives me error in following line
AND DATE p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
I try to understand what I made wrong, where is mistake but I couldn't ?
What is wrong here ? What i make wrong can someone tell me ?
UPDATE
FUNCTION ABSENCE_EXIST_FOR_DATE(p_userId IN INT,p_dateFormat IN DATE)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = p_userId
AND uta.Approved = 1
AND p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY;
RETURN rc;
END ABSENCE_EXIST_FOR_DATE;
Error gone, but unfortunetlly when I execute function I get error message
ORA-01861: literal does not match format string
01861. 00000 - "literal does not match format string"
*Cause: Literals in the input must be the same length as literals in
the format string (with the exception of leading whitespace). If the
"FX" modifier has been toggled on, the literal must match exactly,
with no extra whitespace.
*Action: Correct the format string to match the literal.
You must replace
DATE p_dateFormat
with the appropriate conversion of the VARCHAR2 parameter p_dateFormat to the DATE type
to_char(p_dateFormat,'yyyy-mm-dd')
Adapt the the format if appropriate or use DATE parameter in the function.
Than you would simple constraint
FUNCTION GET_AVAILABE_USER_PER_DATES(p_userId IN INT,p_dateFormat IN DATE)
...
AND p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
Check if the name p_dateFormat is the best possible name for a parameter with a DATE value (or a string with a DATE value) ...
To avoid ORA-01861: literal does not match format string use the ON CONVERSION ERROR clause as follows (Oracle 12 and up is required)
FUNCTION GET_AVAILABE_USER_PER_DATES(p_userId IN INT,p_dateFormat IN DATE)
...
AND p_dateFormat BETWEEN TO_DATE(uta.StartDate default null on conversion error,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate default null on conversion error,'YYYY-MM-DD') + INTERVAL '1' DAY
If the column EndDate or StartDate contain invalid data, such as today or 2020-99-01 the conversion will not fail with error, but returns null, is the record will not be selected (which is probably what you want).
This leads into a cte in Oracle 11g:
declare
STARTDATE DATE := '01/01/2017';
;with cte(Accounts) AS (....
This is the error I am getting:
ORA-06550: line 10 column 1 PLS-00103:Encountered the symbol ";"
I need to declare a startdat and it needs to = the date provided.
The snippet you posted doesn't have a begin before tha with, and instead has an extra semicolon.
declare
startdate DATE := DATE '2017-01-01';
begin
with cte(Accounts) AS (....
... complete that statement ... ;
end;
/
You can set the date value as part of the declaration; you shouldn't set it to a string though, as that relies on implicit conversion and NLS settings. I've used a date literal, which has to be in exactly the format shown, YYYY-MM-DD; but to_date() would also work (a literal is simpler though, for a fixed date).
For what I see code, you have to remove the semicolon that is before the statement WITH
Can I convert a string column formatted as "YYYY-MM" from SQL back into a Date that uses text. (ie. January, 2014) as a new column using proc SQL?
Initially my source is 2014-01 and I would like every row to be converted to the respective month and year as shown. I have tried the Format option outside of the proc SQL table build, however I need it as a Macro date afterwards.
Thanks
Here's one option that uses a custom format. First convert to date using INPUT() with the ANYDTDTE. format. Then you can either display the variable with the format or you can convert it to a new character variable with the format applied.
/*Create your own format definition*/
proc format;
picture monyyc_fmt (default=25)
low - high = "%B, %Y" (datatype=date);
run;
data want;
str='2014-12';
date=input(str,anydtdte.);
format date monyyc_fmt.;
want=put(date, monyyc_fmt.);
put (_all_) (=/);
run;
proc print data=want;
run;
Results are:
Obs str date want
1 2014-12 December, 2014 December, 2014
References for the custom date format:
http://www2.sas.com/proceedings/sugi31/243-31.pdf
Not sure what PROC SQL has to do with the issue of converting the value. One way would be to convert your string to date using INPUT() and then use the CATX(), PUT() and YEAR() functions and the MONNAME. format to build the new string.
data _null_;
str='2014-12';
date=input(str,anydtdte.);
format date date9.;
want=catx(', ',put(date,monname.),year(date));
put (_all_) (=/);
run;
You could skip the middleman and just parse the string yourself to get the year number. This might be easier to code inside an SQL statement.
want=catx(', ',put(input(str,anydtdte.),monname.),scan(str,1,'-'));
In SQL, consider the next example:
-- The table holding the result
CREATE TABLE #myTable(stringDate CHAR(7), dateValue DATETIME, newStringDate VARCHAR(20))
-- The values in original format
INSERT INTO #myTable(stringDate) SELECT '2014-01'
INSERT INTO #myTable(stringDate) SELECT '2014-02'
INSERT INTO #myTable(stringDate) SELECT '2014-03'
INSERT INTO #myTable(stringDate) SELECT '2015-01'
INSERT INTO #myTable(stringDate) SELECT '2015-02'
GO
-- All months have a first day, so conveting "2014-01" to date is just removing "-" and adding "01"
UPDATE #myTable SET dateValue = CAST(REPLACE(stringDate, '-', '') + '01' AS DATETIME)
GO
-- When we have the dates, you can tranform it to the format you want
UPDATE #myTable SET newStringDate = DATENAME(MONTH, dateValue) + ', ' + CAST(YEAR(dateValue) AS VARCHAR)
GO
SELECT * FROM #myTable
I've got a report I'm writing in BIRT against an Oracle database:
Table:
tranx_no (string)
type (string)
description (string)
amount (number(14,2))
date (date)
Query in BIRT:
SELECT tranx_no, type, description, amount
FROM tranx_table
WHERE date BETWEEN ? AND ?
If I just do plain dates (02-01-2014 and 02-14-2014) in the parameters, it misses things that happen during the day of the 14th (stops at midnight). I've tried concatenating the time onto the date parameter
WHERE date BETWEEN ? || '12:00:00 AM' AND ? || '11:59:59 PM'
and got an ORA 01843 error. I also tried casting it with to_date
WHERE date BETWEEN TO_DATE(? || '12:00:00 AM', 'MM-DD-YYYY HH:MI:SS AM') AND TO_DATE(? || '11:59:59 PM', 'MM-DD-YYYY HH:MI:SS AM')
and no joy there either. ORA 01847 error happens with that one.
Ideas? I know there's probably something simple I'm not thinking of, but Google hasn't helped. I'm wanting to edit the query, not change the date entry on the face of the form.
Thanks.
Correct handling DATEs with BIRT can be tricky.
I recommend to always use VARCHAR2 for passing DATE parameters (for report parameters as well as for query parameters). Always verify the data type of your parameters.
In your SQL, always use TO_DATE / TO_CHAR with an explicit date format - otherwise the results would depend on the locale settings.
Next, be sure that the value the user entered is adjusted to a known date-format before it is used in the query. For example, in Germany the SQL date format DD.MM.YYYY HH24:MI:SS is commonly used.
You could create a utility function which adds the missing parts (e.g. the time) automatically. Use an additional argument in this function to specify if it's a "from" date (adds 00:00:00) or a "to" date (adds 23:59:59).
OTOH if the UI forces the user to enter a from-to date without time (say in the format 'MM-DD-YYYY' as in your example), you could just code
WHERE (date >= to_date(?, 'MM-DD-YYYY') and date < to_date(?, 'MM-DD-YYYY') + 1)
Note the usage of < and not <=.
This works because if no time is specified in the format mask, 00:00:00 (in HH24:MI:SS format) is implied.
As you pointed out the start date is not a problem as it begins at 00:00:00 of the start date. If your paramter is a text box your users can enter 02-01-2014 08:00:00 to get results starting at 8am on Feb 1.
Note that my date format has the year first, while yours has the year last
For the end date, I use a text box paramater with this as my default value
//Creates a date for one second before midnight of the current date,
//which is properly formatted to use as an end date in quires (for my data)
// Note that a custom date format (yyyy-MM-dd HH:mm:ss) is required for proper display in pop-up GUI
var T; T = BirtDateTime.addDay(BirtDateTime.today(),1);
var Y; Y = BirtDateTime.year(T);
var M; M = BirtDateTime.month(T);
var D; D = BirtDateTime.day(T);
{
Y +"-"
+ M +"-"
+ D +" "
+"00:00:00"
}
I also use this help text
Enter date as YYYY-MM-DD. For example, 2013-3-14
Adn this prompt text
End Date (YYYY-MM-DD), if time is blank will default to 00:00:00