Case expression inside a where clause - Oracle - oracle

I have a column of dates that has 2 different formats of data: yyyy-mm-dd and dd/mm/yyyy.
Because of that, I have to indentify the format of the date so I can convert them in the right format. My SQL query is as follows:
select *
from teste
where
(CASE
WHEN data like '%-%' THEN
TO_DATE(data, 'yyyy-mm-dd') BETWEEN
TO_DATE(01/01/2000, 'dd/mm/yyyy') AND
TO_DATE(01/01/2016, 'dd/mm/yyyy')
ELSE
TO_DATE(data, 'dd/mm/yyyy') BETWEEN
TO_DATE(01/01/2000, 'dd/mm/yyyy') AND
TO_DATE(01/01/2016, 'dd/mm/yyyy')
END)
Running this, I get the error:
00905. 00000 - "missing keyword"
*Cause:
*Action:
Erro na linha: 6 Coluna: 35.
It seems that there is a problem in the between clause. Could anyone help me with this?

CASE expression returns you some value. And you should compare this value with something. You can't put whole expression inside CASE.
E.g.
select *
from teste
where
CASE WHEN data like '%-%' THEN
TO_DATE(data, 'yyyy-mm-dd')
ELSE
TO_DATE(data, 'dd/mm/yyyy')
END
BETWEEN TO_DATE(01/01/2000, 'dd/mm/yyyy') AND
TO_DATE(01/01/2016, 'dd/mm/yyyy')

Related

Difference between the performance of to_date(:PARAMETER, 'DD/MM/YYYY') and to_date('20/11/2019', 'DD/MM/YYYY')

I have a query like this:
select * from table where dat_reg between to_date('19/11/2019', 'DD/MM/YYYY') and to_date('19/11/2019', 'DD/MM/YYYY') + 1
On PL/SQL, the performance is perfect. But when I put this on report:
select * from table where dat_reg between to_date(:DAT_BEGIN, 'DD/MM/YYYY') and to_date(:DAT_END, 'DD/MM/YYYY') + 1
My performance drops a lot. Why?
The parameters are of type character

encountered the symbol FROM when expecting one of the following pl sql

I am trying to extract year from datefield but when I use extract (year from
datefield) I get this error
Encountered the symbol FROM when expecting one of the following pl sql
cursor o1 is
select substr(tarifa,1,2), count(*)
from pol p, uvod u, doppov d
where extract(year FROM datum_dop) = EXTRACT(YEAR FROM sysdate)
and izdavanje >='1-jul-13'
and p.orgjed = u.sorgz (+)
and DATUM_PREKIDA is not null
and p.polica=d.polica and d.pov_dopl='P'
and d.status='F'
and cisti_ao(p.polica)!=0
group by substr(tarifa,1,2);
Where did I made mistake ?
Ah, this is Forms, probably 6i.
Its engine doesn't know extract function. Change that line to
where to_char(datum_dop, 'yyyy') = to_char(sysdate, 'yyyy')
This would, though, make index on datum_dop column (if it exists) unusable and force Oracle to convert dates to strings, so you'd rather try with
where datum_dop >= trunc(sysdate, 'yyyy')
and datum_dop < add_months(trunc(sysdate, 'yyyy'), 12)
Other than that:
count(*) should have an alias (if you plan to use it), e.g. count(*) as broj_tarifa
if izdavanje is date, don't compare it to a string ('1-jul-13') but date, e.g. izdavanje >= to_date('01.07.2013', 'dd.mm.yyyy')
use table aliases for all columns

SCN to TimeStamp - wrong expression?

I have SCN:
SELECT TIMESTAMP_TO_SCN(SYSTIMESTAMP) SCN FROM DUAL;
I can convert it to time stamp:
SELECT SCN_TO_TIMESTAMP(6480157) FROM DUAL;
When I want to mix this two select Im getting error:
SELECT SCN_TO_TIMESTAMP(SELECT TIMESTAMP_TO_SCN(SYSTIMESTAMP) FROM DUAL) FROM DUAL;
ORA-00936: missing expression
Please use
SELECT SCN_TO_TIMESTAMP(TIMESTAMP_TO_SCN(SYSTIMESTAMP)) FROM DUAL;
#F.Madsen has the correct and simplest answer, but just to illustrate, you can get to the result following your logic:
SELECT SCN_TO_TIMESTAMP(SCN) FROM
(
SELECT (TIMESTAMP_TO_SCN(SYSTIMESTAMP)) SCN FROM DUAL
);

Oracle: handle different date format

Assume we have a VARCHAR2 column called MyDate
Assume it contains the following values:
13/02/2001
13-gen-2001
I have to convert this field to a DATE value. But TO_DATE fails either on some values or on the others.
TO_DATE(MyDate, 'DD/MM/YYYY')
How can I convert it?
SELECT CASE
WHEN REGEXP_LIKE(mydate, '\d{2}/\d{2}/\d{4}') THEN
TO_DATE(mydate, 'DD/MM/YYYY')
WHEN REGEXP_LIKE(mydate, '\d{2}-[a-z]{3}-\d{4}') THEN
TO_DATE(mydate, 'DD-MON-YYYY')
END
FROM mytable
you can write like this
CASE WHEN instr(labour_contract_expiry, '-') > 0 THEN
to_date(LABOUR_CONTRACT_EXPIRY,'DD-MON-RRRR')
ELSE
to_date(LABOUR_CONTRACT_EXPIRY,'DD/MM/RRRR')
END,
At least you can do something like
CASE WHEN REGEXP_LIKE(YOUR_COLUMN,'\d{2}/\d{2}/\d{4}' THEN TO_DATE(MyDate, 'DD/MM/YYYY')
WHEN REGEXP_LIKE(YOUR_COLUMN,'\d{2}-\D{,3}-\d{4}' THEN TO_DATE(MyDate, 'DD-MON-YYYY')
WHEN ...
etc.

TO_DATE error in Oracle

When I run this query:
SELECT * FROM tbl_person
WHERE to_date(date_create, 'dd/mm/yyyy') < to_date('01/01/2010', 'dd/mm/yyyy')
I hit the following error:
ORA-01841: (full) year must be between -4713 and +9999, and not be 0
To be clear, date_create field stored SYSDATE when I added into table. What I need is to retrieve data from tbl_person table starting from 01/01/2010 onward.
You don't want to call TO_DATE on a DATE. Just use the date column in the query (and compare it to a date)
SELECT *
FROM tbl_person
WHERE date_created < to_date('01/01/2010', 'dd/mm/yyyy')

Resources