SSRS - Oracle DB, Passing Date parameter - oracle

Using SSRS with an Oracle Database. I need to prompt the user when running the report to enter a date for report. What is the best way to add in the parameter in my SSRS Report. Having problem finding the right date format. under the "Report Parameter" menu, I have setup the Report Parameters using the DateTime Datatype.
Keep getting this error "ORA-01843: Not a Valid Month"
Thank you for your help.
Select
a.OPR_Name,
a.OPR,
a.Trans_Desc,
a.Trans_Start_Date,
Cast(a.S_Date as date) as S_Date,
Sum(a.Duration) as T
From (
Select
US_F.OPR_Name,
ITH_F.OPR,
ITH_F.ITH_RID,
ITH_F.TRANSACT,
Transact.DESC_1 as Trans_Desc,
To_CHAR(ITH_F.Start_Time,'DD-Mon-YY') as Trans_Start_Date,
To_CHAR(ITH_F.Start_Time,'MM/DD/YYYY') as S_Date,
Substr(To_CHAR(ITH_F.Start_Time,'HH24:MI'),1,6) as Start_Time,
To_CHAR(ITH_F.End_Time,'DD-Mon-YY') as Trans_End_Date,
Substr(To_CHAR(ITH_F.End_Time,'HH24:MI'),1,6) as End_Time,
Cast(Case When To_CHAR(ITH_F.Start_Time,'DD-Mon-YY') = To_CHAR(ITH_F.End_Time,'DD-Mon-YY')
Then (((To_CHAR(ITH_F.End_Time,'SSSSS') - To_CHAR(ITH_F.Start_Time,'SSSSS')) / 60))/60
Else ((86399 - (To_CHAR(ITH_F.Start_Time,'SSSSS')) + To_CHAR(ITH_F.End_Time,'SSSSS'))/60)/60
End as Decimal(3,1)) as Duration
from Elite_76_W1.ITH_F
Left Join Elite_76_W1.Transact
on Transact.Transact = ITH_F.Transact
Left Join Elite_76_W1.US_F
on US_F.OPR = ITH_F.OPR
Where ITH_F.TRANSACT not in ('ASN','QC','LGOT')
) a
Where a.S_Date = #Event_Date
Having Sum(a.Duration) <> 0
Group By a.OPR_Name,
a.OPR,
a.Trans_Desc,
a.Trans_Start_Date,
a.S_Date
Order by a.OPR_Name

Oracle parameters are indicated with a leading colon - #Event_Date should be :Event_Date.

You use CAST(a.S_Date AS DATE) in your query, where a.S_Date is a VARCHAR: To_CHAR(ITH_F.Start_Time, 'MM/DD/YYYY'). If your session date parameter NLS_DATE_FORMAT is different from 'MM/DD/YYYY', this will result in a format error (in your case I suspect your NLS_DATE_FORMAT is something like DD-MON-YYYY, resulting in a "month" error).
A few options:
don't use TO_CHAR in the inner query (always try to keep the date format for internal calculations, use TO_CHAR only where it belongs -- in the GUI). If you only want the date portion, use TRUNC.
use TO_DATE instead of CAST in the outer query: to_date(a.S_Date, 'MM/DD/YYYY'), this is obviously tedious: you cast a date to a varchar that is later transformed to a date.

Related

Oracle: filter query on datetime

I need to restrict a query with a
SELECT ... FROM ...
WHERE my_date=(RESULT FROM A SELECT)
... ;
in order to achieve that I am using as result of the select a timestamp (if I instead use a datetime I get nothing from my select probably because the format I am using trims the datetime at the second).
Sadly this is not working because these kindo of queries:
select DISTINCT TO_DATE(TO_TIMESTAMP(TO_DATE('25-10-2017 00:00', 'dd-MM-yyyy HH24:MI'))) from DUAL;
return an
ORA-01830: date format picture ends before converting entire input string
how to deal with timestamp to date conversion?
If you want to just compare and check only he dates use trunc on both LHS and RHS.
SELECT ... FROM ...
WHERE trunc(my_date)=(select trunc(RESULT) FROM A)
... ;
This will just compare the dates by truncating the timestamp values
You can use the combination of "TRUNC" and "IN" keywords in your query to achieve what you are expecting. Please check the below query sample as a reference.
SELECT * FROM customer WHERE TRUNC(last_update_dt) IN (select DISTINCT (TRUNC(last_update_dt)) from ... )
Cheers !!

Date format in Oracle- fetching Date of certain range

I have a date table in my db in Oracle. When I run a query I get the date format as '01-05-2015' but when I run a similar query in BIRT, I get the date format as '01-MAY-2015 12:00 AM'. How can I get the date format in dd/mm/yyy by keeping the data type of date field as date.
here is sample of my database.
EQ_DT
05-07-2015
06-06-2015
15-02-2015
19-09-2015
28-12-2015
also my query is :
select to_date(to_char(to_date(enquiry_dt,'DD/MM/YYYY'),'DD/MM/YY'),'DD/MM/YY') as q from xxcus.XXACL_SALES_ENQ_DATAMART where to_date(to_char(to_date(enquiry_dt,'DD/MM/YY'),'DD/MM/YY'),'DD/MM/YY')>'21-06-2012' order by q
I am getting error of NOT A VALID Month also
If enquiry_dt is already a date column, why are you trying to convert it to date (and then to char and to date again)?
SELECT to_char(enquiry_dt, 'DD/MM/YYYY') AS q
FROM xxcus.xxacl_sales_enq_datamart
WHERE enquiry_dt > to_date('21-06-2012', 'dd-mm-yyyy')
ORDER BY enquiry_dt
In birt, where you place the field on the report, set the field type to date. Then in properties for that field , go to format date time, and finally specify the date formatting you want for that field .
I prefer to always use pass date parameters as strings to BIRT, using a known date format. This is for report parameters as well as for DataSet parameters.
Then, inside the query, I convert to date like this:
with params as
( select to_date(pi_start_date_str, 'DD.MM.YYYY') as start_date_incl,
to_date(pi_end_date_str, 'DD.MM.YYYY') + 1 as end_date_excl
from dual
)
select whatever
from my_table, params
where ( my_table.event_date >= params.start_date_incl
and
my_table.end_date < params.start_date_excl
)
This works independent of the time of day.
This way, e.g. to select all events for january 2016, I could pass the query parameters '01.01.2016' and '31.01.2016' (I'm using german date format here).

Date in LOV Query

I have a report that has two parameters, PM_DATE and PM_STOCK_ID. It's LOV query is
SELECT DISTINCT ID FROM STOCK_COUNT
I want to filter the parameter PM_STOCK_ID based on the date which user specifies in date parameter. In the where clause of LOV I tried using:
SELECT DISTINCT ID FROM STOCK_COUNT
WHERE TRUNC (SCHEDULE_DATE) = NVL (:PM_DATE, SCHEDULE_DATE)
but this didn't work.
I've also tried with a range using two parameters, P_SDATE (Start Date) and P_EDATE (End Date):
SELECT distinct id FROM STOCK_COUNT
WHERE
(TRUNC(SCHEDULE_DATE)) BETWEEN NVL(:P_SDATE, TRUNC(SCHEDULE_DATE)) AND NVL(:P_EDATE, TRUNC(SCHEDULE_DATE))
which gets error:
Parameter name: P_STOCK_ID Unparseable date: ""
How should I be doing this?
By just specifying the string :PM_DATE without a to_date function around it, you are getting implicit type conversion which is likely the root cause of the difficulty.

compare 13digit (millisecond) unix timestamp with date in oracle

A database column (VARCHAR2 datatype) stores the date/time as 13 digit (milliseconds
) unixtimestamp format. Now when I want to compare the column with a oracle date (in question), The error thrown as 'invalid number'
I tried both ways,
converting the 13digit number to Date and compare with the date in question like below. The expressions seems valid as they are printed in select query, but if i include in the where part, it throws 'invalid number'
Here 'value' is 13th digit unixtimestamp column of VARCHAR2 datatype.
select
TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000,
TO_DATE('2014-04-21', 'YYYY-MM-DD')
from dummytable
-- where and TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000 > TO_DATE('2014-04-21', 'YYYY-MM-DD')
converting the date in question to 13digit unixtimestamp and comparing with the database column.The expressions seems valid as they are printed in select query, but if i include in the where part, it throws 'invalid number'
.
select
value,
(to_date('2013-04-21', 'YYYY-MM-DD') - to_date('1970-01-01', 'YYYY-MM-DD')) * (1000*24*60*60)
from dummytable
-- where value > ((to_date('2013-04-21', 'YYYY-MM-DD') - to_date('1970-01-01', 'YYYY-MM-DD')) * (1000*24*60*60))
any pointers? Thanks in advance.
[EDIT- 1 day later] I see the problem now. There are some data (other rows) for the 'value' column that are non-numeric. But I have another column say field, where always field='date' return value as 13 digit timestamp. Now I think when 'where' condition executes, although the field='date' is in the condition, it is still validating the other values for 'value' which are non-numeric. Is there a way to avoid this ?
Your code works just fine. The problem is in your data. Some of your values is not a number.
create table test
(value varchar2(13));
insert into test(value) values('2154534689000');
--insert into test(value) values('2 54534689000');
select TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000
from test
where TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000 > TO_DATE('2014-04-21', 'YYYY-MM-DD');
This code works fine. But if you uncommented the second insert, you would get exactly the same invalid number error as you get.
UPD. Allan gave you a nice hint, but i feel that it can be good to explain you a bit about views. The fact that you select from a view CAN make a difference. A view is not stored somewhere physically, when you select from it, it is just "added to your query". And then Oracle Query Optimizer starts working. Among other things, it can change the order in which your where predicates are evaluated.
For example, your the view query can have a line where value is not null and it would normally show only 'good' values. But if your query has a predicate where to_date(value,'ddmmyyyy') > sysdate, Oracle can decide to evaluate your predicate earlier, because Oracle predicts that it would "cut off" more rows, thus making the whole query faster and less momery consuming. Of course, execution will crash because of an attempt to convert a null string to date.
I believe, that Allan in his answer that he gave a link to, gave a great way to solve this problem: "wrapping" your query in a subquery that Oracle can't "unwrap":
select value
from
(select value
from my_view
where rownum > 0)
where to_date(value,'ddmmyyyy') > sysdate
Hope that helps.

BIRT Report: Parameters between two dates

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

Resources