Oracle problems with DATEs - oracle

iam confused. Iam trying to read an Value from an oracle table, format: timestamp(6).
In my PHP Scripts im setting the Dateformat with:
$db->query('ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-RR"');
On 2 Machines im recieving this string as value (wich is correct for me):
["TIME_INSERT"] => string(24) "05.10.07 14:20:05,000000"
On one linux machines where the same script is running, it returns:
["TIME_INSERT"] => string(28) "05-OCT-07 02.20.05.000000 PM"
any ideas how to change this ?

you should set the session parameter NLS_TIMESTAMP_FORMAT or NLS_TIMESTAMP_TZ_FORMAT to display timestamp data as you want:
SQL> select systimestamp from dual;
SYSTIMESTAMP
----------------------------------------------------
12/10/09 12:52:41,462532 +02:00
SQL> ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'dd.mm.rr hh24:mi:ss,ff5';
Session altered
SQL> select systimestamp from dual;
SYSTIMESTAMP
--------------------------------------------------------------------------------
12.10.09 12:56:36,14023

Related

Why is DATE data type treated like TIMESTAMP(0) data type in Oracle mode in H2?

According to the H2 documentation, in the Oracle compatibility mode:
DATE data type is treated like TIMESTAMP(0) data type.
Meantime, DATE and TIMESTAMP(0) datatypes are not the same in Oracle. Compare:
SELECT CAST(SYSDATE AS TIMESTAMP(0)), CAST(SYSDATE AS DATE) from dual
gives
25-MAR-22 13.07.42.000000000 25-MAR-22
respectively.
In particular, this weird treating of DATE as TIMESTAMP(0) influences on how H2 calculates the difference between two dates.
Again, in Oracle:
SELECT CAST(TO_DATE('2022-01-05', 'YYYY-MM-DD') AS TIMESTAMP(0)) - CAST(TO_DATE('2022-01-01', 'YYYY-MM-DD') AS TIMESTAMP(0)) from dual
gives
+04 00:00:00.000000
and
SELECT CAST(TO_DATE('2022-01-05', 'YYYY-MM-DD') AS DATE) - CAST(TO_DATE('2022-01-01', 'YYYY-MM-DD') AS DATE) from dual
produces just:
4
Apparently, for H2 both above queries produce the result in nanoseconds and not days as expected.
So, it is an H2 bug or I am missing something?
Meantime, DATE and TIMESTAMP(0) datatypes are not the same in Oracle
Oracle differs from many other RDBMS in that its DATE data type ALWAYS contains both a date and a time component. Its implementation predates the ANSI standard.
In Oracle, if you have the table:
CREATE TABLE table_name (ts TIMESTAMP(0), dt DATE);
and insert the data:
INSERT INTO table_name (ts, dt) VALUES (SYSDATE, SYSDATE);
Then you can look at the binary data being stored using the DUMP function:
SELECT DUMP(ts) AS dump_ts,
DUMP(dt) AS dump_dt
FROM table_name;
Which outputs:
DUMP_TS
DUMP_DT
Typ=180 Len=7: 120,122,3,25,15,13,37
Typ=12 Len=7: 120,122,3,25,15,13,37
Then you can see that they are both stored as 7-byte binary values:
120 = Century + 100
122 = Year-of-century + 100
3 = Month
25 = Day
15 = Hour + 1
13 = Minutes + 1
37 = Seconds + 1
And the binary values are identical (the only difference is in the meta-data Typ where 180 = TIMESTAMP and 12 = DATE).
Effectively, they are stored identically.
db<>fiddle here
However
The side-effects of a TIMESTAMP vs. a DATE data type in Oracle may lead to different effects.
When you subtract a TIMESTAMP and either a TIMESTAMP or a DATE then the return value is an INTERVAL DAY TO SECOND data type.
When you subtract a DATE and a DATE then the default return value is a NUMBER representing the number of days difference.
When you display a TIMESTAMP then the client application you are using may default to using the NLS_TIMESTAMP_FORMAT session parameter to format the timestamp as a string and the default for this parameter will typically show date, time and fractional seconds.
When you display a DATE then the client application you are using may default to using the NLS_DATE_FORMAT session parameter to format the date as a string and the default for this parameter will show date but not time (and there will never be any fractional seconds to show). Just because the client application may chose not to show the time component does not mean that the time component does not exist.
If you set the session parameters using:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
Then, provided your client application is using those parameters to format them, they will display identically.
The problem you are seeing with the difference in Oracle is due to these side effects.
If the question is
So, it is an H2 bug or I am missing something?
than the the answer would be:
No, it is not a bug, and what you've missed is the fact, that compatibility modes in H2 are just that - attempt to reach with minimal efforts maximum compatibility with different databases.
H2 is not an emulator for any non-standard features (quirks) of those databases.
It that particular case, to achieve identical behaviour would require to introduce new non-standard data type, which goes beyond "minimal effort" level.
The different in the output of the values in the first query is down to the session's NLS settings. These control the display format for dates and timestamps:
sho parameter nls_date_format
NAME TYPE VALUE
--------------- ------ -----------
nls_date_format string DD-MON-YYYY
sho parameter nls_timestamp_format
NAME TYPE VALUE
-------------------- ------ -------------------------
nls_timestamp_format string DD-MON-YYYY HH24.MI.SSXFF
SELECT CAST(SYSDATE AS TIMESTAMP(0)), CAST(SYSDATE AS DATE) from dual;
CAST(SYSDATEASTIMESTAMP(0)) CAST(SYSDAT
------------------------------ -----------
25-MAR-2022 12.18.24.000000000 25-MAR-2022
If you change these to be the same format, both expressions return the same result:
alter session set nls_date_format = 'DD-MON-YYYY HH24:MI:SS';
alter session set nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS';
SELECT CAST(SYSDATE AS TIMESTAMP(0)), CAST(SYSDATE AS DATE) from dual;
CAST(SYSDATEASTIMEST CAST(SYSDATEASDATE)
-------------------- --------------------
25-MAR-2022 12:17:43 25-MAR-2022 12:17:43
So they both contain the full date + time with no fractional seconds.
Note that while date and timestamp(0) have the same precision, as your further examples show they work differently:
Subtracting one date from another returns the number of days between the values as a number
Subtracting a timestamp from a date or timestamp returns an interval
So the result of:
SELECT CAST(TO_DATE('2022-01-05', 'YYYY-MM-DD') AS DATE) - CAST(TO_DATE('2022-01-01', 'YYYY-MM-DD') AS DATE) from dual
Is 4 days.

DBeaver/Oracle wrong datetime pattern includes .0 at end

Using DBeaver and Oracle, select querys shows date in a wrong format, which always includes .0 at the end, like 2019-05-17 16:10:47.0.
To update/insert any date column in a table, on DBeaver editor, doesn't matter the date pattern I try, throws:
ORA-01861: literal does not match format string
SELECT sysdate FROM dual
-- returns date with .0: 2019-05-17 17:21:11.0
SELECT TO_CHAR(sysdate, 'YYYY-MM-DD HH24:MI:SS') FROM dual
-- returns ok: 2019-05-17 17:21:11
It's ok on Oracle SQL Developer.
I also tried removing SSXFF from NLS_PARAMETERS, but doesn't seem to work:
SELECT * FROM v$nls_parameters
--NLS_DATE_FORMAT DD/MM/RR
--NLS_TIME_FORMAT HH24:MI:SSXFF
--NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
--NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
--NLS_TIMESTAMP_TZ_FORMAT DD/MM/RR HH24:MI:SSXFF TZR
alter session set NLS_TIME_FORMAT = 'HH24:MI:SS'
alter session set NLS_TIMESTAMP_FORMAT = 'DD/MM/RR HH24:MI:SS'
alter session set NLS_TIME_TZ_FORMAT = 'HH24:MI:SS TZR'
alter session set NLS_TIMESTAMP_TZ_FORMAT = 'DD/MM/RR HH24:MI:SS TZR'
Environment:
Windows 10
Oracle Database 12c 12.2.0.1.0 - 64bit
DBeaver 6.0.3
Driver OJDBC7
Make sure on DBeaver Preferences > Data Formats > "Disable date / time formatting" option is unchecked.
Thats allows to use client-side formats on insert/update actions.

different date format to one date format in table

I have two DATE column in table oracle database(12c).sysdate format is:
SQL> select sysdate from dual;
SYSDATE
---------
25-NOV-17
SQ>desc test_table
id NUMBER(10)
LAST_CREATED_DATE DATE
IS_CREATED_DATE DATE
where LAST_CREATED_DATE has different format to IS_CREATED_DATE(sysdate).
because LAST_CREATED_DATE is fixed and i'm reading from file(date format:20100330) where as IS_CREATED_DATE am inserting as sysdate(current date).
insert into test_table (id,LAST_CREATED_DATE,IS_CREATED_DATE) values (123,20100930,sysdate);
but with this insert statement am facing errors.
I tried ALTER SESSION SET NLS_DATE_FORMAT = 'yyyymmdd';.This works fine in current session,but looking for by which i can change ORACLE database date format to yyyymmdd(linux).
You should change your statement like this:
insert into test_table (id,LAST_CREATED_DATE,IS_CREATED_DATE)
values (123,to_date('20100930','yyyymmdd'),sysdate);
There are three ways to accomplish this task :
1)
SQL>conn myschema/mypwd
SQL>insert into test_table values(123,to_date('20100930','yyyymmdd'),sysdate);
2) as you mentioned
SQL>alter session set nls_date_format = 'yyyymmdd';
SQL>insert into test_table values(123,'20100930',sysdate); -- notice that 20100930 is quoted
3) globally(along with the db, needs restart, maybe dangerous on a production system in coordination with existing applications' date format model)
SQL>conn / as sysdba
SQL>alter system set nls_date_format = 'yyyymmdd' scope=spfile;
SQL>shutdown immediate;
SQL>startup;
SQL>conn myschema/mypwd
SQL>insert into test_table values(123,'20100930',sysdate); -- from now on, you don't need to alter your date parameter for every session

Inserting date as dd-mon-yy in oracle

I am trying to insert date value as dd-mon-yy but the database is storing it as dd/mm/yy.
For example: INSERT INTO tablename VALUES (to_date('01-mar-09', 'dd-mon-yy');
The DB stores it as 01/03/09. Why is that? Whay can't I just store it as 01-mar-09?
Please help.
Date is a raw datatype. It doesn't have a format to be saved. It's upto you or the environment/session to decide how to display it.. use NLS_DATE_FORMAT parameter as required... using alter session or use to_char() function
alter session set nls_date_format = 'DD-MON-YY';
select sysdate from dual;
28-OCT-15
alter session set nls_date_format = 'MM/DD/YY';
select sysdate from dual;
10/28/15
The NLS parameters precedence is decided as below, if not set on session level then use instance level, if not set at instance level then use which is present at database level. Below are the views which provide set values at each level
NLS_SESSION_PARAMETERS => session level parameters
NLS_INSTANCE_PARAMETERS => instance level parameters
NLS_DATABASE_PARAMETERS => database level parameters
Oracle doesn't store a date as any format .. it just stores "a date". you are viewing it/displaying it as a different format. Check your nls_date settings.
SQL> select sysdate from dual;
SYSDATE
---------
28-OCT-15
SQL> alter session set nls_date_format='dd-mon-yyyy hh24:mi:ss'
Session altered.
SQL> select sysdate from dual;
SYSDATE
--------------------
28-oct-2015 11:00:56
SQL>

date and time oracle error

I am trying to show the date and time in oracle where I have altered the date and time formats as:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY MM DD';
ALTER SESSION SET NLS_DATE_FORMAT = 'HH24:MI:SS';
insert into train
values(18103,'2011/apr/30 21:00:00','2011/apr/31 21:00:00','abl','ndl');
But I am getting the error as ORA-01861: literal does not match format string
I have also tried entering the date and time as, 2011/04/30 21:00:00 but still it returns the same error! help!
Your nls_date_format does not match the format of the date string you insert. It should be:
SQL>ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY/MON/DD HH24:MI:SS';
session SET altered.
SQL>insert into dat
values('2011/apr/30 21:00:00');
1 rows inserted.
SQL>select d from dat;
D
----------------------
2011/APR/30 21:00:00
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY MM DD';
ALTER SESSION SET NLS_DATE_FORMAT = 'HH24:MI:SS';
these have to be combined. eg
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY MM DD HH24:MI:SS'
also on your insert be sure to TO_DATE eg to_date('2011/apr/31 21:00:00', 'yyyy/mon/dd hh24:mi:ss')

Resources