I'm calling Oracle procedures that have argument date. How can I specify the format of the date so it is recognized by oracle no matter what kind of globalization it uses ?
E.g.
create or replace procedure MyProc(p_valid_date in date) ...
The client calls the proc, how should I specify p_valid_date as a string ... ?
If I use, e.g., '01212014', i.e. DDMMYYYY then it won't work with US settings. If I use US settings, it won't work in UK. Etc.
In SQL Server, I'd use YYYYMMDD format which is culture invariant but I can't find anything about culture invariant format in Oracle documentation and all kind of formats that I have tried seem to be always bound to the culture.
UPDATE
I don't want to use functions because my client does pure procedure call. That's a limitation of my client. I know that I could change the argument into string and then convert the string using to_date inside the procedure but that seems like a pretty poor design.
Thank you
ISO date format is "invariant" you are looking for:
SQL> alter session set nls_date_format='dd/mon.yyyy';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-----------
07/nov.2014
SQL> select to_char(DATE '2014-12-31') from dual;
TO_CHAR(DAT
-----------
31/dec.2014
You can use this notation: DATE '2014-12-31'
Related
If I try a query as
select * from hr.employees
by sqldeveloper I have an output where the field HIRE_DATE is display so:
21-GIU-07
The data format is in according of the land (Italy)
If I use Tora or Toad (an old version) for the query the same row and the same field is display as
HIRE_DATE 2007-06-21 00:00:00
I am not undestand why there is time value in the field HIRE_DATE. In the example is 0 but I have found table where the time is set.
Why Tora/Toad show the time too and not in sqldeveloper ?
Thanks in advance anyone wants to answer
There is a parameter called NLS_DATE_FORMAT which specifies the default format for date data type.
The NLS_DATE_FORMAT has an order of overriding precedence, and tool specific NLS paramter settings will override it. That is the reason why two different tools has different outputs.
This is the most usual order of overriding precendence :
NLS_DATE_FORMAT is in the database initialization parameters, will be overriden by,
Settings of OS environment variable on the client machine, will be overriden by,
NLS parameter setting at session level with ALTER SESSION statements, will be overriden by,
to_date and to_char functions at the sql statement level.
Having said all that, in your situation, you need to check the NLS_DATE_FORMAT in both the tools.
Last but most important, check this link and learn more about the NLS_DATE_FORMAT.
I have inserted into a table in Oracle. My implementation without PLSQL would be:
SELECT to_date('1900-01-01','YYYY-MM-DD') + (rownum - 1) AS DT_CAL,
rownum AS NUM_JOUR
FROM dual
CONNECT BY to_date('1900-01-01','YYYY-MM-DD') + (rownum - 1) <=
to_date('2000-12-31','YYYY-MM-DD')
result is: 05/28/1900, not 1900-05-28. Can you help me understand what the problem is?
The DATE data type does not have a format; Oracle stores it as either 7- or 8-bytes and it is not until it is passed to a client program (i.e. SQL/Plus, SQL Developer, Toad, Java, Python, etc) and that client program formats it according to whatever rules it has that the date gets a format.
If you are using SQL/Plus or SQL Developer then it will use the NLS_DATE_FORMAT session parameter to format the date. You can change this using:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
(Be aware that this will only change the format in the current session and will not change it for any other sessions/users.)
If you want to give the date a particular format then you will need to convert it to a string.
to_date() takes your string parameter, matches it to the format you provide in the second parameter, and constructs a date field from it. The date field isn't using the format you provided in the second parameter - in fact it'll be stored using some internal data representation that has no format at all (a number, in all likelihood).
To present a format back out in the results from a date field, you can either:
Have the client executing the query set the NLS parameters (at session level) to provide a localized format, with an ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD'; statement), or
Use to_char(..., 'YYYY-MM-DD') around your existing field to turn the date back into a string formatted the way you want to have it. Where you replace ... with your current column definition in the select.
Approach #1 is already happening, as there'll already be an NLS_DATE_FORMAT set that is producing the current format, but it's with a format you don't want, so if you can control it and change it there, you can do it that way. If you can't and you must have the format a single consistent other way, then #2 could be the way to go.
I'm calling an Oracle procedure with this code:
begin
PPT2000_AGG_HOURLY.RUNDURATION_HOURLY(4, to_date('01112014', 'DDMMYYYY'), 20);
end;
/
My problem is the date format. On one PC the procedure calculates all fine with the result for the date 01.11.2014 00:00.
On the other PC (same version of Oracle SQL Developer) the procedure returns
0 for the calculation and for the date 01.11.2014
So something seems to be different in converting the date and I don't know why. I tried it with a third PC and get also the return of 01.11.2014.
The PC which gives the correct result has the same operating system (WIN7 German) and the same version of the Oracle SQL Developer. Also the same Oracle database.
So how could this be possible?
Update Solution:
Thanks for the answers, I changed the NLS-Settings from DD.MM.RR to DD.MM.RR HH24:MI and now it works :)
You should handle the display format in the code, and not depend on the client's NLS_DATE_FORMAT. You can't expect 1000 users to change their local NLS settings in their GUI based client tools.
A date doesn't have a format. What you see, is just for display depending on the locale-specific NLS_DATE_FORMAT of the client.
And the NLS_DATE_FORMAT could be overridden at different levels. If you don't want to depend on the client's NLS settings, then always use TO_CHAR with desired format mask to make sure it is overridden at individual statement level.
Remember, for diaplaying DATE values, always use TO_CHAR with desired format. To do date arithmetic, use TO_DATE to convert a literal into DATE.
For example,
TO_CHAR(date_column, '<desired_format>')
It will override the locale-specific NLS_DATE_FORMAT at statement level.
See this similar answer for more understanding.
If you really have a constant date then use the Oracle DateTime literal. It works every time and it's independent of the NLS_DATE_FORMAT:
begin
PPT2000_AGG_HOURLY.RUNDURATION_HOURLY(4, DATE '2014-11-01', 20);
end;
/
Check the NLS preferences in SQL Developer to see if there is a mismatch. Go to Preferences->Database->NLS. You can also override these settings on a per session basis if you want.
This question already has an answer here:
comparing date with a predefined format pl sql
(1 answer)
Closed 9 years ago.
Oracle 11g documentation says that default date format is DD-MON-YYYY, which means that if I insert date to a date column using:
insert into table t values(1, '02-JAN-2013')
and then select it
select * from t
it should display as 02-JAN-2013 whereas in reality it displays date as 01/02/2013.
Why his discrepancy or am I missing something.
Ref. http://infolab.stanford.edu/~ullman/fcdb/oracle/or-time.html
FYI. I am using PL/SQL Developer for this experiment.
There isn't really a default date format for the product, the reference guide states that the default for NLS_DATE_FORMAT at system level is based on NLS_TERRITORY. Though this says the 'standard' is `DD-MON-RR', and I think that's what you get if you don't specify a value at database level, at least on the platforms I've worked on.
When you create a new database the initialisation parameters can include a specific NLS_DATE_FORMAT, and that can be changed later too.
But the system-level NLS_DATE_FORMAT can be overridden by the client, the session, or in a TO_CHAR call. You can look in v$nls_parameters to see the system value, and nls_session_parameters to see your current session value. You can change that with alter session if you want to.
I'm pretty sure you'll find that PL/SQL Developer is setting the session NLS_DATE_FORMAT to MM/DD/YYYY somewhere in its preferences.
Generally it's better to not rely on that value at all, and always use an explicit format mask for display, e.g. TO_CHAR(<column>, 'YYYY-MM-DD HH24:MI:SS').
There's more on NLS_DATE_FORMAT in the globalisation guide here and here; and a bit about date display here; and an overview of the date format model elements here
It depends of NSL_DATE_FORMAT that depends of NLS_TERRITORY
Give a look to: http://docs.oracle.com/cd/B19306_01/server.102/b14237/initparams122.htm
I am using Oracle10g database in which a table contains a Column with Date DataType. I am using the following query to get the record:
select to_char(START_TIME, 'YYMMDD HH24:MI:SS') from table;
So from above query, the result will be of type VARCHAR. I have tried to_Date() method but resulted in displaying only DATE. Can i convert VARCHAR to DATETIME format? The result should be of type DATETIME. Please help me how to resolve this problem.
an Oracle date contains both date and time so you can consider it a datetime (there is no datatype of datetime in Oracle). how is DISPLAYS when you select it is entirely up to your client. the default display setting is controlled by the NLS_DATE_FORMAT parameter. If you're just using the date in your pl/sql block then just assign it into a date datatype and select into that variable without to_char and it will work just fine and contain whatever time component is present in your table.
to control the display, for example using nls_date_format:
SQL> select a from datetest;
A
---------
19-FEB-13
SQL> alter session set nls_date_format='YYMMDD HH24:MI:SS';
Session altered.
SQL> select a from datetest;
A
---------------
130219 07:59:38
but again, this is only for display.
Oracle's Date type fields contain date/time values, therefore converting it to Datetime does not make any sense (it's already datetime)
Read more about oracle date types here
Yeah the Date datatype will meet your needs but you will have to jump through some hoops every time to get the exact time out of it. Definitely use the Timestamp datatype.