how to insert iso-8601 type date into oracle database - oracle

I am using Oracle 11g and trying to figure out how to insert this date into my table. The date seems like it is ISO-8601, but the 7 zeros are confusing me.
Insert into myTestTable (myDate) values ('2013-01-22T00:00:00.0000000-05:00');
I have tried to format the date with no luck. The error I am getting is ORA-01861 literal does not match format string.

First of all, the column must be a TIMESTAMP WITH TIME ZONE type to hold the value you're trying to insert. An Oracle DATE is accurate to seconds only, and it doesn't hold a time zone.
The seven zeros are the fractional seconds. The default precision for a TIMESTAMP WITH TIME ZONE happens to be seven decimal places. To specify three decimal places for seconds, define the column as TIMESTAMP(3) WITH LOCAL TIME ZONE.
The actual number of decimal places returned by SYSTIMESTAMP, which is the current timestamp at the server, depends on the operating system. My local Windows 7 Oracle returns three significant decimal places, while the Solaris OS at one of my clients returns six significant decimal places.
As for inserting the value, if you do something like this...
insert into myTestTable (myTS) values ('2013-01-22T00:00:00.0000000-05:00');
... Oracle will try to convert the timestamp using its current NLS_TIMESTAMP_TZ_FORMAT setting. You can query the setting like this:
SELECT *
FROM NLS_Session_Parameters
WHERE Parameter = 'NLS_TIMESTAMP_TZ_FORMAT';
PARAMETER VALUE
----------------------- ----------------------------
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
The result I got is the "factory default". Yours is probably the same, and you can see it doesn't match the format you've given, hence the conversion fails.
As another answer correctly notes, you can use the TO_TIMESTAMP_TZ function and a format string to convert the string to a timestamp. You can also use an ANSI timestamp literal:
insert into myTestTable (myTS)
values (TIMESTAMP '2013-01-22T00:00:00.0000000-05:00');
Oracle documents timestamp literals here. The link covers literals for all types, so you'll need to scroll about two-thirds of the way down the screen (or do a find) to get to the timestamp literals.

Here is the answer.
insert into myTestTable (myDate) values
(to_timestamp_tz('2013-01-22T00:00:00.0000000-05:00',
'YYYY-MM-DD"t"HH24:MI:SS.FF7TZR'));

Related

Converting date from DD-MON-YY to DD-MM-YYYY with NLS_DATE_FORMAT

I'm trying to store date type data from Oracle FORMS with format mask as like DD-MM-YYYY but every time it store as like DD/MON/YY.
I already alter session with NLS_DATE_FORMAT, but result is as same as before.
Oracle internal date format that is written in the table is something you can't change in any way, but, in the same time, it is irrelevant. If you are dealing with DATE type column then you should know that it containes both the date and the time. How, where and when you will show it or use it is on you. Here is a sample of a few formats derived from that original Oracle DATE format...
WITH
t AS
(
Select SYSDATE "MY_DATE_COLUMN" From Dual
)
Select
MY_DATE_COLUMN "DATE_DEFAULT_FORMAT",
To_Char(MY_DATE_COLUMN, 'mm-dd-yyyy') "DATE_1",
To_Char(MY_DATE_COLUMN, 'yyyy/mm/dd') "DATE_2",
To_Char(MY_DATE_COLUMN, 'dd.mm.yyyy') "DATE_3",
To_Char(MY_DATE_COLUMN, 'dd.mm.yyyy hh24:mi:ss') "DATE_4"
From t
DATE_DEFAULT_FORMAT
DATE_1
DATE_2
DATE_3
DATE_4
22-OCT-22
10-22-2022
2022/10/22
22.10.2022
22.10.2022 10:59:44
You can find a lot more about the theme at https://www.oracletutorial.com/oracle-basics/oracle-date/
Regards...
In Oracle, a DATE is a binary data-type consisting of 7-bytes (representing century, year-of-century, month, day, hour, minute and second). It ALWAYS has those 7 components and it is NEVER stored in any particular human-readable format.
every time it store as like DD/MON/YY.
As already mentioned, no, it does not store a date like that; the database stores dates as 7 bytes.
What you are seeing is that the client application, that you are using to connect to the database, is receiving the 7-byte binary date value and is choosing to convert it to something that is more easily comprehensible to you, the user, and is defaulting to converting the date to a string with the format DD/MON/RR.
What you should be doing is changing how the dates are displayed by the client application by either:
Change the settings in the Toad (View > Toad Options > Data Grids > Data and set the Date Format option) and allow Toad to implicitly format the string; or
Use TO_CHAR to explicitly format the date (TO_CHAR(column_name, 'DD-MM-YYYY')).
I'm trying to store data as like DD-MM-YYYY.
If you want to store a date then STORE it as a date (which has no format) and format it when you DISPLAY it.
If you have a valid business case to store it with a format then you will need to store it as a string, rather than as a date, because you can format strings; however, this is generally considered bad practice and should be avoided.
Sadman, to add to what others have posted I suggest you do not write your applications with reliance on the NLS_DATE_FORMAT parameter but rather you screens and application should specify the expected DATE entry format and the code should use the TO_DATE function to store the data into the database. All application SQL should use the TO_CHAR function to format date output for display.

Oracle TRUNC function doesn't work in perl

I try to insert the created field in my_table. The created field has a datetime type. In my_table the field my_created has a date format. So I try to TRUNC the created field. However I'm getting the error ORA-01830: date format picture ends before converting entire input stringwhile inserting the truncated value. It seems, that the time is still there but is reset to 00:00. how can I get only the date without time? It happens only in perl. I'm getting only date in toad.
Very simplified code looks like:
my $SQL="SELECT
TRUNC(CREATED),
FROM
DBA_OBJECTS";
my $sth = $db->prepare($SQL);
$sth->execute();
my $date = $sth->fetchrow();
$SQL = "INSERT INTO MY_TABLE
(MY_CREATED)
VALUES (?)";
my $stmt = $dbh_master->prepare($SQL);
$stmt->execute($date);
EDIT:
I found an ugly workaround and I'm executing it like this:
$stmt->execute(substr($date, 0, 10));
However maybe someone has a nicer solution.
How can I get only the date without time?
In Oracle, a DATE is a binary data type that is composed of 7 bytes representing: century, year-of-century, month, day, hour, minute and second. It ALWAYS has those binary components so if you want an Oracle DATE data type then you cannot get it without a time.
The Oracle DATE data type was released with Oracle version 2 in 1979 and predates the ANSI/ISO standard (of 1986, where a DATE does not have a time component) and Oracle has maintained backwards compatibility with their previous data types rather than adopting the ANSI standard.
If you use the TRUNC(date_value, format_model) function then it will set the binary components of the DATE, up to the specified format model, to the minimum (0 for hours, minutes and seconds, 1 for days and months) but it will NOT give you a data type that does not have a time component.
It happens only in perl. I'm getting only date in toad.
No, you are getting the entire 7 byte binary value in Toad; however, the user interface is only choosing to show you the date component. There should be a setting in the preferences that can set the date format in Toad which will let you see the entire date-time components.
Oracle SQL/Plus and SQL Developer use the NLS_DATE_FORMAT session parameter and Toad may also be able to use that.
If you want to get the value as a DATE then it will always have a time component (even if you set that time component to zeros using TRUNC).
If you want to get the date so that it is formatted in a way without a time component then you need to convert it to another data type and can use TO_CHAR to format it as a string:
SELECT TO_CHAR(CREATED, 'YYYY-MM-DD')
FROM DBA_OBJECTS
But then you will be returning a (formatted) string and not a DATE data type.

Storing timestamp values stored in a varchar2 column into a date column in oracle

I have a column in a table that stores timestamp values as
"2018-01-12 16:13:51.107000000", i need to insert this column into a date column in another table, what format mask do i have to use here..
I have used the mask 'YYYY-MM-DD HH24:MI:SS.FF' but shows 'date format not recognized'.
I am assuming that you were trying to use TO_DATE on your text timestamp data. This won't work, because Oracle dates do not store anything more precise than seconds. Since your timestamps have fractional seconds, you may use TO_TIMESTAMP here, then cast that actual timestamp to a date:
SELECT
CAST(TO_TIMESTAMP('2018-01-12 16:13:51.100000',
'YYYY-MM-DD HH24:MI:SS.FF') AS DATE)
FROM dual;
12.01.2018 16:13:51
Demo
You can do this with a single call to TO_DATE(), but you must give the correct format model. Note that this solution is simpler (and possibly faster - if that matters) than converting to a timestamp and then casting to date.
If you want TO_DATE() to ignore part of the input string, you can use the "boilerplate text" syntax in the format model. That is enclosed in double quotes. For example, if your string included the letter T somewhere and it had to be ignored, you would include "T" in the same position in the format model.
This has some flexibility. In your case, you must ignore the decimal point, and up to nine decimal digits (the maximum for timestamp in Oracle). The format model will allow you to use ".999999999" (or any other digits, but 9999... is used by most programmers) to ignore a decimal point and UP TO nine digits after that.
Demo: (notice the double-quoted "boilerplate text" in the format model)
select to_date('2018-01-12 16:13:51.100000',
'YYYY-MM-DD HH24:MI:SS".999999999"') as dt
from dual;
DT
-------------------
2018-01-12 16:13:51

How to Insert a Timestamp in Oracle in a Specific Format

I am at a loss as how to insert the current time in a different format than the default. Can somebody help explain?
Here is how my table was created:
CREATE TABLE ACTIVITY_LOG
(
TIME TIMESTAMP NOT NULL
, ACTIVITY VARCHAR2(200) NOT NULL
);
My insert command works:
insert into activity_log
values (localtimestamp,'blah');
But how do i insert the localtimestamp value into my table in a different format using the various MM DD YY HH MM SS tags? I've tried the following, but it gives me the ORA-1830: date format picture ends before converting entire input string error.
insert into activity_log
values (to_timestamp(localtimestamp,'YYYY/MM/DD'),'blah');
You don't insert a timestamp in a particular format. Timestamps (and dates) are stored in the database using an internal representation, which is betwen 7 and 11 bytes depending on the type and precision. There is more about that in this question, among others.
Your client or application decides how to display the value in a human-readable string form.
When you do:
to_timestamp(localtimestamp,'YYYY/MM/DD')
you are implicitly converting the localtimestamp to a string, using your session's NLS settings, and then converting it back to a timestamp. That may incidentally change the value - losing precision - but won't change how the value is stored internally. In your case the mismatch between the NLS setting and the format you are supplying is leading to an ORA-01830 error.
So your first insert is correct (assuming you really want the session time, not the server time). If you want to see the stored values in a particular format then either change your client session's NLS settings, or preferably format it explicitly when you query it, e.g.:
select to_char(time, 'YYYY-MM-DD HH24:MI:SS.FF3') from activity_log
You don't seem to provide any indication of what your 'localtimestamp' is - is that pseudocode? A variable name? A column you haven't shown the definition for?
What data type is 'localtimestamp'? What data does it contain? Pertinent questions as other answers point out, because if it truly is a time stamp then oracle will be converting it to a string for you, before passing that string to to_timestamp() in your final query. Your initial stab at it should just work if the variable is a timestamp, containing a timestamp
Ultimately "date format picture ends" means "you passed me a string looking like '2017-05-17 12:45:59', but claimed it was only 'yyyy-mm-dd'. What was I expected to do with the rest of it?"
Your current final comment on your question "I was hoping to look in the table and see a useful looking time" - that's your query tool's problem. Have a look in the setting of your query tool and change the date format it displays. As has been noted, dates in oracle are stored as a decimal number days since a certain moment in time. If 0 represents 01 Jan 1970, then 1.75 represents 6pm on the 2 Jan 1970. It is up to the end program the user is using, to format the date into something you like.. you cannot "insert a timestamp with a different format" because time stamps don't have a format any more than a number like 1.75 has a format. It is what your query does with it when it gets it out, that gives it the format:
To_char(timestampcol, 'yyyy mm did')
To-char(tomestampcol, 'mon dd yyyy')
These use oracles built in date formatter, that turns that decimal number of the date into a string in the given format; you will see a string.. or you can just write "select * from table" and run it in TOAD and toad will show you the dates according to the format in settings, or you can write a c# program and get a load of date objects out and call my date.ToString("yyyy-MM-dd") on them to format them. The idea I'm trying to get across is that you don't pick the date format on the way in, you pick it on the way out, if you don't like what you're looking at, you have to change it on the way out, not the way in

How to change default date,timestamp dataype for columns in oracle

I have created a table in Oracle in which I have KPI_START_DATE column which is a Date datatype, and KPI_START_TIME which is a TIMESTAMP datatype.
Now I want to modify this date dataype for
KPI_START_DATE to dd/mm/yyyy
and
KPI_START_TIME to HH:MI:SS.
So that user should always enter the date and time in this column in this proper format.
I tried below query but its was giving error:
Alter table KPI_DEFINITION MODIFY(to_char(KPI_START_DATE,'dd/mm/yyyy') )
DATE and TIMESTAMP columns do not have any inherent readable format. The values are stored in Oracle's own internal representation, which has no resemblance to a human-readable date or time. At the point to retrieve or display a value you can convert it to whatever format you want, with to_char().
Both DATE and TIMESTAMP have date and time components (to second precision with DATE, and with fractional seconds with TIMESTAMP; plus time zone information with the extended data types), and you should not try to store them separately as two columns. Have a single column and extract the information you need at any time; to get the information out of a single column but split into two fields you could do:
select to_char(KPI_START, 'dd/mm/yyyy') as KPI_START_DATE,
to_char(KPI_START, 'hh24:mi:ss') as KPI_START_TIME
but you'd generally want both together anyway:
select to_char(KPI_START, 'dd/mm/yyyy hh24:mi:ss')
Also notice the 'hh24' format model to get the 24-hour clock time; otherwise you wouldn't see any difference between 3 a.m. and 3 p.m.
You can store a value in either type of column with the time set to midnight, but it does still have a time component - it is just midnight. You can't store a value in either type of column with just a time component - it has to have a date too. You could make that a nominal date and just ignore it, but I've never seen a valid reason to do that - you're wasting storage in two columns, and making searching for and comparing values much harder. Oracle even provides a default date if you don't specify one (first day of current month). But the value always has both a date and a time part:
create table KPI_DEFINITION (KPI_START date);
insert into KPI_DEFINITION (KPI_START)
values (to_date('27/01/2015', 'DD/MM/YYYY'));
insert into KPI_DEFINITION (KPI_START)
values (to_date('12:41:57', 'HH24:MI:SS'));
select to_char(KPI_START, 'YYYY-MM-DD HH24:MI:SS') from KPI_DEFINITION;
TO_CHAR(KPI_START,'YYYY-MM-DDHH24:MI:SS')
-----------------------------------------
2015-01-27 00:00:00
2015-01-01 12:41:57
Your users should be inserting a single value with both date and time as one:
insert into KPI_DEFINITION (KPI_START)
values (to_date('27/01/2015 12:41:57', 'DD/MM/YYYY HH24:MI:SS'));
select to_char(KPI_START, 'YYYY-MM-DD HH24:MI:SS') from KPI_DEFINITION;
TO_CHAR(KPI_START,'YYYY-MM-DDHH24:MI:SS')
-----------------------------------------
2015-01-27 12:41:57
You can also use date or timestamp literals, and if using to_date() you should always specify the full format - don't rely on NLS settings as they may be different for other users.
You should understand difference between datatype and format. DATE is a datatype. TIMESTAMP is a datatype. None of them have formats, they're just numbers.
When converting character datatype to or from date datatype, format should be applied. It's an attribute of an actual conversion, nothing else.
Look at this:
SQL> create table tmp$date(d date);
Table created
SQL> insert into tmp$date values (DATE '2010-11-01');
1 row inserted
SQL> insert into tmp$date values (DATE '2014-12-28');
1 row inserted
SQL> select d, dump(d) from tmp$date;
D DUMP(D)
----------- ---------------------------------
01.11.2010 Typ=12 Len=7: 120,110,11,1,1,1,1
28.12.2014 Typ=12 Len=7: 120,114,12,28,1,1,1
There is no any 'format' here.
DISPLAYING and STORING are NOT the same when it comes to DATE.
When people say Oracle isn’t storing the date in the format they wanted, what is really happening is Oracle is not presenting the date in the character string format they expected or wanted.
When a data element of type DATE is selected, it must be converted from its internal, binary format, to a string of characters for human consumption. The conversion of data from one type to another is known as known a “conversion”, “type casting” or “coercion”. In Oracle the conversion between dates and character strings is controlled by the NLS_DATE_FORMAT model. The NLS_DATE_FORMAT can be set in any of several different locations, each with its own scope of influence.
I could go on with my leacture over DATE data type, but I am glad that someone has already got a good writeup over this. Please read this https://edstevensdba.wordpress.com/2011/04/07/nls_date_format/

Resources