Adding fractional part to a TIMESTAMP - oracle

How can I add the fractional part to a TIMESTAMP. I tried this and it didn't seem to work.
CREATE TABLE t(A TIMESTAMP);
INSERT INTO t(A) VALUES (
DATE '2022-04-01' + INTERVAL '18:02:42.123456' HOUR TO SECOND);
SELECT * from t;
A
01-APR-22 06.02.42.000000 PM

Try
INSERT INTO t(A) VALUES (
TIMESTAMP '2022-04-01 00:00:00' + INTERVAL '18:02:42.123456' HOUR TO SECOND);
When you add in INTERVAL to a DATE then the result is converted to DATE which does not support fractional seconds, see Datetime/Interval Arithmetic

Related

Fetch Hours from Created date

I'm just trying to fetch Hour of my table from created date in Oracle 12c Database but it is showing error INVALID EXTRACT FIELD FOR EXTRACT FIELD. kindly guide me to fetch hour of my date my code is here...
SELECT
EXTRACT( HOUR FROM (TO_CHAR(CREATED_DATE,'RRRR-MM-DD HH:MI:SS')) ) HOUR
FROM
INVOICE_V;
my Date is stored as 6/1/2020 4:04:50 PM in this format and Extract function is not accept this function.
Do not store dates as strings.
But, since you have, convert it from a string to a date using TO_DATE:
SELECT EXTRACT( HOUR FROM TO_TIMESTAMP(CREATED_DATE,'DD/MM/YYYY HH12:MI:SS AM') ) AS HOUR
FROM INVOICE_V;
If, however, you meant that its just displaying in that format (and is actually a DATE data type) then CAST the date to a timestamp:
SELECT EXTRACT( HOUR FROM CAST( CREATED_DATE AS TIMESTAMP) ) AS HOUR
FROM INVOICE_V;
An hour can not be used in the EXTRACT function.
The only way to extract hour is to use TO_CHAR or subtract it from TRUNC date as follows:
TO_CHAR(created_date,'HH24') -- OR 'HH' as per your requirement
-- OR
FLOOR(24*(created_date- TRUNC(created_date)))
Please note that Oracle does not store dates in any format. It has its own binary representation. What you see while selecting from the table is based on the NLS_DATE_FORMAT parameter.
You can set it according to your requirement.
ALTER SESSION SET NLS_dATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; -- like this
If you have a date column (or the-like), then:
select extract(hour from cast(created_date as timestamp)) as hr
from invoice_v
Alternatively:
select to_char(created_date, 'hh24') as hr
from invoice_v
The first expression returns an integer number, while the second produces a string.
Note that hour is a language keyword, hence not a good choice for an identifier (here, you used it as a column alias). I changed that.

Oracle -- Datatype of column which can store value "13:45"

We need to store a value "13:45" in the column "Start_Time" of an Oracle table.
Value can be read as 45 minutes past 13:00 hours
Which datatype to be used while creating the table? Also, once queried, we would like to see only the value "13:45".
I would make it easier:
create table t_time_only (
time_col varchar2(5),
time_as_interval INTERVAL DAY TO SECOND invisible
generated always as (to_dsinterval('0 '||time_col||':0')),
constraint check_time
check ( VALIDATE_CONVERSION(time_col as date,'hh24:mi')=1 )
);
Check constraint allows you to validate input strings:
SQL> insert into t_time_only values('25:00');
insert into t_time_only values('25:00')
*
ERROR at line 1:
ORA-02290: check constraint (CHECK_TIME) violated
And invisible virtual generated column allows you to make simple arithmetic operations:
SQL> insert into t_time_only values('15:30');
1 row created.
SQL> select trunc(sysdate) + time_as_interval as res from t_time_only;
RES
-------------------
2020-09-21 15:30:00
Your best option is to store the data in a DATE type column. If you are going to be any comparisons against the times (querying, sorting, etc.), you will want to make sure that all of the times are using the same day. It doesn't matter which day as long as they are all the same.
CREATE TABLE test_time
(
time_col DATE
);
INSERT INTO test_time
VALUES (TO_DATE ('13:45', 'HH24:MI'));
INSERT INTO test_time
VALUES (TO_DATE ('8:45', 'HH24:MI'));
Test Query
SELECT time_col,
TO_CHAR (time_col, 'HH24:MI') AS just_time,
24 * (time_col - LAG (time_col) OVER (ORDER BY time_col)) AS difference_in_hours
FROM test_time
ORDER BY time_col;
Test Results
TIME_COL JUST_TIME DIFFERENCE_IN_HOURS
____________ ____________ ______________________
01-SEP-20 08:45
01-SEP-20 13:45 5
Table Definition using INTERVAL
create table tab
(tm INTERVAL DAY(1) to SECOND(0));
Input value as literal
insert into tab (tm) values (INTERVAL '13:25' HOUR TO MINUTE );
Input value dynamically
insert into tab (tm) values ( (NUMTODSINTERVAL(13, 'hour') + NUMTODSINTERVAL(26, 'minute')) );
Output
you may either EXTRACT the hour and minute
EXTRACT(HOUR FROM tm) int_hour,
EXTRACT(MINUTE FROM tm) int_minute
or use formatted output with a trick by adding some fixed DATE
to_char(DATE'2000-01-01'+tm,'hh24:mi') int_format
which gives
13:25
13:26
Please see this answer for other formating options HH24:MI
The used INTERVAL definition may store seconds as well - if this is not acceptable, add CHECK CONSTRAINT e.g. as follows (adjust as requiered)
tm INTERVAL DAY(1) to SECOND(0)
constraint "wrong interval" check (tm <= INTERVAL '23:59' HOUR TO MINUTE and EXTRACT(SECOND FROM tm) = 0 )
This rejects the following as invalid input
insert into tab (tm) values (INTERVAL '13:25:30' HOUR TO SECOND );
-- ORA-02290: check constraint (X.wrong interval) violated

Subtract number of days from sysdate using variable oracle trigger

I am creating a trigger to perform an insert in with a date in the past.
days_trans := dbms_random.value(14,90);
time_avail := sysdate - interval ':days_trans' day;
This gives me
PLS-00166: bad format for date, time, timestamp or interval literal
How should I subtract the variable constant?
You cannot bind variables to literals. INTERVAL are used with TIMESTAMP, use either
time_avail := sysdate - days_trans;
or
time_avail := systimestamp - days_trans * interval '1' day;

how to change the date to time in oracle 10g

I have to put in STIMING a time when I insert I use TO_DATE function but it give me date not time and it should be time.
This is the table and the code that i use
SQL> select * from shift;
SNO SNAME STIMING
---------- -------------------- ---------
121323 morning 01-APR-17
112232 evening 01-APR-17
665342 afternoon 01-APR-17
SQL> update shift
2 set STIMING= ('07:00:00 HH,MI,SS')
3 where SNO=121323;
set STIMING= ('07:00:00 HH,MI,SS')
*
ERROR at line 2:
ORA-01843: not a valid month
I have to put in STIMING a time
Oracle does not have a TIME datatype. The DATE data type is always stored internally as 7-bytes and is always composed of year (2-bytes) and month, day, hours, minutes and seconds (1-byte each).
You cannot not have a year, month or day component of a DATE.
If you want a time on its own then you will have to store it as a different data type or store the year/month/day and ignore that component.
When you are SELECTing the STIMING column it is not showing the time component. You can change this by changing the default date format which is set in the NLS_DATE_FORMAT session parameter.
You can review this parameter using:
SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT';
You can set this value within your current session using:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
(Note: this does not change the value for any other users.)
When you insert the date you can use:
INSERT INTO shift ( SNO, SNAME, STIMING)
VALUES ( 121323, 'morning', TO_DATE( '01-APR-2017 07:00' DD-MON-YYYY HH24:MI' ) )
Or, an ANSI TIMESTAMP literal (which will be implicitly cast to the DATE format of the column):
INSERT INTO shift ( SNO, SNAME, STIMING)
VALUES ( 121323, 'morning', TIMESTAMP '2017-04-01 07:00:00' )
I suggest you to avoid updates, change your insert part from to_date with no formatting param to to_date( colname, 'DD-MON-YY HH24:MI:SS')

How do you retrieve last day's of data from Oracle table?

I have an oracle database that I like to retrieve last days or last 10 minutes data:
I am ussing this command first:
alter session set nls_date_format='dd-mm-yyyy hh24:mi:ss'
Then this:
select TIMESTAMP, TARGET_NAME, TARGET_TYPE, COLUMN_LABEL, VALUE, KEY_VALUE from METRIC_TABLE where TIMESTAMP > sysdate -1
This command is not giving me last days of data, it only gives me last couple hours of data. I suspect that TIMESTAMP column is not in Oracle datatime format.
Is there a way to format TIMESTAMP to Oracle timestamp format before doing this:
TIMESTAMP>SYSDATE -1
Presuming your TIMESTAMP column contains an ordinary date/time variable:
SELECT whatever FROM table WHERE TIMESTAMP >= SYSDATE -1
gets everything that's newer than 24 hours ago.
SELECT whatever FROM table WHERE TIMESTAMP >= SYSDATE - (10.0 / 1440.0)
gets everything that's newer than ten minutes ago.
SELECT whatever FROM table WHERE TIMESTAMP >= TRUNC(SYSDATE)
gets everything newer than midnight last night.
SELECT whatever FROM table WHERE TIMESTAMP >= TRUNC(SYSDATE) -1
AND TIMESTAMP < TRUNC(SYSDATE)
gets everything from yesterday.
Edit Pro tip: don't use reserved words, like TIMESTAMP, for column names.
Try figuring out how many records you have for each hour in the last 5 days like this:
SELECT TO_CHAR(TRUNC(timestamp, 'HH24'), 'DD-MON-YYYY HH24:MI:SS') hr,
COUNT(*)
FROM METRIC_TABLE
WHERE timestamp >= TRUNC(sysdate) -5
GROUP BY TRUNC(timestamp, 'HH24')
That will help you understand what timestamp values you have in your database.

Resources