Oracle PL/SQL : to_date() format not considered - sql

When I execute this in PL/SQL Developer :
SELECT to_date('29/03/17 14:05','DD/MM/RR HH24:MI') FROM dual;
Here's what I get :
3/29/2017 2:05:00 PM
How is this possible ? I use HH24 but it seems like it's HH that's being used instead. The day and month are also not in the format I entered.

What you are doing with the to_date method is parsing the string into a date object. If you then want to output the date object as string with a different format you should use the to_char method.
Example:
SELECT to_char(
to_date('29/03/17 14:05','DD/MM/RR HH24:MI'),
'DD/MM/RR HH24:MI'
) FROM dual;

Ok, conceptual excercise coming up
Which of these dates represents the 1st January 2017?
01/01/2017
2017-01-01
01-JAN-2017
That's right, all of them. The date datatype is not a format, it stores the value of the date, not how it appears.
If using Oracle, adjust your NLS_DATE_FORMAT to match your expectation, but again, this is just how the system will display the date, not how it stores it.

(N.B. This answer is more to give more clarity to the other answers but it's too long for a comment.)
Oracle stores DATEs (and TIMESTAMPs etc) in its own specific format. Us humans represent dates in a variety of different formats and we deal with strings. Even us humans can get confused over what a date string represents, given no context - e.g. 03/09/2017 - is that the 3rd of September, 2017 or the 9th of March 2017?
So, when you pass a date into Oracle, you need to convert it into Oracle's date format by passing a string in and telling Oracle what the date format of that string is. This can be done using to_date() or via the DATE literal (which is always in yyyy-mm-dd format).
Conversely, when you want to read something that's stored in Oracle's DATE datatype, you need to tell Oracle how you want it to be displayed, which you can do by using to_char() with the appropriate format mask.
If you fail to explicitly convert the string-to-a-date or date-to-a-string, then Oracle uses the format specified in the NLS_DATE_FORMAT to decide how to do the conversion.
In your case, you didn't specify how you wanted your date to be displayed, so Oracle has to use to_char() along with the format contained in your NLS_DATE_FORMAT in order to display the date as a string, and clearly that's different to the format you passed the date-string in as.

Related

How to insert date in SQL date type column?

I have a table with date type column.
I am trying to insert date in it:
But I get an error:
Please give me to make the correct query to put the date
Easy fix::
INSERT INTO t(dob) VALUES(DATE '2015-12-17');
Assuming this is an Oracle question based on the ORA-01843 error message, the problem appears to be in the date formatting as the error suggests.
In the provided example does the date '6-3-2012' mean '3 March 2012' or 'June 6, 2012?' The answer lies within the NLS_DATE_FORMAT parameter.
Out of the box, the Oracle date format is DD-MON-RR. So your corrected date format is either '03-MAR-12' or '06-JUN-12.' If the NLS_DATE_FORMAT has not been changed.
Never try to insert a string into a date column! If you have a string, use the to_date function with an explicit date format (and use 4 digit dates).
Relying on nls_date_format to implicitly convert your strings is just asking for trouble (like you just did), it can very easily change, even some apps will change it themselves.
The date literal (date '2015-12-17' https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#BABGIGCJ) always uses the same date format so that might be okay for ad hoc statements but you need to be aware that it is literal by name and literal by nature. They don't support bind variables so you will end up writing unshareable SQL to chew up your shared pool.

Searching Between Two Dates With A Specific Format

So I have a table where the dates are formatted as such: 15-Jan-13
That would obviously be January 15th, 2013.
The problem is, when I try to search a date range between 01/01/2014 and SYSDATE, it errors out.
Does anyone know the proper way in which I would format this based off of how my dates are stored?
FYI my raw data is stored as: 15-JAN-13 02.23.27.000000000 PM -05:00
I'm converting it as
TRUNC(variable_name)
Given that you are asking about "sysdate" then I would assume you are using Oracle. It would also seem that the the column with the dates are not actual in the date format. Best option would be to change the column to a date type. If for some reason that isn't an option, the next best thing to do is to translate the text to a date as part of your query:
select *
from foo
where to_date(your_column, 'dd-Mon-yy') between to_date('01/01/2014', 'mm/dd/yyyy')
and sysdate
Note that to_date is expecting it's second argument to match the structure of the date specified so '01/01/2014' would match the date format 'mm/dd/yyyy' and your_column (value: '15-Jan-13') would match a different format 'dd-Mon-yy'. Once everything is translated to a date, Oracle can perform appropriate date comparisons.
DISCLAIMER: The translation of your_column to a date using to_date means that if an index is defined on your_column, it won't be used. If this is a large table you can expect sub-optimal performance. One additional reason to change the column data type to a date.

Convert date format in Oracle

I have a date format 2011-01-06T06:30:10Z in Excel.I want to just load the date part into a table from excel.How do I get the date part from it.
i.e. 2011-01-06
Thanks
Try this:
select cast(TO_TIMESTAMP_TZ(REPLACE('2011-01-06T06:30:10Z', 'T', ''), 'YYYY-MM-DD HH:MI:SS TZH:TZM') as date) from dual
I think, some more explanation is needed.
Loading data into database is one part, and displaying it after fetching is another part.
If you have loaded the data into database, then all you need to do is use TRUNC. It will truncate the time portion and will display only the date portion.
A DATE always has a datetime part together. TIMESTAMP is an extension to the DATE type. And what you see the date looks like is not the way it is stored in database. The format is for we human beings to understand. A date is stored in 7 byte in internal format.
More information Based on OP's question via comments
NEVER store a DATE as VARCHAR2 datatype. A date is not a string literal. Oracle provides lot of FORMAT MODELS to display the datetime the way you want. Sooner or later, you will run into performance issues due to data conversion. Always use explicit conversion to convert a literal to a perfect DATE to compare it with other date value.

How do I display DATE in 'DD MON YYYY' format?

I am a newbie for Oracle database programming and I wish to INSERT date (also display) in 'DD MON YYYY' format. (PS: This only involves INSERT event). Which data type (DATE or TIMESTAMP) is the most suitable option for me in order to accomplish this format? How was I supposed to do that? Thanks.
A DATE column does not have any format.
So the format that you use when inserting or updating data is irrelevant for displaying that data (that's one of the reasons why you should never store a date in a VARCHAR column).
Any formatted output you see for a DATE column in your SQL tool (e.g. SQL*Plus) is applied by that tool. It is not part of the data stored in that column.
When providing a date literal you should either use the to_date() function with an explicit format mask:
insert into some_table (some_date_column)
values (to_date('27-06-2014', 'dd-mm-yyyy'));
I also do not recommend using formats with written month names (27-JUN-2014) when supplying a date literal because they also depend on the NLS settings of the client computer and might produce (random) errors due to different languages. Using numbers only is much more robust.
I prefer to use ANSI date literals because it's a bit less typing:
insert into some_table (some_date_column)
values (DATE '2014-06-27');
The format for an ANSI date (or timestamp) literal is always the ISO format (yyyy-mm-dd).
When you select your data you can display the date in whatever format you like. Either by using the to_char() function (e.g. when using a SQL tool) or using functions from your programming language (the preferred way to use inside an application):
select to_char(some_date_column,'dd-mon-yyyy')
from some_table;
Note that the DATE data type in Oracle (despite it's name) also stores the time. a TIMESTAMP does the same thing only with a higher precision (it includes milliseconds, whereas the DATE data type only stores seconds).
To insert a record,
INSERT INTO TABLE_NAME (DATE_FIELD) VALUES (TO_DATE ('27-JUN-2014', 'DD-MON-YYYY');
It is advisable to use DATE data-type until and unless you need the date's accuracy to be till milli seconds. In your case, go with DATE datatype and TIMESTAMP is not necessary
To select a record,
SELECT TO_CHAR(DATE_FIELD, 'DD-MON-YYYY') FROM TABLE_NAME;
In genral, remember this:
TO_DATE is a function used to convert a string(CHAR) TO DATE
TO_CHAR is a function used to convert a DATE to a string(CHAR)
In this scenario date datatype will be suitable for you, and for the desired format you should try like this:-
INSERT INTO TABLE_NAME(DATE_COLUMN) VALUES('27-JUN-2014');
Hope this can help you.

creating table in Oracle with Date

I want to create a table in Oracle 10g and I want to specify the date format for my date column. If I use the below syntax:
create table datetest(
........
startdate date);
Then the date column will accept the date format DD-MON-YY which I dont want.
I want the syntax for my date column to be MM-DD-YYYY
Please let me know how to proceed with this.
Regards,
A DATE has no inherent format. It is not simply a string that happens to represent a date. Oracle has its own internal format for storing date values.
Formats come into play when actual date values need to be converted into strings or vice versa, which of course happens a lot since interactively we write dates out as strings.
The default date format for your database is determined by the settings NLS_DATE_FORMAT, which you probably have set to DD-MON-YYYY (which I believe is the default setting for American English locales). You can change this at the database level or for a single session for convenience, but in general it is safer programming practice to be explicit so that you don't get errors or, worse, wrong results if your code is run in a different environment.
The simplest way to specify a date value unambiguously is a date literal, which is the word 'date' followed by a string representing the date in YYYY-MM-DD format, e.g. date '2012-11-13'. The Oracle parser directly translates this into the corresponding internal date value.
If you want to use a different format, then I recommend explicitly using TO_CHAR/TO_DATE with your desired format model in your code. Examples:
INSERT INTO my_table (my_date) VALUES ( TO_DATE( '11-13-2012', 'MM-DD-YYYY' ) );
SELECT TO_CHAR( my_date, 'MM-DD-YYYY' ) FROM my_table;
dates rdo not have a format like you're suggesting. they are stored internally as a 7 byte number. to format the date when selecting, please use TO_CHAR(yourdatefield, 'format')
where formats are all shown here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34924
eg to_char(startdate, 'mm-dd-yyyy')