Inject character to date column - sql

I have a date column.
select RETAIL_ACQUISITION_DTTM from XXXXX.TABLE_2348
13/07/2018
I want to select the value as such it returns as below,
2018-07-13T00:00:00
so it has to display the date as YYYY-MM-DD with T and then HH24:MI:SS

You need to convert your string (why is it stored as a string?) to a date using a format model that matches the actual string value:
to_date(RETAIL_ACQUISITION_DTTM, 'DD/MM/YYYY')
Having that format model wrong is why you get the 0013 year in your result.
Then you can convert that date back to a string with to_char(), and you can embed the fixed T as a character literal with double quotes, using a format model like 'YYYY-MM-DD"T"HH24:MI:SS':
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select '13/07/2018' from dual
)
select to_char(to_date(RETAIL_ACQUISITION_DTTM, 'DD/MM/YYYY'),
'YYYY-MM-DD"T"HH24:MI:SS') as RETAIL_ACQUISITION_DTTM
from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
2018-07-13T00:00:00
You could also just ignore that it is a date and use string manipulation:
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select '13/07/2018' from dual
)
select substr(RETAIL_ACQUISITION_DTTM, 7, 4)
|| '-' || substr(RETAIL_ACQUISITION_DTTM, 4, 2)
|| '-' ||substr(RETAIL_ACQUISITION_DTTM, 1, 2)
|| 'T00:00:00' as RETAIL_ACQUISITION_DTTM
from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
2018-07-13T00:00:00
If the column is actually a date rather than a string then you are doing unnecessary conversions, including implicit ones which rely on your NLS settings, and you are losing the original time from the value if it was not midnight anyway:
alter session set nls_date_format = 'DD-MON-RR';
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select to_date('2018-07-13 12:34:56', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select to_char(to_date(RETAIL_ACQUISITION_DTTM, 'YYYY-MM-DD-HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS') as RETAIL_ACQUISITION_DTTM from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
0013-07-20 18:00:00
That is really doing:
to_char(
to_date(
to_char(
RETAIL_ACQUISITION_DTTM,
'DD-MON-RR'), ---- from your session NLS_DATE_FORMAT setting
'YYYY-MM-DD-HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS')
If you skip to extra steps you can just format the date directly:
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select to_date('2018-07-13 12:34:56', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select to_char(RETAIL_ACQUISITION_DTTM,
'YYYY-MM-DD"T"HH24:MI:SS') as RETAIL_ACQUISITION_DTTM
from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
2018-07-13T12:34:56
which also doesn't rely on your NLS settings, so won't break in interesting ways if it's run in another session with different settings.

replace sysdate with your column name if its date type.
Using Single to_char:
select to_char(sysdate,'--YYYY-MM-DD"T"hh24:mi:ss') from dual;
Using two to_char and concatenation for simplification.
select to_char(sysdate,'--'||'YYYY-MM-DD')||'T'||to_char(sysdate,'hh24:mi:ss') from dual; -- 13/07/2018
select '--'||to_char(sysdate,'YYYY-MM-DD')||'T'||to_char(sysdate,'hh24:mi:ss') from dual; -- 13/07/2018

Related

null values not processed by to_timestamp in oracle sql

I'm trying to load data from a csv with sql-loader. There's one column with date in this format:
2011-12-31 00:00:00.000
I tried it using to_date() but it couldn't handle fractions of second. Therefore I used this:
cast(TO_TIMESTAMP(:DATUM_ONTVANGST, 'YYYY-MM-DD HH24:MI:SS.FF3')as date)
Now I get the error:
ORA-01841: (full) year must be between -4713 and +9999, and not be 0
for null values in the column
Can to_timestamp not handle null values or am I doing something wrong?
This works:
select
cast(TO_TIMESTAMP('2011-12-31 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FF3')as date)
from dual
and this also works
select
cast(TO_TIMESTAMP(null, 'YYYY-MM-DD HH24:MI:SS.FF3')as date)
from dual
So there must be some value that is not right format
I think there is space(<field>, ,<field>) in your data which is causing the issue.
Better to use TRIM before using them.
Following are some examples to demonstrate with different values:
-- working fine with correct timestamp values
SQL> SELECT
2 CAST(TO_TIMESTAMP('2019-11-05 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FF3') AS DATE) as dt
3 FROM
4 DUAL;
DT
---------
05-NOV-19
-- working fine with a null value
SQL>
SQL> SELECT
2 CAST(TO_TIMESTAMP(NULL, 'YYYY-MM-DD HH24:MI:SS.FF3') AS DATE) as dt
3 FROM
4 DUAL;
DT
---------
-- working fine with an empty value
SQL>
SQL> SELECT
2 CAST(TO_TIMESTAMP('', 'YYYY-MM-DD HH24:MI:SS.FF3') AS DATE) as dt
3 FROM
4 DUAL;
DT
---------
Now showing the error and solution
-- giving an error with space in the value -- Your case
-- might be you are considering it as the null
-- but it is actually a value that is a space character
SQL>
SQL> SELECT
2 CAST(TO_TIMESTAMP(' ', 'YYYY-MM-DD HH24:MI:SS.FF3') AS DATE) as dt
3 FROM
4 DUAL;
CAST(TO_TIMESTAMP(' ', 'YYYY-MM-DD HH24:MI:SS.FF3') AS DATE) as dt
*
ERROR at line 2:
ORA-01841: (full) year must be between -4713 and +9999, and not be 0
-- Solution to your issue -- using TRIM
SQL>
SQL> SELECT
2 CAST(TO_TIMESTAMP(TRIM(' '), 'YYYY-MM-DD HH24:MI:SS.FF3') AS DATE) as dt
3 FROM
4 DUAL;
DT
---------
SQL>
Cheers!!
Building off Ersin's answer, this is the format that worked for me
select
cast(NULL AS TIMESTAMP WITH LOCAL TIME ZONE) as date
from dual

Update date field of one table from the value taken from another table

I have two table A and B where both have date fields but in different format('MM/DD/YYYY HH:MI:SS' and 'MM/DD/YYYY') and they both have a common field called invoiced_value. I need to update the date values of table A(with 'MM/DD/YYYY HH:MI:SS') from the values of table B(with 'MM/DD/YYYY'). Can i use the following query?. can i append the date like this to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS') ?.
UPDATE Table1
SET m.invoiced_date = to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS')
FROM Table2 e, Table1 m
WHERE m.invoiced_value = e.invoiced_value
[TL;DR] Use a MERGE statement:
MERGE INTO Table1 dst
USING Table2 src
ON ( src.invoiced_value = dst.invoiced_value )
WHEN MATCHED THEN
UPDATE SET invoiced_date = TRUNC( src.invoiced_date ) + INTERVAL '3:56:24' HOUR TO SECOND;
Can i use the following query?
No, an UPDATE statement does not have a FROM clause. You would need to use a correlated sub-query or a MERGE statement.
can i append the date like this to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS') ?.
Maybe ... but you should not do it this way. TO_DATE( string_value, format_model ) takes a string as the first argument (and the || string concatenation operator also requires string arguments to concatenate) so your e.invoiced_date will be implicitly converted from a DATE to a string and your expression is effectively:
to_date(
TO_CHAR(
e.invoiced_date,
( SELECT value FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
) || ' 3:56:24',
'MM/DD/YYYY HH:MI:SS'
)
If your NLS_DATE_FORMAT session parameter is MM/DD/YYYY then your query will work. If it is something different then your query will either raise an exception or work but give incorrect results. Since NLS_DATE_FORMAT is a session parameter and each user can set it to whatever value they want then you should not rely on this to be consistent.
Instead, add an interval literal to the date (which does not require any conversions to-or-from a string):
TRUNC( src.invoiced_date ) + INTERVAL '3:56:24' HOUR TO SECOND
Or explicitly convert the date to a string in the correct format:
TO_DATE( TO_CHAR( e.invoiced_date, 'MM/DD/YYYY' ) || ' 3:56:24', 'MM/DD/YYYY HH24:MI:SS' )

Convert yyyy/mm/dd into dd/mm/yyyy hh24:MI:SS

I'm trying to convert data in format 2016/06/26 into 26/06/2016 00:00:00
I was trying few option all the time getting error "Invalid months name",
Any idea/advice?
Thanks
select to_date('2016/05/07 00:00:00','mm/dd/yyyy HH24:MI:SS') from dual
In order to convert a string to a date you need to convert it first to a date. Your problems is that you are trying to format a string not a date. So for you specific case it would be:
--convert it first to a date
select to_date('2016/05/07 00:00:00','yyyy/mm/dd HH24:MI:SS')
from dual
--then convert it to a string in the format you want:
select to_char( to_date('2016/05/07 00:00:00','yyyy/mm/dd HH24:MI:SS'),
'mm/dd/yyyy HH24:MI:SS' )
from dual
--since you want it as a date:
--then convert it to a string in the format you want:
select to_date( to_char( to_date('2016/05/07 00:00:00',
'yyyy/mm/dd HH24:MI:SS'),
'mm/dd/yyyy HH24:MI:SS' )
'mm/dd/yyyy HH24:MI:SS' )
from dual
If you want just to convert your string into a date no matter the format, just use the first select I showed. Thanks to #Boneist in comments for pointing it out.

removing milliseconds from a oracle tmstmp field

I have a TIMESTAMP(6) field in Oracle and I need to remove the millisecond component from the time.
For example I have
10/20/2014 10:34:06.356000 AM
and I would like to remove the milliseconds so that I have
10/20/2014 10:34:06 AM
Do you know the best way to do this?
Thank you!
How about this?
select cast(col as timestamp(0))
EDIT:
The easiest way to avoid rounding is to use trunc() or to subtract half a second:
select cast(col - 0.5/(24*60*60) as timestamp(0))
try this
SELECT TO_CHAR(SYSDATE, 'MM-DD-YYYY HH24:MI:SS') "NOW"
FROM DUAL;
if you need 12-hour date format
SELECT TO_CHAR(SYSDATE, 'MM-DD-YYYY HH:MI:SS AM') "NOW"
FROM DUAL;
SQL FIDDLE
You can either cast it to a timestamp with no fractional seconds (this will round to the nearest second):
CAST( your_timestamp AS TIMESTAMP(0) )
Or to a DATE data type (this will truncate to the nearest second):
CAST( your_timestamp AS DATE )
If you want it as a TIMESTAMP(0) data type then cast it back:
CAST( CAST( your_timestamp AS DATE ) AS TIMESTAMP(0) )
Or you can convert it to a formatted string and specify the format model you want to use (this will truncate to the nearest second):
TO_CHAR( your_timestamp, 'YYYY-MM-DD HH24:MI:SS' )
Like this:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE your_table ( your_timestamp ) AS
SELECT TIMESTAMP '2017-10-25 12:53:12.10076' FROM DUAL;
Query 1:
SELECT CAST( your_timestamp AS TIMESTAMP(0) ) AS "Timestamp",
CAST( your_timestamp AS DATE ) AS "Date",
TO_CHAR( your_timestamp, 'DD-MM-YYYY HH24:MI:SS' ) AS "String"
FROM your_table
Results:
| Timestamp | Date | String |
|-----------------------|----------------------|---------------------|
| 2017-10-25 12:53:12.0 | 2017-10-25T12:53:12Z | 25-10-2017 12:53:12 |
note: How the TIMESTAMP and DATE are formatted in the output will depend on your NLS_TIMESTAMP_FORMAT and NLS_DATE_FORMAT session parameters but you can directly control the formatting of TO_CHAR when you specify a format model.
This might help!
select substr(to_char('10/20/2014 10:34:06.356000 AM'),1,instr(to_char('10/20/2014 10:34:06.356000 AM'),'.')-1)||' '||
substr(to_char('10/20/2014 10:34:06.356000 AM'),-2,instr(to_char('10/20/2014 10:34:06.356000 AM'),'.')-1) "Date"
from dual;

Date Error Invalid Number

I would like to add 10 minutes to sysdate,
select to_char(SYSDATE,'dd-Mon-yyyy hh:mi:ss') + 10/1440 from dual
when I tried the above I got the error
ORA-01722: invalid number
The error appears because you add 10/1440 to char not to date.
Try this:
select SYSDATE + 10/1440 from dual;
or
select to_char(SYSDATE+ 10/1440,'dd-Mon-yyyy hh:mi:ss') from dual;
or
select to_char( sysdate + interval '10' minute,'dd-Mon-yyyy hh:mi:ss')
from dual;
Here you can find more information.
Here you can find similar problem on SO, there are more solutions.
You don't need to "to_char" the date first.
Either
select SYSDATE + 10/1440 from dual;
or
select to_char(SYSDATE + 10/1440,'dd-Mon-yyyy hh:mi:ss') from dual;
depending on whether you just want a date or a string representation of the date formatted in a certain way.