Power BI Oracle OLEDB need a where clause to get the first day of the year - oracle

using Power BI to connect to Oracle database server 19c using this connection: provider=OraOLEDB.Oracle.1;data source=gencdbp.domain.pri:1521/GAEN
I need a SQL statement that limits the rows so I don't have to hardcode it.
This works:
select * from aTable where DateCreated >= TO_Date('01/01/2022', 'MM/DD/YYYY')
I have tried the Year function and TRUNC function. Both of these gives me an error:
DateCreated is a Timestamp(6). These do not work:
where DateCreated >= trunc(sysdate, 'YEAR')
where trunc(DateCreated, 'YEAR') = trunc(sysdate, 'YEAR')
YEAR(DateCreated) = YEAR(sysdate)
These all give me this error:
ORA-00904: "YEAR": invalid identifier
Details:
DataSourceKind=OleDb
DataSourcePath=data source=gencdbp.domain.pri:1521/GAEN;provider=OraOLEDB.Oracle.1
Message=ORA-00904: "YEAR": invalid identifier
ORA-00904: "YEAR": invalid identifier
ErrorCode=-2147217900

I don't know tool you use (Power BI), but - have a look at the following example:
Sample table that contains a column whose datatype matches the one you specified:
SQL> create table test (datecreated timestamp(6));
Table created.
Insert sample value:
SQL> insert into test values (systimestamp);
1 row created.
OK, let's now try something you said doesn't work (but raises ORA-00904):
SQL> select * from test where trunc(datecreated, 'year') = trunc(sysdate, 'year');
DATECREATED
---------------------------------------------------------------------------
11-MAY-22 09.47.30.544000 PM
It works OK for me.
Another option might be the extract function:
SQL> select * from test where extract(year from datecreated) = extract(year from sysdate);
DATECREATED
---------------------------------------------------------------------------
11-MAY-22 09.47.30.544000 PM
So, are you sure you really used code you posted? Because, that's the error which suggests that there's no column named year in that table. To simulate it, I removed single quotes for year (which is - for the to_char function - format model):
SQL> select * from test where trunc(datecreated, year) = trunc(sysdate, year);
select * from test where trunc(datecreated, year) = trunc(sysdate, year)
*
ERROR at line 1:
ORA-00904: "YEAR": invalid identifier
SQL>
Right; here it is, ORA-00904.

Related

Oracle date comparison using to_date not working

I am using Oracle XE on my machine.
Defined a table as :
Name Type
ENAME VARCHAR2(20)
DOJ DATE
Firing a simple select:
select * from test1.tasty1;
ENAME DOJ
sat 08-DEC-16
So ok - I am aware that DATE field has time component in it.
The following query using TRUNC works fine:
select * from test1.tasty1 where trunc(DOJ) = '08-DEC-16';
Now I wanted to test the 'to_date' function - but none of the below queries worked - wonder why ?
select * from test1.tasty1 where DOJ =
to_date('08-12-2016','DD-MM-YYYY');
select * from test1.tasty1 where
DOJ = to_date('08-DEC-2016','DD-MON-YYYY');
select * from
test1.tasty1 where DOJ = to_date('08-DEC-16','DD-MON-YY');
select
* from test1.tasty1 where DOJ = to_date('08-DEC-16','dd-mon-RR');
Had taken a look at the following on SO:
Oracle TO_DATE not working
so not sure what is wrong here ?
From your question and comments, it appears that this is the sequence of events which happened.
You did the following INSERT into your table:
INSERT INTO test1.tasty1 VALUES ('sat', SYSDATE)
Keep in mind that dates in Oracle have both a date and a time component. So even though you did insert the date '2016-12-08' you also inserted a time component. As a result, the following query is not returning any records:
SELECT * FROM test1.tasty1 WHERE DOJ = '2016-08-12'
This is probably because you never specified the time component, and therefore the record you inserted earlier is not matching. If you want to compare only the date portion, you can use TRUNC as follows:
SELECT * FROM test1.tasty1 WHERE TRUNC(DOJ) = '2016-08-12'
The solution to your problem moving forward would be to wrap SYSDATE with TRUNC during the insert, if you really only want to deal with the date components.
By the way, the format '08-DEC-16' used as a literal will not be recognized by Oracle as a valid date. Instead, use '2016-12-08'.
Have you tried like this as comparison of date with date is correct:
select * from test1.tasty1 where to_date(DOJ,'DD-MM-YYYY') = to_date('08-12-2016','DD-MM-YYYY');
Compare apples with apples and not with mangoes.
What it worked from is instead of make a date to compare, change the date column to char with to_char(datecol, 'DD-MM-YYYY') = '01-01-2022'

encountered an invalid number error calling the below oracle stored procedure

SELECT Ticket, ETRs, "Last ETR","Last ETR Time Change","STAR Restore Time","Restore Time - Last ETR"
FROM(
SELECT e.xsystemjob Ticket,
a.eventkey Event,
(select count(generatedtime) from obvwh.ops_ertchangelog_fact where eventkey = a.eventkey) ETRs,
to_char(a.ERT, 'MM/DD/YYYY HH24:MI:SS') "Last ETR", --GENERATEDTIME,
to_char(generatedtime, 'MM/DD/YYYY HH24:MI:SS') as "Last ETR Time Change",
to_char(e.restdate,'MM/DD/YYYY HH24:MI:SS') as "STAR Restore Time",
round(((e.restdate - a.generatedtime) * 1440),0) as "Restore Time - Last ETR"
FROM obvwh.ops_ertchangelog_fact a
join obvwh.ops_event_dim e
on a.eventkey = e.eventkey
where a.generatedtime = (select max(generatedtime) from obvwh.ops_ertchangelog_fact where eventkey = a.eventkey)
)
WHERE Substr(Ticket,0,1) = region
AND to_char("Last ETR", 'MM/DD/YYYY') between to_char(start_date,'MM/DD/YYYY') and to_char(end_date,'MM/DD/YYYY');
From you inner query, Last ETR is a string, representing the column value in format MM/DD/YYYY HH24:MI:SS. You're trying to convert that string to a string, passing a single format mask, and that is throwing the error.
You can see the same thing with a simpler demo:
select to_char('07/18/2016 12:13:14', 'MM/DD/YYYY') from dual;
Error report -
SQL Error: ORA-01722: invalid number
You could explicitly convert the string to a date and back again:
select to_char(to_date('07/18/2016 12:13:14', 'MM/DD/YYYY HH24:MI:SS'), 'MM/DD/YYYY') from dual;
TO_CHAR(TO
----------
07/18/2016
... but in the context of your comparison that doesn't really make sense anyway if the range you're comparing with can span a year end - the format mask you're using doesn't allow for simple comparison. Assuming start_date and end_date are dates (with their times set to midnight) you could do:
AND to_date("Last ETR", 'MM/DD/YYYY HH24:MI:SS') between start_date and end_date;
or even simpler, use the original raw ERT value (which is presumably already a date), and convert it to a string - if that is actually the right thing to do - in the outermost select list.
I'm not quite sure why you have an inline view here at all though, or why you're using a subquery to get the count since you're already querying ops_ertchangelog_fact - maybe you want to be using analytic functions here.

Oracle DB Ora-01839: date not valid for month specified. 29-02-2016 leap year

We all know today is a special day. Its the 29th of February 2016 of a leap year.
We receive an error message from some tables in our Oracle DB. The error is:Oracle ORA-01839: date not valid for month specified.
For example a simple select where the error occurs:select * from table where table_date > sysdate -0.1;
For other tables this select makes no problem, just for some of the tables.
Is there a way to fix this issue? Because we are not able to use many tables today.
We are using Oracle 12c.
After intensive research, its clear why some of our selects does not work today. The error is caused by the keyword interval and its a known issue. (Or it's how the ANSI/ISO spec says it should work, bottom of page 205/top of page 206)
Here is a qoute from the oracle community blog:
Question:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' year as dt from dual;
ORA-01839: date not valid for month specified
01839. 00000 - "date not valid for month specified"
*Cause:
*Action:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '2' year as dt from dual;
ORA-01839: date not valid for month specified
01839. 00000 - "date not valid for month specified"
*Cause:
*Action:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '3' year as dt from dual;
ORA-01839: date not valid for month specified
01839. 00000 - "date not valid for month specified"
*Cause:
*Action:
select to_date('2012-feb-29','yyyy-mon-dd') + interval '4' year as dt from dual;
29-FEB-16 00:00:00
select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' day as dt from dual;
01-MAR-12 00:00:00
select to_date('2012-feb-29','yyyy-mon-dd') + interval '1' month as dt from dual;
29-MAR-12 00:00:00
Answer:
That's just how INTERVALs work. Leap years are the least of the
problem; adding 1 month to March 31 results in the same error. If you
want to make sure that the result is a valid DATE, then use
ADD_MONTHS. (There's no separate function for adding years; use
ADD_MONTH (SYSDATE, 12*n) to get the DATE that is n years from now.)
Why it happens in our case:
In our case, we used virtual private database for some of our tables because of security reasons. And there we applied the interval keyword in most of the selects.
What to do instead:
Use ADD_MONTHS instead.
select add_months(to_date('2012-feb-29','yyyy-mon-dd'), 12) as dt from dual;

JPA 2 Criteria Day from date

I have a field in a table and that stores a date. I'd like to select all records that which the date is on day 5.
After a lot of research I get the code below:
Predicate dayValue = cb.equal(cb.function("day", Integer.class, test.<Date>get(Test_.dateInit)), now.get(Calendar.DAY_OF_MONTH) );
But, I'm using a Oracle database and it doesn't have the function day:
[EL Warning]: 2013-01-14 11:51:08.001--UnitOfWork(23011228)--Thread(Thread[main,5,main])--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-00904: "DAY": invalid identifier
Is there an other way to do this select?
Thanks
I got a way.
Using the function to_char of oracle in the function method:
Predicate dayValue = cb.equal(cb.function("to_char", Integer.class, test.<Date>get(Test_.dateInit),cb.parameter(String.class, "dayFormat")), now.get(Calendar.DAY_OF_MONTH) );
...
q.setParameter("dayFormat", "DD");
In Oracle you can use
select to_char (date '2013-01-14', 'D') d from dual;
to give you the day number, the above will output 1 for Monday
if you want to see Monday just change to
select to_char (date '2013-01-14', 'Day') d from dual;
the above will output Monday
hope that helps.

Between 2 date/times in PL/SQL not giving expected answers

I have a query in PL/SQL on Oracle 10g that isn't behaving as I thought. I'm 100% sure I am doing something silly so I'm sorry.. Here goes:
I have some data in a table that looks like this:
I then went to query but using the time element, like this:
select * from dw_time
where createdtime > to_date('2012/04/12 03:06:00', 'yyyy/mm/dd hh24:mi:ss')
When this is executed we get records returned that include the rows in the image 03:05AM. So thinking it was the to_date function I checked that:
select to_date('2012/04/12 10:24:00', 'yyyy/mm/dd hh:mi:ss')
from dual;
Now I was totally confused as it clearly know that as a time. So I tried it again:
select * from dw_time
where createdtime > to_date('2012/04/12 03:06:00', 'yyyy/mm/dd hh24:mi:ss')
As you can see it is totally ignoring the time component! At this point I thought it was time to ask the gurus on here!
Many thanks
Mike
Is it possible that in your table '12/4/2012' means 4 Dec 2012 and query outputs it in MM/DD/YYYY format?
Look at DB output date format - it's MM/DD/YYYY - you can see it on output of:
select to_date('2012/04/12 10:24:00', 'yyyy/mm/dd hh:mi:ss') from dual;
So change your select to:
select * from dw_time where createdtime > to_date('2012/12/04 03:06:00', 'yyyy/mm/dd hh24:mi:ss')
You can see date output format by this query:
select * from nls_session_parameters where parameter = 'NLS_DATE_FORMAT';
And you can change date output format by this:
alter session set NLS_DATE_FORMAT='DD/MM/YYYY HH24:MI:SS';

Resources