Oracle convert hhmmss to hh:mm:ss - oracle

I have some timestamp data in an old Oracle database that needs converting into HH:MM:SS. After trying to use to_char function, the value I give is not readable (E.g. 105001, to_char('105001','HH24:MI:SS)), this SQL will break. I can convert sysdate into the incorrect format but I can't reverse the procedure.
For example:
select to_char(sysdate, 'HHmiss')from table
returns '105001'
I need something that will convert the hhmmss format into HH:MM:SS so when I produce a select statement it is in a readable format.

You can first select from dual table which is virtual table
There are 2 different way to have time
24 hours : like 5 and 15
select to_char(sysdate, 'HH24:MI:SS')from dual
Result
14:25:56
12 hours : like 2 AM and 2 PM
select to_char(sysdate, 'HH:MI:SS AM')from dual
Result
02:22:35 PM

Assuming that your values are a NUMBER in the database which is six-digits long and represents an HHMMSS value you can format it as you want by using SUBSTR:
SELECT SUBSTR(TO_CHAR(SOME_TIMESTAMP, 'FM000000'), 1, 2) || ':' ||
SUBSTR(TO_CHAR(SOME_TIMESTAMP, 'FM000000'), 3, 2) || ':' ||
SUBSTR(TO_CHAR(SOME_TIMESTAMP, 'FM000000'), 5, 2)
FROM cteNumbers
db<>fiddle here

I have some timestamp data in an old Oracle database that needs converting into HH:MM:SS
Just use HH24 to get a 24-hour clock and add the : separators to your format model and then apply that format directly to your TIMESTAMP column using the TO_CHAR function:
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( your_timestamp_column TIMESTAMP );
INSERT INTO table_name ( your_timestamp_column )
VALUES ( TIMESTAMP '2018-09-24 12:34:56' );
Query 1:
SELECT TO_CHAR( your_timestamp_column, 'HH24:MI:SS') FROM table_name
Results:
| TO_CHAR(YOUR_TIMESTAMP_COLUMN,'HH24:MI:SS') |
|---------------------------------------------|
| 12:34:56 |
You do not need to output it as a HHMMSS string and then try to reformat it to add separators as that is needlessly complicated.

Related

Split Date from Oracle Form to DB

I have a table with columns(year,day-month) -date type- in my database.
and a form with a text field for the user to enter a date.
how can I split the entered date to save it on db as following
year day_month
---- ---------
2018 03-04
I tried SUBSTR(TO_CHAR(TO_DATE(block.field)) in a trigger ,
but it didn't work bcz the column type is date, and I tried to add TO_DATE() as outer but the result was
year day_month
---------- ----------
03-04-2018 03-04-2018
How can I do it without changing my columns type?
I'd suggest you NOT to do that. Always store DATE values into DATE datatype columns. ALWAYS.
Later, if you want to present them differently, apply appropriate functions (such as TO_CHAR) to those values and display them any way you want.
In your example, that would be
TO_CHAR(date_column, 'yyyy') year
or
EXTRACT (year from date_column) year
and
TO_CHAR(date_column, 'dd-mm') day_month
[EDIT]
Once again (to repeat what I've said in a comment): the fact that you named columns in the database "year" (whose datatype is DATE) and "day_month" (whose datatype is also DATE) is completely useless.
Right now is (dd.mm.yyyy hh24:mi) 03.04.2018 10:32.
DATE datatype contains both date and time, so - how do you plan to put "2018" into the "year" column? What will you do with its month/day/hour/minutes/seconds component? It can't just "vanish", has to have some value. Is it the first of January at 00:00:00? Or what?
The same goes to your "day_month" column - it'll contain year, as well as hours/minutes/seconds, whether you want it or not.
Let's start with the "year": if you want to extract it from the Form item, that would be TO_CHAR, such as
to_char(:block.some_item, 'yyyy')
which results in a string, '2018'. You can't store it into a DATE datatype column, so you have to apply TO_DATE to it:
to_date(to_char(:block.some_item, 'yyyy'), 'yyyy')
and it will result in 01.04.2018 00:00:00 >>> see? Day, month, hours ... everything is here.
The alternative is to create those columns as VARCHAR2, but that's even worse.
Seriously, don't do that.
Try the following and make the necessary changes in Oracle Forms, substitute block and columns names instead of variables.
DECLARE
p_year VARCHAR2 (8);
p_date VARCHAR2 (8);
BEGIN
SELECT TO_CHAR (SYSDATE, 'YYYY') INTO p_year FROM DUAL;
SELECT TO_CHAR (SYSDATE, 'DD-MM') INTO p_date FROM DUAL;
DBMS_OUTPUT.put_line ('p_year --> ' || p_year || ' p_date --> ' || p_date);
END;
If your column is a DATE type, expect that it will require you to input a date data also.
In your case, you don't need to split a date. For the YEAR column, if the year value only matters to you, then you can use the TRUNC function
:BLK.YEAR_DATE_FIELD := TRUNC(:BLK.DATE_VALUE, 'YYYY');
and for the MONTH column, just save the date value there.
:BLK.MONTH_DATE_FIELD := :BLK.DATE_VALUE;
Also, maybe you just need to set the format mask of those two fields in Oracle forms. You can set the Format Mask of YEAR field to YYYY and MM-DD to the MONTH field.
The DATE data type is stored dates in tables as 7-bytes
byte 1 - century + 100
byte 2 - (year MOD 100 ) + 100
byte 3 - month
byte 4 - day
byte 5 - hour + 1
byte 6 - minute + 1
byte 7 - seconds+ 1
You CANNOT have a DATE data type that just stores year or month + day; it will always store all the components of the date/time.
So you either store the correct values in each column or you will have to make up values for the components you are not storing and will need to make sure that all the made up values are appropriate for the real values. It is just easier to use the real values in both columns.
So just do:
INSERT INTO your_table(
year,
day_month
) VALUES (
:BLK1.T_DATE,
:BLK1.T_DATE
);
Without splitting the date because a day_month without a year does not make sense (is 29th February a valid date? For the majority of years, no it isn't).
When you want to output it with a format then just format it as a string on output:
SELECT TO_CHAR( year, 'yyyy' ) AS year,
TO_CHAR( day_month, 'dd-mm' ) AS day_month
FROM your_table;

extract month and year in oracle

Why does below query work successfully?
select to_char(sysdate,'MM-YYYY') from dual;
But the following queries give an invalid number error:
select to_char('28-JUL-17','MM-YYYY') from dual;
select to_char('7/28/2017','MM-YYYY') from dual;
Though, below query gives you the same date format.
select sysdate from dual; -- 7/28/2017 11:29:01 AM
TO_CHAR function accepts only date or number. Maybe you can try this
select to_char(to_date('28-JUL-17', 'DD-MON-YY'),'MM-YYYY') from dual;
As a side note, if you're planning to convert a bunch of dates to strings so you can look for all records in a certain month of a certain year, be aware that the TRUNC function can be used to reduce the precision of a date (e.g. to "month and year"). The following query pulls all records created this month, from the table. It should be faster than converting dates to char and doing string comparison..
SELECT * FROM table WHERE trunc(create_date, 'MON') = trunc(sysdate, 'MON')
Because function TO_CHAR() accepts date or timestamp values. However, neither '28-JUL-17' nor '7/28/2017' are dates or timestamps - they are STRINGS.
Oracle gently tries to convert these stings into DATE values. This implicit conversion may work or may fail, it depends on your current session NLS_DATE_FORMAT, resp. NLS_TIMESTAMP_FORMAT settings.
As given already in other answers you have to convert the string explicitly:
TO_DATE('28-JUL-17', 'DD-MON-RR')
TO_DATE('7/28/2017', 'MM/DD/YYYY')
to_char() isn't expecting you to start with a char value. If you really want that to work, you'll need to wrap it around a to_date() function.
to_char(
to_date(
'28-JUL-17'
, 'DD-Mon-YY'
)
,'MM-YYYY'
)
You are using an incorrect mask, for more information read here.
The correct one should be:
select to_char(to_date('28-JUL-17','DD-MON-YY'), 'MON-YY') from dual;
You can also extract the month using EXTRACT:
select EXTRACT (MONTH FROM to_date('28-JUL-17','DD-MON-YY')) from dual;
Cheers

Between not included the end date in oracle

I am writing the query like
select * from tablename where date between '27-mar-2015' and '1-apr-2015'.
but records with date '1-apr-2015' is not retrieved from the oracle database date type is TIMESTAMP(6).
between '27-mar-2015' and '1-apr-2015'
'27-mar-2015' is NOT a DATE, it is a string literal. You are forcing Oracle to do an implicit datatype conversion.
date type is TIMESTAMP(6)
Since your data type is TIMESTAMP, you need to take care of the precision of the TIMESTAMP datatype which holds fractions of a second to a precision between 0 and 9 decimal places, the default being 6.
BETWEEN
to_timestamp('27-mar-2015 01.01.01.000001','dd-mon-yyyy HH24:MI:SS.FF')
AND
to_timestamp('01-apr-2015 23.59.59.999999','dd-mon-yyyy HH24:MI:SS.FF')
For example,
SQL> ALTER SESSION SET nls_timestamp_tz_format = 'DD-MON-YYYY HH24:MI:SS.FF';
Session altered.
SQL> SELECT
2 to_timestamp('27-mar-2015 01.01.01.000001','dd-mon-yyyy HH24:MI:SS.FF') st,
3 to_timestamp('01-apr-2015 23.59.59.999999','dd-mon-yyyy HH24:MI:SS.FF') end
4 FROM dual
5 /
ST END
---------------------------------- ----------------------------------
27-MAR-15 01.01.01.000001000 AM 01-APR-15 11.59.59.999999000 PM
SQL>
You have to note that timestamp-columns (and with oracle even date-columns) always include the time of day and that date '1-apr-2015' actually means '1-apr-2015 00:00:00' - then everything makes sense. The exact string-representation of timestamps might vary according to the configured locale.
To get date including the first of april you best use between ... and '2-apr-2015' if you don't mind having the first microsecond of that day included.
Try convert to_date:
select * from tablename
where date between to_Date('27-mar-2015','dd-mm-yyy')
and to_date('1-apr-2015','dd-mm-yyyy')
I have faced same issue. Using TRUNC Date Function helped.
select * from tablename where trunc(date,'DAY') between '27-mar-2015' and '1-apr-2015'
Try to use this code:
select * from tablename where to_date(date,'DD-MON-YYYY') between '27-mar-2015' and '1-apr-2015'.

Oracle virtual column, date and timestamp

I have a problem in Oracle, with a virtual column (I need the timestamp starting from a date column); here my example:
CREATE TABLE TBDATETIME(
DATETIME_1 DATE,
DATETIME_2 TIMESTAMP(9) GENERATED ALWAYS AS (
CAST( TO_CHAR(DATETIME_1, 'DD/MM/YYYY HH24:MI:SS')
|| '.' || TO_CHAR(DATETIME_1, 'FF9') AS TIMESTAMP(9))
) VIRTUAL
);
INSERT INTO TBDATETIME(DATETIME_1)
VALUES(SYSDATE);
COMMIT;
SELECT *
FROM TBDATETIME;
ORA-01821: date format not recognized
01821. 00000 - "date format not recognized"
*Cause:
*Action:
Where is the problem fetching data? I tried a lot of format masks, but nothing helps...
DATETIME_1 DATE
TO_CHAR(DATETIME_1, 'FF9')
That's the problem - DATE doesn't have fraction seconds
And it's dangerous to cast char to timestamp (the result depends on nls settings)
I suppose you want this:
CREATE TABLE TBDATETIME(DATETIME_1 DATE, DATETIME_2 TIMESTAMP(9) GENERATED ALWAYS AS (CAST(DATETIME_1 AS TIMESTAMP(9))) VIRTUAL);

What must be considered when modifying Oracle DATE column to TIMESTAMP

The system I'm working on uses an oracle 11 db and has a java implemented backend which uses JDBC.
The system has one main performance problem:
The oracle db has indexed DATE columns but the java backend access the db like this
String sql = "SELECT foo FROM bar WHERE a_date > ?";
// ... prepare the statement
statement.setTimestamp(1, new Timestamp());
then Oracle will not use the index and fall back to full table scan because of statement.setTimestamp.
First Solution:
So I have changed the access of the backend from statement.setTimestamp to statement.setDate.
The performance has been improved and the DATE index was now used, but now I lost the accuracy of the timestamp data type, and only got a day-accuracy of the java.sql.Date type.
Thus, the first solution was unusable for my system.
Second Solution:
I don’t change the java backend thus using statement.setTimestamp and change all DATE columns of the oracle db like the following sql command example:
ALTER TABLE <table_1> MODIFY <date_column> TIMESTAMP;
Now my question:
What must be considered when modifying Oracle DATE column to TIMESTAMP
I think a list of the important aspects would be perfect.
Here my first draft of the "CHECKLIST of Migrating Oracle DATE columns to TIMESTAMP
1. CREATE / INSERT
2. READ / SELECT
3. UPDATE / UPDATE
4. DELETE / DELETE
5. TO_DATE( )
select * from table where crea_time between TO_DATE( '10.2014', 'MM.yyyy' ) and TO_DATE( '12.2014', 'MM.yyyy' ) ;
6. TRUNC( )
select TRUNC( crea_time ) from table;
output of crea_time data typ DATE
05.11.2014 00:00:00
output of crea_time data typ TIMESTAMP
05.11.2014 00:00:00
7. TO_CHAR( )
select to_char( crea_time,'hh24miss' ) from table;
output data typ DATE
140612
output data typ TIMESTAMP
140612
8. NESTED - TRUNC( TO_DATE() )
select TRUNC(TO_DATE( crea_time), 'YEAR') from table;
output of crea_time data typ DATE
01.01.2014 00:00:00
output of crea_time data typ TIMESTAMP
ORA-01830:
01830. 00000 - "date format picture ends before converting entire input string"
*Cause:
*Action:
Solution >>> select TRUNC( TO_TIMESTAMP( crea_time), 'YEAR' ) from table;
output of crea_time data typ TIMESTAMP
01.01.2014 00:00:00
9. Add A DAY/HOUR/MINUTE/SECOND
select crea_time+1 from table;
output data typ DATE
06.11.2014 14:06:12
output data typ TIMESTAMP
06.11.2014 14:06:12
10. MIN() / MAX()
SELECT MIN(crea_time) FROM table;
output data typ DATE
05.11.2014 14:06:12
output data typ TIMESTAMP
05.11.2014 14:06:12,000000000
Please excuse my bad English.

Resources