I have a DB2 table where NUM column is defined as INTEGER in DB2 and the query result is shown below,
NUM columns have numeric values which needs to be converted to date format. This numeric values are nothing but duration from 01.01.1850. Example : 01.01.1850 + 57677 days = 01.12.2007.
So Is it possible to convert or cast the numeric value into date fields in DB2 , so that the select query from the table can result as shown below after converting a numeric field into date field,
You may use the scalar ADD_DAYS function:
SELECT EMP_ID, ADD_DAYS('1850-01-01', NUM) AS NUM
FROM yourTable;
Not all Db2 products & versions have the ADD_DAYS function.
The following expression works for all of them.
You may optionally add DAY or DAYS at the end.
DATE ('1850-01-01') + 57677
I want to concatenate string with year in oracle. The string is month.
Query is
select to_date('11'||EXTRACT(YEAR FROM SYSDATE)-1,'MMYYYY') from dual;
This query wrks fine however if the string is '01' or anything starting with zero i am getting not a valid month error.
select to_date('04'||EXTRACT(YEAR FROM SYSDATE)-1,'MMYYYY') from dual;
select to_date('05'||EXTRACT(YEAR FROM SYSDATE)-1,'MMYYYY') from dual;
Let's run it without the to_date(..., ...) wrapper:
select '04'||EXTRACT(YEAR FROM SYSDATE)-1 from dual;
'04'||EXTRACT(YEARFROMSYSDATE)-1
--------------------------------
42019
Do you see the problem? (Note that the result is a number, not even a string.)
Concatenation is performed before you subtract 1. You get the string '042020' first, and then you subtract 1; the string is converted to number, and you get the result 42019. When you apply TO_DATE() this is converted back to string, and the first thing Oracle will choke on is the 42 for month.
Use parentheses around the arithmetic operation to force the subtraction to be performed first, and it will work:
select to_date('04'||(EXTRACT(YEAR FROM SYSDATE)-1), 'MMYYYY') from dual;
TO_DATE('04'||(EXTR
-------------------
2019-04-01 00:00:00
Data = 2019-12-31
Don't know the data type of the data variable
Below query
Select to_date (data, 'yyyy-mm-dd') from dual
Working as follows
Select to_date (2019-12-31, 'yyyy-mm-dd') from dual;
output is
Error
Input value not long enough for date format
Don't say i haven't given single quotes .becoz i cant give single quotes to 'data' in the query
Can u give solution s assuming scenarios where the data comes without single quote or where data is number or date datatype
select to_char(to_date(20191231,'yyyymmdd'),'mm-dd-yyyy') from dual;
Convert number to date sql oracle
tl;dr
Why am I not able to convert following string timestamp
select timestamp_format('2015-08-21 000000', 'YYYY-MM-DD HH24MISS') as timestamp
from sysibm.sysdummy1;
on an i7.1.0/OS machine?
Especially since I can convert
select timestamp_format('000000' , 'HH24MISS') as timestamp
from sysibm.sysdummy1;
to:
timestamp
-------------------------
2015-08-01 00:00:00.000000
Context
On an i7.1.0/OS machine, I have a table with timestamp data split up in several decimal columns, like
declare global temporary table tstamp
(
year dec(4,0),
month dec(2,0),
day dec(2,0),
time dec(6,0)
);
with data like
insert into session.tstamp
values (2015,8,21,92601),
(2015,8,21,132601);
on which I want to do some date filtering. Given the somewhat inflexible format, I figured that it is probably better if I convert this to a timestamp and use this to query the table. So i consulted the i/OS 7.1 Manual on timestamp_format
I started of with building the date part, ending up with
select
timestamp_format(YEAR || '-' || MONTH || '-' || DAY, 'YYYY-MM-DD') as timestamp
from session.tstamp;
which returns
TIMESTAMP
--------------------------
2015-08-21 00:00:00.000000
2015-08-21 00:00:00.000000
Perfect, let us add the time part and explicit lpad it to contain six characters:
select
timestamp_format(YEAR || '-' || MONTH || '-' || DAY || ' ' || lpad(TIME, 6, '0'), 'YYYY-MM-DD HH24MISS') as timestamp
from session.tstamp;
This results in the following error:
SQL State: 22007
Vendor Code: -20448
Message: [SQ20448] Expression not valid using format string specified for TIMESTAMP_FORMAT. Cause . . . . . : Argument 1 of the TIMESTAMP_FORMAT function can not be interpreted using the format string specified in argument 2 for one of the following reasons: -- The string expression is too short or too long. -- The string expression does not conform to the template specified in the format string. -- Too many digits were specified in the string expression for the corresponding format element in the format string. -- A value in the string expression is not valid for the corresponding format element in the format string. Recovery . . . : Specify a valid format string for the function. Try the request again.
According to the manual regarding the format-string, a separator between fields is optional:
[...]
Two format elements can optionally be separated by one or more of the following separator characters:
[...]
Question
So why are not my values accepted when using 'YYYY-MM-DD HH24MISS' as the format-string, given that I explicit has bound the time length to six characters?
Side note
It is possible to use HH24MISS on its own as format-string, so I'm not really able to wrap my head around this.
select timestamp_format(lpad(TIME, 6, '0'), 'HH24MISS') as timestamp from session.tstamp;
TIMESTAMP
--------------------------
2015-08-01 13:26:01.000000
2015-08-01 09:26:01.000000
The difficulties described, are due to defects with the TIMESTAMP_FORMAT [aka TO_DATE] scalar. The requests shown are tested to have functioned, as expected, with the DB2 for IBM i 7.3 [and as a comment to the OP suggests, also on v7r2]. I had asked a similar question, "Why the failures using my earlier examples?" in SQL convert text mm/dd/yy to date and timestamp, but I have not yet re-visited those examples on the newer release. And FWiW, there may be some updated code on IBM i 7.1 for that feature with the latest code; I do not have that level of maintenance, so I can not test if the [the last of the] enhancements that are coming for that release include the code fixes that apparently exist in newer releases.
Note that the TO_DATE feature is not a true built-in [instead, is a system-supplied User Defined Function (UDF)], so personally, I would recommend an alternative; namely, writing and using a scalar UDF specific to the task, and/or choose a more compatible and easy way to generate the TIMESTAMP from those columns as they are defined. Consider the following expression [that assumes all dates are beyond year 1000, else the expression must change to use DIGITS(YEAR) vs just YEAR]:
timestamp( YEAR concat digits( MONTH ) concat digits( DAY )
concat digits( TIME )
)
A variation of that, is to use arithmetic to achieve the same effect of a 14–character timestamp-string form 'yyyymmddhhmmss':
timestamp( concat( YEAR * 10000 + MONTH * 100 + DAY
, digits ( TIME ) ) )
The following scalar function could be created to avoid coding the expression in [VIEW] queries or other places. As coded, with nothing but an expression on a RETURN statement, should allow in-lining; I did not specify any other potentially performance-related clauses such as parallel or on-null-input:
create function y4m2d2t6TS
( year dec(4, 0)
, month dec(2, 0)
, day dec(2, 0)
, time dec(6, 0)
) returns timestamp
language sql deterministic
return
digits( YEAR ) concat digits( MONTH )
concat digits( DAY ) concat digits( TIME )
; -- this semicolon is a statement separator, not terminator of above CREATE
select
y4m2d2t6TS( year, month, day, time ) as timestamp
from session.tstamp
; -- likeness of report from above query:
TIMESTAMP
2015-08-21-09.26.01.000000
2015-08-21-13.26.01.000000
******** End of data ***
You can use this in DB2 :
values(VARCHAR_FORMAT(current_date,'YYYY-MM-DD HH24:MI:SS'))
Bye
Different behaviour ,when the date contains year 2000
select to_date(add_months(sysdate,-50),'dd/mm/yyyy') from dual --error
ORA-01858: a non-numeric character was found where a numeric was expected
-- 04/08/2000 12:59:15 contains year 2000
select to_date(sysdate,'dd/mm/yyyy') from dual --this work,but diff output
You should use TO_CHAR instead of TO_DATE.
The first parameter of TO_DATE function is a STRING parameter so here your data is converted to STRING representation and then converted to date format BUT in the DIFFERENT format:
to_char(add_months(sysdate,-50),'dd/mm/YYYY')
Your first query select to_date(add_months(sysdate,-50),'dd/mm/yyyy') from dual works fine for me
Result:
TO_DATE(ADD_MONTHS(SYSDATE,-50),'DD/MM/YYYY')
---------------------------------------------
04-OCT-09