Computing date difference from within DevExpress - oracle

We use a third-party software that uses DevExpress for building reports. Normally on Oracle - I can get the difference in dates with ease by simply subtracting them:
TRUNC(sysdate) - TRUNC(a.birth_date) AS datediff
I used the same logic from within DevExpress:
CAST(CAST(CURRENT_DATE AS VARCHAR(9)) AS DATE) - CAST(CAST(a.birth_date AS VARCHAR(9)) AS DATE) AS datediff
But doing so gives me this error message:
Invalid cast from 'Decimal' to 'DateTime'. Couldn't store <35> in DATEDIFF Column.
Expected type is DateTime.
How do I fix this?
Notes:
There's a lot of casting going on here but that's just a work-around because TRUNC doesn't work so I'm basically just casting to a VARCHAR essentially removing the time portion and casting it back to a DATE field.
CURRENT_DATE is the equivalent of SYSDATE in the world of DevExpress.

Looks like the simplest solution is to cast the result to decimal.
CAST(CAST(CAST(CURRENT_DATE AS VARCHAR(9)) AS DATE) - CAST(CAST(a.birth_date AS VARCHAR(9)) AS DATE) AS DECIMAL) AS datediff

Related

Oracle TRUNC function doesn't work in perl

I try to insert the created field in my_table. The created field has a datetime type. In my_table the field my_created has a date format. So I try to TRUNC the created field. However I'm getting the error ORA-01830: date format picture ends before converting entire input stringwhile inserting the truncated value. It seems, that the time is still there but is reset to 00:00. how can I get only the date without time? It happens only in perl. I'm getting only date in toad.
Very simplified code looks like:
my $SQL="SELECT
TRUNC(CREATED),
FROM
DBA_OBJECTS";
my $sth = $db->prepare($SQL);
$sth->execute();
my $date = $sth->fetchrow();
$SQL = "INSERT INTO MY_TABLE
(MY_CREATED)
VALUES (?)";
my $stmt = $dbh_master->prepare($SQL);
$stmt->execute($date);
EDIT:
I found an ugly workaround and I'm executing it like this:
$stmt->execute(substr($date, 0, 10));
However maybe someone has a nicer solution.
How can I get only the date without time?
In Oracle, a DATE is a binary data type that is composed of 7 bytes representing: century, year-of-century, month, day, hour, minute and second. It ALWAYS has those binary components so if you want an Oracle DATE data type then you cannot get it without a time.
The Oracle DATE data type was released with Oracle version 2 in 1979 and predates the ANSI/ISO standard (of 1986, where a DATE does not have a time component) and Oracle has maintained backwards compatibility with their previous data types rather than adopting the ANSI standard.
If you use the TRUNC(date_value, format_model) function then it will set the binary components of the DATE, up to the specified format model, to the minimum (0 for hours, minutes and seconds, 1 for days and months) but it will NOT give you a data type that does not have a time component.
It happens only in perl. I'm getting only date in toad.
No, you are getting the entire 7 byte binary value in Toad; however, the user interface is only choosing to show you the date component. There should be a setting in the preferences that can set the date format in Toad which will let you see the entire date-time components.
Oracle SQL/Plus and SQL Developer use the NLS_DATE_FORMAT session parameter and Toad may also be able to use that.
If you want to get the value as a DATE then it will always have a time component (even if you set that time component to zeros using TRUNC).
If you want to get the date so that it is formatted in a way without a time component then you need to convert it to another data type and can use TO_CHAR to format it as a string:
SELECT TO_CHAR(CREATED, 'YYYY-MM-DD')
FROM DBA_OBJECTS
But then you will be returning a (formatted) string and not a DATE data type.

SSRS 2005 passing datetime parameter to Oracle

I have a SSRS 2005 report runs on a Oracle 9 database.
The report use this simple query to return a dataset
SELECT order_number FROM apps.oe_order_headers_all
WHERE ordered_date >= to_date(:start_date,'DD-MON-YYYY')
AND ordered_date < to_date(:end_date,'DD-MON-YYYY') +1
The parameters work fine if they are of type string in SSRS. E.g. 01-JAN-2014 for both start_date and end_date. But if changed to datetime the report returns nothing (if in string, the report returns many rows). I really want to use the date picker control of SSRS.
This is probably more of a SSRS thing than Oracle thing?
This is probably a date conversion issue, but I'm surprised it isn't either erroring, or returning the same data - at least for the example date you gave.
In your previous question you were entering a string, so adding the to_date() made sense. But if you're binding it as a date then you do not want those.
This is fine:
to_date(<string>,'DD-MON-YYYY')
But this:
to_date(<date>,'DD-MON-YYYY')
is really doing:
to_date(to_char(<date>,<NLS_DATE_FORMAT>), 'DD-MON-YYYY')
If your `NLS_DATE_FORMAT happens to be the same as the fixed format you supplied, then this is kind of OK as it's just a redundant conversion to a string and back. But if they are different then you'll get errors or incorrect results.
For example, if my NLS_DATE_FORMAT is MM/DD/YYYY' thento_date(sysdate, 'DD-MON-YYYY) gets anORA-01843: not a valid montherror, because it's trying to interpret28as the month and02` as the day.
So you just need to simplify it to:
SELECT order_number FROM apps.oe_order_headers_all
WHERE ordered_date >= :start_date
AND ordered_date < :end_date +1
Given the odd error you get from this, you could also try:
AND ordered_date < :end_date + interval '1' day
... but without understanding why the simpler +1 is erroring I'm not confident that will help. It doesn't seem to be following the normal datetime arithmetic rules. This is another possibility but should not be necessary:
AND ordered_date < CAST(:end_date AS DATE) + 1

Date as number in sql

When we type current date in Excel cell as 08-May-2013
Right click on the cell and in the format when i click number as category i get a number
Date-08-May-13
Formatted one-41402.00
So is there anyway i can get the same number in sql
I tried using this.
select to_char(sysdate,'J') from dual
But the output is 2456421
I understand that this is a Julian value
But can anyone help me in getting the output as that i am getting on excel i.e; 41402
The Windows version of Excel stores dates as serial numbers. 01-Jan-1900 is 1, 02-Jan-1900 is 2, etc. The Mac version used to use a different starting date; I don't know whether that's still the case.
The essential data you need is in simple date arithmetic.
select current_date, current_date - date '1900-01-01'
from dual;
That returns 41400.67037037037 for my current connection. Rounding up and adding 1 for fenceposting would return the number you're looking for, but I'd want to test that with multiple time zones and such before I'd swear by it.
A date in Excel is stored as a serial number, with 01-JAN-1900 as 1. Citation.
We can do arithmetic with dates in Oracle, so converting to an Excel date from Oracle would be:
trunc(sysdate) - to_date( '1900-01-01', 'yyyy-mm-dd')
I've tested this and infuriatingly it produces 41401 - because it's going from midnight. So obviously Microsoft are using a ceiling function to raise it to the next integer:
ceil (sysdate - to_date( '1900-01-01', 'yyyy-mm-dd') )

Oracle - Converting Date value TO_CHAR()

Ok, so I want to convert a date value to properly format my date for comparison, however, will converting my "DATE" data type to char affect indexing when comparing on that field? Can I resolve this by doing to_date(tochar())? Any advice on this would be greatly appreciated Thanks!
EDIT - Sorry for the lack of specifics.... basically I need to eliminate the time stamp from my date, I used the following and it appears to work TO_DATE(TO_CHAR, 'YYYY-MM-DD'),'YYYY-MM-DD'), mind you I don't know if this is good practice or not, but at least (or so I think) now it's comparing a DATE against a DATE, and not a string.
If you are doing a comparison, you should not be converting the date to a string. You should be comparing to another date. Otherwise, Oracle won't be able to use a non function-based index on the date column.
In general, that is, you're much better off coding
WHERE some_indexed_date_column = to_date( :string_bind_variable,
<<format mask>> )
rather than
WHERE to_char( some_indexed_date_column,
<<format mask>> ) = :string_bind_variable
Of course, if your bind variable can be a DATE rather than a VARCHAR2, that's even better because then you don't have to do any data type conversion and the optimizer has a much easier time of estimating cardinalities.
If you are trying to do some manipulation of the date-- for example, if you want to compare the day portion while omitting the time portion of the date-- you may want to use function-based indexes. For example, if you wanted to find all the rows that were created some time today
WHERE trunc( some_date_column ) = date '2011-11-04'
you could either create a function-based index on the date column
CREATE INDEX idx_trunc_dt
ON table_name( trunc( some_date_column ) )
or you could rewrite the query to do something like
WHERE some_date_column >= date '2011-11-04'
AND some_date_column < date '2011-11-05'
You should compare dates as dates, not as strings. If comparing a date to a string, convert the string to a date to compare.
IMO, you should convert your comparison value to the format stored in the database. Otherwise, you will need to create a function based index on the DATE column to take advantage of indexing. So, if you have an input character date of, say, 11/4/2011, you could compare it in a where clause thusly:
SELECT ...
FROM your_table
WHERE the_date_column = TO_DATE('11/4/2011','MM/DD/YYYY');

Oracle Date formatting "2009-02-13T11:46:40+00:00"

I've had some brilliant help before and I'm hoping you can get me out of a hole again.
I've got a date coming in from a web service in this format:
2009-02-13T11:46:40+00:00
which to me looks like standard UTC format.
I need to insert it into an Oracle database, so I'm using to_date() on the insert. Problem is, I cant get a matching formatting string for it and keep getting "ORA-01861: literal does not match format string" errors.
I know its a fairly trivial problem but for some reason I cannot get it to accept the right format string. Any help appreciated.
Thanks :)
Gareth
You can directly convert it to a TIMESTAMP_WITH_TIME_ZONE datatype.
select
to_timestamp_tz('2009-02-13T11:46:40+00:00','YYYY-MM-DD"T"HH24:MI:SSTZH:TZM')
from
dual
TO_TIMESTAMP_TZ('2009-02-13T11:46:40+00:00','YYYY-MM-DD"T"HH24:MI:SSTZH:TZM
---------------------------------------------------------------------------
13-FEB-09 11.46.40.000000000 AM +00:00
(I'm assuming the input string is using a 24-hour clock since there is no AM/PM indicator.)
If you want to convert that to a simple DATE, you can, but it will lose the time zone information.
SELECT CAST(TO_TIMESTAMP_TZ(REPLACE('2009-02-13T11:46:40+00:00', 'T', ''), 'YYYY-MM-DD HH:MI:SS TZH:TZM') AS DATE)
FROM dual
To import date in specified format you can set nls_date_format.
Example:
alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS'
This way your SQL statements can be shorter (no casts). For various mask look at Datetime Format Models

Resources