how to insert 0001 year in oracle? - sql

how to insert 0001 year in oracle ?
I've tried
UPDATE table1
SET
datblock = to_timestamp('01/01/0001 00:00:00,000000000','DD/MM/RR HH24:MI:SSXFF')
but it shows as 2001, anyone can help ?

Do not use the RR format which has a special logik to decide the century.
Use explicite YYYY format
select to_timestamp('01/01/0001 00:00:00,000000000','DD/MM/RR HH24:MI:SSXFF') yyyy from dual;
YYYY
-----------------------------
01.01.0001 00:00:00,000000000

Use a timestamp literal:
UPDATE table1
SET
datblock = TIMESTAMP '0001-01-01 00:00:00';
However, your query works as the string-to-date conversion rules mean that RR also matches RRRR.
CREATE TABLE table1 (datblock) AS
SELECT TIMESTAMP '2021-09-27 01:23:45' FROM DUAL;
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SSXFF';
ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ',.';
UPDATE table1
SET datblock = to_timestamp(
'01/01/0001 00:00:00,000000000',
'DD/MM/RR HH24:MI:SSXFF'
);
SELECT * FROM table1;
Outputs:
DATBLOCK
0001-01-01 00:00:00,000000000
db<>fiddle here

Related

how to fetch records between two timestamps in oracle?

I have a column of TIMESTAMP(6) datatype in oracle and have values like 2022-04-01 18:02:42 and i wanna fetch all the records that falls between two datetime. I tried like below but no luck,
select * from table
where column BETWEEN '2022-04-01 18:02:42' and '2022-11-03 19:28:57' -- no records
tried this too,
select *
from table
where column BETWEEN to_date('2022-04-01','yyyy-mm-dd')
and to_date('2022-11-03','yyyy-mm-dd') -- a non-numeric character was found where a numeric was expected
and,
select *
from table
where column BETWEEN to_timestamp('2022-04-01','yyyy-mm-dd')
and to_timestamp('2022-11-03','yyyy-mm-dd') -- a non-numeric character was found where a numeric was expected.
I want to fetch records falls in this dates!
Thanks.
You need to convert the literal into DATE using TO_DATE and required format mask to compare the timestamp column with the input timestamp values.
SQL> CREATE TABLE t(A TIMESTAMP);
Table created.
SQL>
SQL> INSERT INTO t(A) VALUES(to_date('2022-04-10T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS'));
1 row created.
SQL> INSERT INTO t(A) VALUES(to_date('2022-05-01T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS'));
1 row created.
SQL> INSERT INTO t(A) VALUES(to_date('2022-03-01T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS'));
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM t;
A
----------------------------
10-APR-22 03.39.00.000000 PM
01-MAY-22 03.39.00.000000 PM
01-MAR-22 03.39.00.000000 PM
SELECT *
FROM t
WHERE A BETWEEN
to_date('2015-04-06T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS')
AND
to_date('2022-05-06T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS');
A
--------------------------------------------------------------------------
10-APR-22 03.39.00.000000 PM
01-MAY-22 03.39.00.000000 PM
Use TIMESTAMP literals:
SELECT *
FROM table_name
WHERE column_name BETWEEN TIMESTAMP '2022-04-01 18:02:42'
AND TIMESTAMP '2022-11-03 19:28:57';
or DATE and INTERVAL DAY TO SECOND literals:
SELECT *
FROM table_name
WHERE column_name BETWEEN DATE '2022-04-01' + INTERVAL '18:02:42' HOUR TO SECOND
AND DATE '2022-11-03' + INTERVAL '19:28:57' HOUR TO SECOND;
or TO_TIMESTAMP:
SELECT *
FROM table_name
WHERE column_name BETWEEN TO_TIMESTAMP('2022-04-01 18:02:42', 'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP('2022-11-03 19:28:57', 'YYYY-MM-DD HH24:MI:SS');
or TO_DATE:
SELECT *
FROM table_name
WHERE column_name BETWEEN TO_DATE('2022-04-01 18:02:42', 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE('2022-11-03 19:28:57', 'YYYY-MM-DD HH24:MI:SS');
Firstly have to change NLS_DATE_FORMAT as follows:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
ALTER SESSION SET NLS_DATE_FORMAT = 'HH24:MI:SS';
Then running the query using TIMESTAMP literal as follows:
SELECT * FROM table_name WHERE column_name BETWEEN TIMESTAMP '2022-04-01 18:02:42' AND TIMESTAMP '2022-11-03 19:28:57';

Update date field of one table from the value taken from another table

I have two table A and B where both have date fields but in different format('MM/DD/YYYY HH:MI:SS' and 'MM/DD/YYYY') and they both have a common field called invoiced_value. I need to update the date values of table A(with 'MM/DD/YYYY HH:MI:SS') from the values of table B(with 'MM/DD/YYYY'). Can i use the following query?. can i append the date like this to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS') ?.
UPDATE Table1
SET m.invoiced_date = to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS')
FROM Table2 e, Table1 m
WHERE m.invoiced_value = e.invoiced_value
[TL;DR] Use a MERGE statement:
MERGE INTO Table1 dst
USING Table2 src
ON ( src.invoiced_value = dst.invoiced_value )
WHEN MATCHED THEN
UPDATE SET invoiced_date = TRUNC( src.invoiced_date ) + INTERVAL '3:56:24' HOUR TO SECOND;
Can i use the following query?
No, an UPDATE statement does not have a FROM clause. You would need to use a correlated sub-query or a MERGE statement.
can i append the date like this to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS') ?.
Maybe ... but you should not do it this way. TO_DATE( string_value, format_model ) takes a string as the first argument (and the || string concatenation operator also requires string arguments to concatenate) so your e.invoiced_date will be implicitly converted from a DATE to a string and your expression is effectively:
to_date(
TO_CHAR(
e.invoiced_date,
( SELECT value FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
) || ' 3:56:24',
'MM/DD/YYYY HH:MI:SS'
)
If your NLS_DATE_FORMAT session parameter is MM/DD/YYYY then your query will work. If it is something different then your query will either raise an exception or work but give incorrect results. Since NLS_DATE_FORMAT is a session parameter and each user can set it to whatever value they want then you should not rely on this to be consistent.
Instead, add an interval literal to the date (which does not require any conversions to-or-from a string):
TRUNC( src.invoiced_date ) + INTERVAL '3:56:24' HOUR TO SECOND
Or explicitly convert the date to a string in the correct format:
TO_DATE( TO_CHAR( e.invoiced_date, 'MM/DD/YYYY' ) || ' 3:56:24', 'MM/DD/YYYY HH24:MI:SS' )

Inject character to date column

I have a date column.
select RETAIL_ACQUISITION_DTTM from XXXXX.TABLE_2348
13/07/2018
I want to select the value as such it returns as below,
2018-07-13T00:00:00
so it has to display the date as YYYY-MM-DD with T and then HH24:MI:SS
You need to convert your string (why is it stored as a string?) to a date using a format model that matches the actual string value:
to_date(RETAIL_ACQUISITION_DTTM, 'DD/MM/YYYY')
Having that format model wrong is why you get the 0013 year in your result.
Then you can convert that date back to a string with to_char(), and you can embed the fixed T as a character literal with double quotes, using a format model like 'YYYY-MM-DD"T"HH24:MI:SS':
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select '13/07/2018' from dual
)
select to_char(to_date(RETAIL_ACQUISITION_DTTM, 'DD/MM/YYYY'),
'YYYY-MM-DD"T"HH24:MI:SS') as RETAIL_ACQUISITION_DTTM
from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
2018-07-13T00:00:00
You could also just ignore that it is a date and use string manipulation:
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select '13/07/2018' from dual
)
select substr(RETAIL_ACQUISITION_DTTM, 7, 4)
|| '-' || substr(RETAIL_ACQUISITION_DTTM, 4, 2)
|| '-' ||substr(RETAIL_ACQUISITION_DTTM, 1, 2)
|| 'T00:00:00' as RETAIL_ACQUISITION_DTTM
from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
2018-07-13T00:00:00
If the column is actually a date rather than a string then you are doing unnecessary conversions, including implicit ones which rely on your NLS settings, and you are losing the original time from the value if it was not midnight anyway:
alter session set nls_date_format = 'DD-MON-RR';
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select to_date('2018-07-13 12:34:56', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select to_char(to_date(RETAIL_ACQUISITION_DTTM, 'YYYY-MM-DD-HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS') as RETAIL_ACQUISITION_DTTM from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
0013-07-20 18:00:00
That is really doing:
to_char(
to_date(
to_char(
RETAIL_ACQUISITION_DTTM,
'DD-MON-RR'), ---- from your session NLS_DATE_FORMAT setting
'YYYY-MM-DD-HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS')
If you skip to extra steps you can just format the date directly:
with TABLE_2348 (RETAIL_ACQUISITION_DTTM) as (
select to_date('2018-07-13 12:34:56', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select to_char(RETAIL_ACQUISITION_DTTM,
'YYYY-MM-DD"T"HH24:MI:SS') as RETAIL_ACQUISITION_DTTM
from XXXXX.TABLE_2348;
RETAIL_ACQUISITION_
-------------------
2018-07-13T12:34:56
which also doesn't rely on your NLS settings, so won't break in interesting ways if it's run in another session with different settings.
replace sysdate with your column name if its date type.
Using Single to_char:
select to_char(sysdate,'--YYYY-MM-DD"T"hh24:mi:ss') from dual;
Using two to_char and concatenation for simplification.
select to_char(sysdate,'--'||'YYYY-MM-DD')||'T'||to_char(sysdate,'hh24:mi:ss') from dual; -- 13/07/2018
select '--'||to_char(sysdate,'YYYY-MM-DD')||'T'||to_char(sysdate,'hh24:mi:ss') from dual; -- 13/07/2018

removing milliseconds from a oracle tmstmp field

I have a TIMESTAMP(6) field in Oracle and I need to remove the millisecond component from the time.
For example I have
10/20/2014 10:34:06.356000 AM
and I would like to remove the milliseconds so that I have
10/20/2014 10:34:06 AM
Do you know the best way to do this?
Thank you!
How about this?
select cast(col as timestamp(0))
EDIT:
The easiest way to avoid rounding is to use trunc() or to subtract half a second:
select cast(col - 0.5/(24*60*60) as timestamp(0))
try this
SELECT TO_CHAR(SYSDATE, 'MM-DD-YYYY HH24:MI:SS') "NOW"
FROM DUAL;
if you need 12-hour date format
SELECT TO_CHAR(SYSDATE, 'MM-DD-YYYY HH:MI:SS AM') "NOW"
FROM DUAL;
SQL FIDDLE
You can either cast it to a timestamp with no fractional seconds (this will round to the nearest second):
CAST( your_timestamp AS TIMESTAMP(0) )
Or to a DATE data type (this will truncate to the nearest second):
CAST( your_timestamp AS DATE )
If you want it as a TIMESTAMP(0) data type then cast it back:
CAST( CAST( your_timestamp AS DATE ) AS TIMESTAMP(0) )
Or you can convert it to a formatted string and specify the format model you want to use (this will truncate to the nearest second):
TO_CHAR( your_timestamp, 'YYYY-MM-DD HH24:MI:SS' )
Like this:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE your_table ( your_timestamp ) AS
SELECT TIMESTAMP '2017-10-25 12:53:12.10076' FROM DUAL;
Query 1:
SELECT CAST( your_timestamp AS TIMESTAMP(0) ) AS "Timestamp",
CAST( your_timestamp AS DATE ) AS "Date",
TO_CHAR( your_timestamp, 'DD-MM-YYYY HH24:MI:SS' ) AS "String"
FROM your_table
Results:
| Timestamp | Date | String |
|-----------------------|----------------------|---------------------|
| 2017-10-25 12:53:12.0 | 2017-10-25T12:53:12Z | 25-10-2017 12:53:12 |
note: How the TIMESTAMP and DATE are formatted in the output will depend on your NLS_TIMESTAMP_FORMAT and NLS_DATE_FORMAT session parameters but you can directly control the formatting of TO_CHAR when you specify a format model.
This might help!
select substr(to_char('10/20/2014 10:34:06.356000 AM'),1,instr(to_char('10/20/2014 10:34:06.356000 AM'),'.')-1)||' '||
substr(to_char('10/20/2014 10:34:06.356000 AM'),-2,instr(to_char('10/20/2014 10:34:06.356000 AM'),'.')-1) "Date"
from dual;

Extract date (yyyy/mm/dd) from a timestamp in PostgreSQL

I want to extract just the date part from a timestamp in PostgreSQL.
I need it to be a postgresql DATE type so I can insert it into another table that expects a DATE value.
For example, if I have 2011/05/26 09:00:00, I want 2011/05/26
I tried casting, but I only get 2011:
timestamp:date
cast(timestamp as date)
I tried to_char() with to_date():
SELECT to_date(to_char(timestamp, 'YYYY/MM/DD'), 'YYYY/MM/DD')
FROM val3 WHERE id=1;
I tried to make it a function:
CREATE OR REPLACE FUNCTION testing() RETURNS void AS '
DECLARE i_date DATE;
BEGIN
SELECT to_date(to_char(val1, "YYYY/MM/DD"),"YYYY/MM/DD")
INTO i_date FROM exampTable WHERE id=1;
INSERT INTO foo(testd) VALUES (i);
END
What is the best way to extract date (yyyy/mm/dd) from a timestamp in PostgreSQL?
You can cast your timestamp to a date by suffixing it with ::date. Here, in psql, is a timestamp:
# select '2010-01-01 12:00:00'::timestamp;
timestamp
---------------------
2010-01-01 12:00:00
Now we'll cast it to a date:
wconrad=# select '2010-01-01 12:00:00'::timestamp::date;
date
------------
2010-01-01
On the other hand you can use date_trunc function. The difference between them is that the latter returns the same data type like timestamptz keeping your time zone intact (if you need it).
=> select date_trunc('day', now());
date_trunc
------------------------
2015-12-15 00:00:00+02
(1 row)
Use the date function:
select date(timestamp_field) from table
From a character field representation to a date you can use:
select date(substring('2011/05/26 09:00:00' from 1 for 10));
Test code:
create table test_table (timestamp_field timestamp);
insert into test_table (timestamp_field) values(current_timestamp);
select timestamp_field, date(timestamp_field) from test_table;
Test result:
Have you tried to cast it to a date, with <mydatetime>::date ?
In postgres simply :
TO_CHAR(timestamp_column, 'DD/MM/YYYY') as submission_date
This works for me in python 2.7
select some_date::DATE from some_table;
Just do select date(timestamp_column) and you would get the only the date part.
Sometimes doing select timestamp_column::date may return date 00:00:00 where it doesn't remove the 00:00:00 part. But I have seen date(timestamp_column) to work perfectly in all the cases. Hope this helps.
CREATE TABLE sometable (t TIMESTAMP, d DATE);
INSERT INTO sometable SELECT '2011/05/26 09:00:00';
UPDATE sometable SET d = t; -- OK
-- UPDATE sometable SET d = t::date; OK
-- UPDATE sometable SET d = CAST (t AS date); OK
-- UPDATE sometable SET d = date(t); OK
SELECT * FROM sometable ;
t | d
---------------------+------------
2011-05-26 09:00:00 | 2011-05-26
(1 row)
Another test kit:
SELECT pg_catalog.date(t) FROM sometable;
date
------------
2011-05-26
(1 row)
SHOW datestyle ;
DateStyle
-----------
ISO, MDY
(1 row)
You can use date_trunc('day', field).
select date_trunc('day', data_gps) as date_description from some_table;