The operative setting for day of week is NLS_TERRITORY
.
How to produce the same result of to_char() on the same DB instance, but from different sessions?
Frage
I have a small utility function that calculates the day of week from a given date:
select to_number(to_char(to_date('20130330', 'YYYYMMDD'),'D')) from dual;
Executing this statement on the same database instance, but from two different machines it produces two different results!
The question is: how to modify the code in order to get the same result on two different PC but using the same database instance?
Details
The result is 6 when I start a session from my pc with these nls_session parameters:
select * from nls_session_parameters;
NLS_LANGUAGE HUNGARIAN
NLS_TERRITORY HUNGARY
NLS_CURRENCY Ft
NLS_ISO_CURRENCY HUNGARY
NLS_NUMERIC_CHARACTERS ,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT RR-MON-DD
NLS_DATE_LANGUAGE HUNGARIAN
NLS_SORT HUNGARIAN
NLS_TIME_FORMAT HH24.MI.SSXFF
NLS_TIMESTAMP_FORMAT RR-MON-DD HH24.MI.SSXFF
NLS_TIME_TZ_FORMAT HH24.MI.SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT RR-MON-DD HH24.MI.SSXFF TZR
NLS_DUAL_CURRENCY Ft
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
The same database instance gives different result: 7 by starting a session from a different pc which has these session paramters:
PARAMETER VALUE
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
For me the correct result is 7, but it must be provided on my PC. I've tried the following without success:
- Altered the NLS_LANGUAGE to AMERICAN
- Used to_char() with the optional nls_language parameter
Any suggestions?
Lösung
Andere Tipps
If you can issue an alter session
then NLS_TERRITORY is probably the way to go, as @JoachimIsaksson says. But if you can't, then unfortunately TO_CHAR()
doesn't support modifying it on the fly via its optional nlsparms
argument.
You could brute-force it as a last resort, e.g. in a Hungarian session:
alter session set nls_language = 'HUNGARIAN';
select to_char(to_date('20130330', 'YYYYMMDD'), 'DY') as hungarian,
to_char(to_date('20130330', 'YYYYMMDD'),
'DY', 'NLS_DATE_LANGUAGE=AMERICAN') as american
from dual;
HUN AME
--- ---
SZO SAT
select case to_char(to_date('20130330', 'YYYYMMDD'),
'DY', 'NLS_DATE_LANGUAGE=AMERICAN')
when 'SUN' then 1 when 'MON' then 2 when 'TUE' then 3
when 'WED' then 4 when 'THU' then 5 when 'FRI' then 6
when 'SAT' then 7
end as american
from dual;
AMERICAN
----------
7
... which is ugly but avoids any side-effects from changing the session. And you could turn it into a function if this is going to be an issue in more than one place, of course.
For the International convention, just use trunc(date)-trunc(date,'IW')+1 If you prefer US convention, it is trunc(date+1)-trunc(date+1,'IW')+1.