Timezone Region Not Found (Oracle 11g) - oracle

Does anyone know why the first query would be causing this error to be thrown while the second one works?
ORA-01882: timezone region not found 01882. 00000 - "timezone region %s not found"
Causes Error: SELECT SYSTIMESTAMP AT TIME ZONE (SELECT t.TIME_ZONE FROM SOME_TABLE t WHERE t.TIME_ZONE = 'America/Denver' AND ROWNUM = 1)
FROM DUAL
Works Correctly: SELECT SYSTIMESTAMP AT TIME ZONE (SELECT 'America/Denver' FROM SOME_TABLE t WHERE ROWNUM = 1)
FROM DUAL
Note: This is running on a Oracle Database 11g Release 11.2.0.4.0 - 64bit db. I've verified both queries work correctly on another db with the same db version. Not sure what else could be causing this.

To summarize the root cause, it was related to t.TIME_ZONE's data type (which was NVARCHAR2). Here's an example showing that NVARCHAR2 time zone names are not supported in 11g:
Does not work: SELECT SYSTIMESTAMP AT TIME ZONE CAST( 'America/Denver' as NVARCHAR2(80)) FROM DUAL
Works: SELECT SYSTIMESTAMP AT TIME ZONE CAST( 'America/Denver' as VARCHAR2(80)) FROM DUAL
Wrapping t.TIME_ZONE in TO_CHAR() fixed the problem.

Related

Change Jasper Reports language?

I'm using jaspersoft server to print some pdf files.
The server is connected to an Oracle Database through oracle.jdbc.OracleDriver.
It's configured as follows :
The server is working nicely. However when running a report that has a query like :
select to_char('Month', sysdate) from dual;
The result is always in english.
Is it possible to change Jaspersoft server connection to Oracle and make it work in another language ?
Thanks.
Regards,
SELECT statement you posted is invalid. It won't work at all:
SQL> select to_char('Month', sysdate) from dual;
select to_char('Month', sysdate) from dual
*
ERROR at line 1:
ORA-01722: invalid number
When fixed:
SQL> select to_char(sysdate, 'Month') from dual;
TO_CHAR(
--------
Studeni
How to use another language (as result I previously got is in Croatian; let's try English):
SQL> select to_char(sysdate, 'Month', 'nls_date_language = english') from dual;
TO_CHAR(S
---------
November
SQL>

Date operations in Oracle

I'm trying to run this queries (Oracle 12c):
SELECT trunc(sysdate) - '25-SEP-18' FROM dual;
SELECT 1 FROM dual WHERE trunc(sysdate) = '04-SEP-19';
CREATE TABLE my_table (order_date date);
INSERT INTO my_table (order_date) VALUES ('04-SEP-19');
I expect implicit conversion and everything is good with the 2 last queries, but for the first i get error ORA-01722: invalid number. NLS_DATE_FORMAT = 'DD-MON-RR'. What is the problem?
The question is WHY is does not work? I didn't find any explanations in documentation.
The documentation has a section on Datetime/Interval Arithmetic which explains what is allowed. The table shows that arithmetic is only allowed between dates, timestamp, intervals and numbers. When you do:
SELECT trunc(sysdate) - '25-SEP-18'
you are trying to subtract a string from a date, which isn't possible. Oracle 'helpfully' tries anyway and interprets the string as a number, effectively doing:
SELECT trunc(sysdate) - to_number('25-SEP-18')
which understandably throws the error you see, "ORA-01722: invalid number". As already said, you should explicitly convert your string to a date:
SELECT trunc(sysdate) - to_number('25-SEP-18', 'DD-MON-RR')
or preferably with a four-digit year, and since you're using a month name it's safer to specify the language that is in:
SELECT trunc(sysdate) - to_number('25-SEP-2018', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH')
or more simply, if it's a fixed value, with a date literal:
SELECT trunc(sysdate) - DATE '2018-09-25'
I expect implicit conversion
You should not rely on implicit conversion, particularly where that is influenced by session NLS settins. As well as the date language I already mentioned, someone else running your statement could have a different NLS_DATE_FORMAT setting which could lead to errors or more subtle data mismatches or corruption; e.g.
alter session set nls_date_format = 'DD-MON-YYYY';
SELECT trunc(sysdate) - DATE '2018-09-25' FROM dual;
TRUNC(SYSDATE)-DATE'2018-09-25'
-------------------------------
344
SELECT trunc(sysdate) - to_date('25-SEP-18') FROM dual;
TRUNC(SYSDATE)-TO_DATE('25-SEP-18')
-----------------------------------
730831
SELECT 1 FROM dual WHERE trunc(sysdate) = '04-SEP-19';
no rows selected
CREATE TABLE my_table (order_date date);
INSERT INTO my_table (order_date) VALUES ('04-SEP-19');
The second query gets a much bigger value than expected; and the third gets no rows back from dual.
Looking at the implicitly converted date shows you why:
SELECT to_char(order_date, 'SYYYY-MM-DD HH24:MI:SS') FROM my_table;
TO_CHAR(ORDER_DATE,'
--------------------
0019-09-04 00:00:00
With a YYYY mask (and no FX modifier) a 2-digit year value like 19 is converted as 0019, not 2019. That sort of problem could go unnoticed for some time, giving you incorrect results in the meantime.
If the session's format mask had RRRR or - as you have - RR then it would be interpreted as 2019; but the point is that you usually have no control over the settings in another session that runs your code later.
You can also cause performance issues or errors by creating implicit conversions where you didn't expect, or where they behave in a way you didn't expect. Not in this example - "When comparing a character value with a DATE value, Oracle converts the character data to DATE" - but it still comes up. It's better to avoid the possibility.
When dealing with strings with dates in them you should use the to TO_DATE command, otherwise Oracle may not always figure out that the string contains a date.
SELECT trunc(sysdate) - TO_DATE('25-SEP-18') FROM dual;
Even better is to indicate the format of the date within the string
SELECT trunc(sysdate) - TO_DATE('25-SEP-18','DD-MON-RR') FROM dual;

Oracle Timezone - Brazil 2018 change

Similar to the issue described in the post:
But for Oracle database itself.
There's a database running on machine whose timezone/clock is set to Brazil/East/Brasilia/SaoPaulo time. We use this query to get the database clock and convert it to GMT:
SELECT to_char(sysdate, 'YYYY-MM-DD HH24:MI') AS MY_SYSDATE
, TO_CHAR(FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'America/Sao_Paulo') AT TIME ZONE 'GMT'
, 'YYYY-MM-DD HH24:MI') as gmt_brazil_east
, TO_CHAR(FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'Etc/GMT+3') AT TIME ZONE 'GMT', 'YYYY-MM-DD HH24:MI') as gmt_03
FROM DUAL
WHERE 1=1
;
Every since this past weekend, the value for the field "gmt_brazil_east" is wrong... I suspect because our Oracle hasn't been updated to reflect the recent change regarding when Brazil changes daylight-savings... Described here:
Though our database version is recent, it is Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
I tried finding info on this similar to the Java-related post above, but could not... Does anyone know where I can find which version/patch of Oracle has this change to Brazil timezone corrected?
Don't know if you have access to Oracle Support, but there is a patch to DSTv32 for Oracle 11.2.0.3.0 until 18.3 available.
Have a look here Brazil to Start DST on November From 2018 Onwards- Impact on Oracle RDBMS (Doc ID 2331560.1)

Toad SQL Issue for Timestamp without Seconds

I am executing the following sql in Toad. Oracle is RDBMS
I only need Date in yyyymmdd HH24:mi, but I get Date only as shown below
alter session set nls_date_format = 'DD/MM/YYYY HH24:MI';
SELECT to_date('22/07/1980 00:00','dd/mm/yyyy hh24:mi') dt FROM dual
22/07/1980
Required Output
22/07/1980 00:00
You are looking for to_char() -- you want to return the date as a string, not a date. As far as I know, the date is returned without the time, and I don't think the NLS changes that.
So:
SELECT to_char(to_date('22/07/1980 00:00', 'dd/mm/yyyy hh24:mi'
), 'DD/MM/YYYY HH24:MI'
) as dt
FROM dual
I have used sql plus and spooled the file instead of Toad, used NLS Date format conversion here, but as this is command based, wanted to use GUI based TOAD.

Informix timestamps in Oracle (via ODBC)

I need to select some values from an Informix database via Oracle ODBC. One of the columns is a timestamp, and when I just select it all I see in SQL*Plus is the date value. How do I get the time as well?
By default SQL*Plus will display the date in the format specified by the NLS_DATE_FORMAT system parameter (client side). You can alter this behaviour by setting the NLS_DATE_FORMAT appropriately. You can also explicitly display the time data:
SQL> select sysdate from dual;
SYSDATE
-----------
05/10/2009
SQL> select to_char(sysdate, 'hh24:mi') from dual;
TO_CHAR(SYSDATE,'HH24:MI')
--------------------------
13:55

Resources