Oracle Data type convert - sql

There are two columns that have created which data type is Date, TimeStart and TimeEnd in my table (EventPlanLine). Well, the insert data is below shows:
Insert into EVENTPLANLINE (TIMESTART,TIMEEND)
values (to_date('25-OCT-18 8:00:00','DD-MON-RR HH24:MI:SS'),
to_date('25-OCT-18 17:00:00','DD-MON-RR HH24:MI:SS'));
Result:
25-OCT-18, 25-OCT-18
Forgive me about I only pick up those two columns data insertion to display. The result of the data presentation in the column shows DD-MON-RR format without time. Here is the question, how could the data presents with DD-MON-RR HH24:MI:SS format. I have checked from online resources, I could change NLS_DATE_FORMAT from Oracle, yes, it does and with time as below shows
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-RR HH24:MI:SS'
But the all tables which data type is Date have changed in the database. So is there a solution could change one table date type rather entire database?

A date column does not have a human-readable format; there is an internal representation and the client decides how to display the results (usually based on NOS_DATE_FORMAT), unless you explicitly format a column in your query with to_char().
But the all tables which data type is Date have changed in the database
No, your client is using that setting to display the dates as formatted strings. Notign has changed in the database.
So is there a solution could change one table date type rather entire database?
No, you can't set a format for a column in a table - they are just dates.
All you can do is explicitly format as part of your query; each date can then be formatted differently. Rather contrived but to demonstrate:
alter session set nls_date_format = 'DD-Mon-RR';
select
timestart,
timeend,
to_char(TIMESTART, 'YYYY-MM-DD HH24:MI:SS') as timestart_2,
to_char(TIMEEND, 'FMDay DD/Mon/YYYY HH:MI AM', 'NLS_DATE_LANGUAGE=ENGLISH') as timeend_2
from EVENTPLANLINE;
TIMESTART TIMEEND TIMESTART_2 TIMEEND_2
--------- --------- ------------------- ---------------------------
25-Oct-18 25-Oct-18 2018-10-25 08:00:00 Thursday 25/Oct/2018 5:0 PM
If the result format matters then don't rely on NLS formats as someone else running your code might have different settings in their session. (And as a related note, don't rely on implicit conversions of strings to dates - you aren't here but they often go together...)

Related

TO_UTC_TIMESTAMP_TZ not returning Month name [duplicate]

I firstly run the following command, and get the following result:
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 10:21:40
This is the format I want to have a TIMESTAMP object stored in.
When I convert it back though, it does not come in the format I want:
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 10.21.40.000000000 AM
In fact, it changes 2018 to be at the end, sets 07 to be "JUL" and the 10 is now at the front. Also the time is separated by dots, has many 0's and an AM.
How can I fix this? I am new to SQL development so I am not sure about the formatting.
Thank you so much
As #Gordon said, timestamps (and dates) are not stored in a format you would recognise Oracle uses an internal representation that you never really need to know about or examine (but it is documented if you're interested in that sort of thing).
When you query a timestamp it is displayed using your client's NLS settings, unless you have a client that overrides those. I can set my session up to match what you are seeing:
alter session set nls_timestamp_format = 'DD-MON-RR HH.MI.SS.FF AM';
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 15:37:31
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 03.37.31.000000000 PM
And I can change it see what you want to see:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHA
-------------------
2018-07-10 15:37:32
But all you are doing is converting from a timestamp with time zone (which is what systimestamp is) to a string and then back to a timestamp. You are losing the time zone portion, and any fractional seconds; which you could also do with a cast:
select cast(systimestamp as timestamp(0)) from dual;
CAST(SYSTIMESTAMPAS
-------------------
2018-07-10 15:37:32
You can see the timezone and fraction seconds with your default timestamp_tz format:
select systimestamp from dual;
SYSTIMESTAMP
------------------------------------
2018-07-10 15:37:33.776469000 +01:00
and change it with a different alter:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM';
select systimestamp from dual;
SYSTIMESTAMP
------------------------------
2018-07-10 15:37:34.070 +01:00
Which isn't entirely relevant if you're really talking about storing timestamps in a table, but shows that there are variations.
In your table make the data type timestamp (or timestamp with time zone or timestamp with local time zone), and only worry about formatting the value as a string for presentation to the end user, at the last possible moment.
When you do need to display it, if the display format is important to you then use to_char() with an explicit format mask - do not assume that anyone else running your queries will have the same NLS settings. As you can see, it's easy to change those to modify the output. (Most clients have a way to let you set the defaults so you don't have to do the same alter commands every time you connect; e.g. in SQL Developer, from Tools->Preferences->Database->NLS). If you want to always show the same format then use something like:
select to_char(your_column, 'YYYY-MM-DD HH24:MI:SS') as column_alias
from your_table
where your_column < timestamp '2018-01-01 00:00:00'
which also shows the column value being filtered (as a timestamp still) using a timestamp literal.
This is the format I want to have a TIMESTAMP object stored in.
This is a common misconception - timestamp (and date) data types do not have a format; they are stored in the database as 20 bytes (or 7 bytes for dates) representing:
year (2 bytes),
month, day, hour, minute, integer seconds (1 bytes each),
fractional seconds (4 bytes),
time zone offset hours (1 byte),
time zone offset minutes (1 byte),
other data (including time zone location) (7 bytes)
You can see the bytes using the DUMP function:
SELECT DUMP( your_timestamp_column ) FROM your_table;
The database will operate on these 20 bytes without any format. But that would not be useful to display to you, the user, so the user interface you use to access the database (SQL/Plus, SQL Developer, Toad, Java, C#, etc) will receive those raw bytes from the database and will silently format them into a more intelligible format for you, the user.
What you are actually asking is:
How can I get the application I am using to access the Oracle database to change the default format it uses to display TIMESTAMP data types?
For SQL/Plus (and SQL Developer) you can use the NLS_TIMESTAMP_FORMAT session parameter:
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Then:
SELECT SYSTIMESTAMP FROM DUAL;
Will output:
2018-07-10 16:24:53
However, this only sets the default format for your user's current session; other users can set their own parameters and can change the value during their session so you should not rely on this to provide a consistent formatting.
Instead, if you want to have a TIMESTAMP with a particular format then you should convert it to a datatype which can have a format - a string.
SELECT TO_CHAR( SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;
Then it does not matter what the user changes their default timestamp format to - your values will always be formatted how you expect.
So based on your replies above it sounds like you may be trying to do something you don't actually need to do.
As Gordon mentioned, timestamps are stored in an internal format so you can do things with the values. If you have the field stored as a timestamp data type you don't need to care how it's formatted in the database, you just need to care about how it looks for your query at the end. You can display a date field using to_char and still use a date range if you have the query built correctly.
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS')
from dual
WHERE systimestamp <= current_timestamp;
I don't think it is possible to to display the timestamp as you've described without using to_char and losing the data type.

How do I get this timestamp in the format I want, Oracle SQL

I firstly run the following command, and get the following result:
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 10:21:40
This is the format I want to have a TIMESTAMP object stored in.
When I convert it back though, it does not come in the format I want:
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 10.21.40.000000000 AM
In fact, it changes 2018 to be at the end, sets 07 to be "JUL" and the 10 is now at the front. Also the time is separated by dots, has many 0's and an AM.
How can I fix this? I am new to SQL development so I am not sure about the formatting.
Thank you so much
As #Gordon said, timestamps (and dates) are not stored in a format you would recognise Oracle uses an internal representation that you never really need to know about or examine (but it is documented if you're interested in that sort of thing).
When you query a timestamp it is displayed using your client's NLS settings, unless you have a client that overrides those. I can set my session up to match what you are seeing:
alter session set nls_timestamp_format = 'DD-MON-RR HH.MI.SS.FF AM';
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 15:37:31
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 03.37.31.000000000 PM
And I can change it see what you want to see:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';
select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;
TO_TIMESTAMP(TO_CHA
-------------------
2018-07-10 15:37:32
But all you are doing is converting from a timestamp with time zone (which is what systimestamp is) to a string and then back to a timestamp. You are losing the time zone portion, and any fractional seconds; which you could also do with a cast:
select cast(systimestamp as timestamp(0)) from dual;
CAST(SYSTIMESTAMPAS
-------------------
2018-07-10 15:37:32
You can see the timezone and fraction seconds with your default timestamp_tz format:
select systimestamp from dual;
SYSTIMESTAMP
------------------------------------
2018-07-10 15:37:33.776469000 +01:00
and change it with a different alter:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM';
select systimestamp from dual;
SYSTIMESTAMP
------------------------------
2018-07-10 15:37:34.070 +01:00
Which isn't entirely relevant if you're really talking about storing timestamps in a table, but shows that there are variations.
In your table make the data type timestamp (or timestamp with time zone or timestamp with local time zone), and only worry about formatting the value as a string for presentation to the end user, at the last possible moment.
When you do need to display it, if the display format is important to you then use to_char() with an explicit format mask - do not assume that anyone else running your queries will have the same NLS settings. As you can see, it's easy to change those to modify the output. (Most clients have a way to let you set the defaults so you don't have to do the same alter commands every time you connect; e.g. in SQL Developer, from Tools->Preferences->Database->NLS). If you want to always show the same format then use something like:
select to_char(your_column, 'YYYY-MM-DD HH24:MI:SS') as column_alias
from your_table
where your_column < timestamp '2018-01-01 00:00:00'
which also shows the column value being filtered (as a timestamp still) using a timestamp literal.
This is the format I want to have a TIMESTAMP object stored in.
This is a common misconception - timestamp (and date) data types do not have a format; they are stored in the database as 20 bytes (or 7 bytes for dates) representing:
year (2 bytes),
month, day, hour, minute, integer seconds (1 bytes each),
fractional seconds (4 bytes),
time zone offset hours (1 byte),
time zone offset minutes (1 byte),
other data (including time zone location) (7 bytes)
You can see the bytes using the DUMP function:
SELECT DUMP( your_timestamp_column ) FROM your_table;
The database will operate on these 20 bytes without any format. But that would not be useful to display to you, the user, so the user interface you use to access the database (SQL/Plus, SQL Developer, Toad, Java, C#, etc) will receive those raw bytes from the database and will silently format them into a more intelligible format for you, the user.
What you are actually asking is:
How can I get the application I am using to access the Oracle database to change the default format it uses to display TIMESTAMP data types?
For SQL/Plus (and SQL Developer) you can use the NLS_TIMESTAMP_FORMAT session parameter:
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Then:
SELECT SYSTIMESTAMP FROM DUAL;
Will output:
2018-07-10 16:24:53
However, this only sets the default format for your user's current session; other users can set their own parameters and can change the value during their session so you should not rely on this to provide a consistent formatting.
Instead, if you want to have a TIMESTAMP with a particular format then you should convert it to a datatype which can have a format - a string.
SELECT TO_CHAR( SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;
Then it does not matter what the user changes their default timestamp format to - your values will always be formatted how you expect.
So based on your replies above it sounds like you may be trying to do something you don't actually need to do.
As Gordon mentioned, timestamps are stored in an internal format so you can do things with the values. If you have the field stored as a timestamp data type you don't need to care how it's formatted in the database, you just need to care about how it looks for your query at the end. You can display a date field using to_char and still use a date range if you have the query built correctly.
select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS')
from dual
WHERE systimestamp <= current_timestamp;
I don't think it is possible to to display the timestamp as you've described without using to_char and losing the data type.

Oracle Database Table Column Timestamp

I am trying to create a table in my Oracle Database with the following structure:
CREATE TABLE orderlines(collectionTime TIMESTAMP NOT NULL);
An example of a timestamp that will be going in a row is:
20-01-2015 11:33:48-04:00
What would be the best datatype to use to store this timestamp?
TIMESTAMP, or DATE?
Also, what would the format be?
When I tried to import my CSV file containing all of the timestamps, SQL Developer Import Wizard didnt like the formatting. I tried
DD-MM-YYYY HH24:SS:MM-TZ
What would be the best datatype to use to store this timestamp? TIMESTAMP, or DATE?
The TIMESTAMP datatype is an extension to the DATE datatype. In addition to the datetime elements, the TIMESTAMP datatype holds fractions of a second. It comes in two forms, TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE. So, if you want the precision till fraction of seconds along with the timezone elements, go for TIMESTAMP. Else, a DATE data type will give you datetime elements.
Also, what would the format be?
Format is only for DISPLAY. So use the format model which you would like to display. You need to use TO_CHAR and a proper format model. For example,
SQL> select to_char(sysdate, 'mm/dd/yyyy hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'MM
-------------------
01/21/2015 11:02:27
SQL> select to_char(sysdate, 'mm/dd/yyyy hh:mi:ss am') from dual;
TO_CHAR(SYSDATE,'MM/DD
----------------------
01/21/2015 11:03:04 am
SQL>
When I tried to import my CSV file containing all of the timestamps,
SQL Developer Import Wizard didnt like the formatting.
That is the issue with your locale-specific NLS_DATE_FORMAT.
Try 'DD-MM-YYYY HH24:MI:SS-TZH:TZM'. This is the mask that would be recognized by to_timestamp_tz. Notice that MM is for months and MI is for minutes. Also, you had hours:seconds:minutes in your mask, but that would result in a wrong value not an error.

Oracle default Timestamp format

I just set default timestamp format as
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH:MI:SS.FF'
When I insert the data into the table the timestamp inserted as,
0014-08-11 04:45:24.000000000
When I query
SELECT SYSTIMESTAMP FROM DUAL
I get:
11-AUG-14 06.14.58.400000000 PM +04:00
But I want the default timestamp as 2014-07-22 05:54:18.000000000.
It would be appreciated if some one could help me on this.
SYSTIMESTAMP returns data type TIMESTAMP WITH TIMEZONE. So you either need to cast it to a plain TIMESTAMP:
SELECT CAST(SYSTIMESTAMP AS TIMESTAMP) FROM DUAL;
CAST(SYSTIMESTAMPASTIMESTAMP)
-----------------------------
2014-08-11 15:27:11.091862000
Or set the separate NLS_TIMESTAMP_TZ_FORMAT parameter:
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
SELECT SYSTIMESTAMP FROM DUAL;
SYSTIMESTAMP
----------------------
2014-08-11 15:27:11.35
1526000
Either way you're losing the time zone information, which may or may not matter to you.
But this doesn't have anything to do with querying values from a TIMESTAMP (without time zone) column in your table. The value in the table has no format incidentally; the NLS settings when you insert will not affect how it is stored or how it is displayed when queried. You need to specify the format at query time as well as at insert time - and preferably using explicit format models with TO_TIMESTAMP() and TO_CHAR() rather than replying on NLS settings, which you might not be able to control.
You should also be using HH24 since you no longer have the AM/PM marker.
There are two solutions to this :
1. Convert TIMESTAMP/DATE format in Oracle client (Applicable only for that session)
alter session set nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF6';
2. Define nls_timestamp_format in init.ora
nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF6';

Perl and Oracle DB - help

I am using Oracle express database, and I would like to know how can I change the date formatting-
from dd-mm-yyyy to dd-mm-yyyy hh-mm. Also, I've heard something about alter session, but I don't know how to use it in Perl.
This is what I did so far:
my $sth = $dbh->prepare("INSERT INTO Perl
(A_FIELD,B_FIELD,C_FIELD,TIME_STAME)
VALUES
(?,?,?,TO_DATE(?,'DD/MM/YYYY HH24:MI'))");
Date fields in Oracle are not formatted for display - it's an internal format that you convert to/from on input/output. When you store a date in Oracle date datatype columns, you convert your character string to internal format by describing the date-time to the TO_DATE function with the format model string. Oracle interprets the character string to it's internal format. When you need to display the date, you do the reverse - you tell oracle how to display the date by again giving a format model, this time to the TO_CHAR function.
To illustrate with your example, you could convert dd-mm-yyyy to dd-mm-yyyy hh-mm without ever storing the value (I assume you meant to display hours-minutes. The format model for minutes is 'MI', since 'MM' is month):
SQL> SELECT TO_CHAR(TO_DATE('01-01-2020','DD-MM-YYYY'),'DD-MM-YYYY HH-MI') mydate
FROM DUAL;
MYDATE
----------------
01-01-2020 12-00
Note that with your example, the time portion of your date is not supplied on input, so it defaults to midnight. To store a time value in your date column, you must supply a time value in your input:
SQL> SELECT TO_CHAR(TO_DATE('01/01/2020 10:13','DD/MM/YYYY HH:MI'),'DD-MM-YYYY HH-MI') mydate
FROM DUAL;
MYDATE
----------------
01-01-2020 10-13
SQL>
Depending on what you're trying to do, the system date in Oracle can be obtained by a reference to the pseudo-column SYSDATE:
SQL> SELECT TO_CHAR(sysdate,'MM/DD/YYYY HH:MI:SS AM') dt1,
2 TO_CHAR(sysdate,'DD-MON-YYYY HH24:MI:SS') dt2
3 FROM dual;
DT1 DT2
---------------------- -----------------------------
07/01/2011 03:44:30 PM 01-JUL-2011 15:44:30
SQL>
So the roundabout answer to your question is that it entirely depends on what format your input date string is in. You convert that to Oracle's date type via a format model and the TO_DATE function, then convert the date item to a display format of your choosing via TO_CHAR and a format model. As for the "ALTER SESSION" command you alluded to in your question, you can specify a default format model for date conversions by specifying the NLS_DATE_FORMAT parameter in the ALTER SESSION command:
SQL> SELECT sysdate FROM dual;
SYSDATE
---------
02-JUL-11
SQL> ALTER SESSION SET nls_date_format='dd-mon-yyyy hh24:mi:ss';
Session altered.
SQL> SELECT sysdate FROM dual;
SYSDATE
--------------------
02-jul-2011 10:39:24
If the incoming date string is in mm-yyyy format, then you can use the statement below(TO_DATE(?,'MM-YYYY')) to convert the string to date:
$sth = $dbh->prepare("INSERT INTO Perl (A_FIELD,B_FIELD,C_FIELD,TIME_STAME) VALUES (?,?,?,TO_DATE(?,'MM-YYYY'))");