BIRT Report: Parameters between two dates - oracle

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

Related

HANA: expression for input parameter to convert time string into today's timestamp

In SAP HANA I can use filters as SQL or Column Store expression within a modelling view (e.g. Calculation View).
I'm trying to convert the time string like 08:00:00 into timestamp which should always take today's date.
The single hana routing I've found until now is the function TO_TIMESTAMP( [, ]).
Is there any build in function for my requrement or how else would you solve this problem?
Thanks and BR.
EDIT: this is how I try to concatenate the today's date and entered time into timestamp:
longdate(string(date(now())) +string(' ')+string(time($$P_StartShift$$))+string('.123456'))
HANA doesn't have a neat construction API for datetime data types.
So, this is somewhat a workaround.
The idea here is that you have the time of the day provided as user input.
With that, we can calculate the seconds since midnight, which in turn can be added to the current_date.
In HANA SQL this is what it looks like:
select
to_time ('13:01', 'HH24:MI') user_input_time
, current_date
, seconds_between ('00:00'
, to_time ('13:01', 'HH24:MI')) secs_since_midnight
, add_seconds (current_date
, seconds_between ('00:00'
, to_time ('13:01', 'HH24:MI')
)
) current_date_user_time
from
dummy;
/*
USER_INPUT_TIME CURRENT_DATE SECS_SINCE_MIDNIGHT CURRENT_DATE_USER_TIME
1:01:00 PM 25/08/2020 46,860 25/08/2020 1:01:00.0 PM
*/

Little bit misunderstanding with datetime formats

SELECT TO_TIMESTAMP('2016-10-01 01:00:01', 'YYYY-MM-DD HH24:MI:SS') from dual;
Gives : 2016-10-01 01:00:01
Here year and month parts are understood for me, but Documentation says about other formats:
"DD" - Day of month (1-31)
"HH24" - Hour of day (0-23)
"MI" - Minute (0-59)
"SS" - Second (0-59)
So, why for example "DD" format returns 01 and not just: 1 ?
For example "MM" format, in same doc described as:
MM - Month (01-12; January = 01) and here everything clearly: January = 01 .
Also, little bit confusing is time parts (for me at least) , because in documentation, range for all begins with 0 but returns result as 00
I've expected from above query, result like this:
2016-10-1 1:0:1
What I missed and don't understood correctly?
First you are passing in two strings: the actual datetime (or timestamp) you want to convert to timestamp datatype, and the format model. Then you call to_timestamp(), and the result is a timestamp. Then you DISPLAY this on screen (through SQLPlus or SQL Developer or whatever). Only strings can be displayed on screen - not numbers, not timestamps, etc. So: somewhere, somehow, your timestamp is converted back to a string.
You either do that explicitly, by calling to_char(.....) around your timestamp, or if you don't, the interface application (SQLPlus, SQL Developer, ...) uses your session's NLS_TIMESTAMP_FORMAT parameter. In that parameter, you can force whatever format model you want. In particular, you can suppress leading zeros with the FM format model modifier.
Without changing your NLS_TIMESTAMP_FORMAT you can see the same effect by using to_char() in the query. Try this:
select to_char(to_date('01-Feb-12', 'dd-Mon-yy'), 'FMdd/mm/yyyy hh24:mi:ss') from dual;
Output: 1/2/2012 0:0:0

How do I update the time in oracle sql?

I need a query to update a time in an appointment date by keeping the date but changing the time.
For example
10-Feb-2016 09:00:00
and i want to change it to 10-Feb-2016 10:00:00.
Update Appointment
set vdate = '10:00:00'
where vdate= '10-Feb-2016'
I get the "0 row has been updated'. Not sure if i'm missing something.
Thanks in advance.
You can use trunc() which sets the time part of a DATE (or TIMESTAMP) to 00:00:00, then add the 10 hours to it:
Update Appointment
set vdate = trunc(vdate) + interval '10' hour
where trunc(vdate) = DATE '2016-02-10'
This would change all rows that have a date 2016-02-10. If you only want to do that for those that are at 09:00 (ignoring the minutes and seconds) then just add one hour to those rows
Update Appointment
set vdate = trunc(vdate) + interval '1' hour
where trunc(vdate, 'hh24') = timestamp '2016-02-10 09:00:00'
trunc(vdate, 'hh24') will set the minutes and seconds of the date value to 00:00, so that the comparison with 2016-02-10 09:00:00 works properly.
Unrelated, but: do not rely on implicit data type conversion. '10-Feb-2016' is a string value, not a DATE literal. To specify a date either use an ANSI DATE literal (as I have done in the above statement) or use the to_date() function with a format mask to convert a string literal to a proper date value.
Your statement is subject to the evil implicit data type conversion and will fail if the SQL client running the statement uses a different NLS setting (it will fail on my computer for example)
If what you want to do is add an hour to a date, then you can do:
Update Appointment
set vdate = vdate + 1/24
where vdate = to_date('10/02/2016 09:00', 'dd/mm/yyyy hh24:mi');
since in Oracle, date differences are measured in number of days, and an hour is 1/24th of a day.
If what you want to do is specify an exact time (e.g. to 10:25:48), then you could do the following instead:
Update Appointment
set vdate = trunc(vdate) + 10/24 + 25/(24*60) + 48/(24*60*60)
where vdate = to_date('10/02/2016 09:00', 'dd/mm/yyyy hh24:mi');
Bear in mind that these updates will update all rows that have a date of 10th Feb 2016 at 9am. You'd need to change your query's where clause if you wanted to specify a more specific row or set of rows.
Try like this.
UPDATE MyTable
SET MyDate = DATEADD(HOUR, 4, CAST(CAST(MyDate AS DATE) AS DATETIME))
or
UPDATE MyTable
SET MyDate = DATEADD(HOUR, 4, CAST(FLOOR(CAST(MyDate AS FLOAT)) AS DATETIME))

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).

SSRS - Oracle DB, Passing Date parameter

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.

Resources