Syntax for inserting just time in Oracle table - oracle

I want to create an Oracle table which contains 3-4 columns in which I want to insert just time in one of the columns.
First, I set the datatype of that column to varchar2 but then I am unable to do any operations on that time.
create table attendance(
ID varchar2(10),
EmpIntime varchar2(10) ,
EmpoutTime varchar2(10));
I want to insert time in 9:00AM format and calculate total time.
Here is DEMO
i want output like that
"emp_in - emp_out = total working hours"

Just make it with to_date like below
select to_date(emp_out,'HH:MIAM')-to_date(emp_in,'HH:MIAM') from attendance
made an sqlfiddle http://sqlfiddle.com/#!4/96975/8 with the hours difference between time

Try this one,this will give you time in hours,minutes and seconds :-
create table attend(ID int,emp_in varchar2(10) ,emp_out varchar2(10));
insert all
into attend values(1,'09:00AM','05:00PM')
into attend values(2,'09:30AM','05:00PM')
into attend values(3,'10:00AM','08:00PM')
select * from dual;
commit;
select outtime-intime time_difference
from(
select to_timestamp(EMP_IN, 'hh:mi am') intime ,
to_timestamp(EMP_OUT, 'hh:mi am') outtime
FROM attend);

Related

Combine Different Date and Time Column to make one Column with Date/Time format in Oracle SQL

I am working with database in which I have appointment table. With Two columns
ApptDate ApptTime
9/26/21 9:00 AM
9/25/20 1:00 PM
I want to drop the ApptTime column after making ApptDate Columns as ApptDateTime column.
I have tried concatnate but I can't figure out, how can I change datatype of AppDate column to DATETIME data type and update all the values simultaneously.
I tried following:
ALTER SESSION SET nls_date_format = 'DD-MON-YYYY hh24:mi'
UPDATE Appointment
SET ApptDate = ApptDate ||' ' ||ApptTime;
ALTER TABLE Appointment
MODIFY(
ApptDate DATE
);
But I got error that Data type can be changed of only Empty Table.
Kindly suggest.
Case 1 : If ApptDate column is of string type, then recreate and populate your table as
/*CREATE TABLE Appointment( ApptDate VARCHAR2(15), ApptTime VARCHAR2(15) );
INSERT INTO Appointment
SELECT '9/26/21','9:00 AM' FROM dual UNION ALL
SELECT '9/25/20','1:00 PM' FROM dual; -- already existing state */
CREATE TABLE Appointment2 AS
SELECT TO_DATE(ApptDate||' '||ApptTime,'MM/DD/RR HH:MI PM') AS ApptDate
FROM Appointment;
DROP TABLE Appointment;
RENAME Appointment2 TO Appointment
Case 2 : If data type of ApptDate column is date, then use the following code block
/*CREATE TABLE Appointment( ApptDate DATE, ApptTime VARCHAR2(15) );
INSERT INTO Appointment
SELECT date'2021-09-26','9:00 AM' FROM dual UNION ALL
SELECT date'2020-09-25','1:00 PM' FROM dual; -- already existing state */
CREATE TABLE Appointment2 AS
SELECT TO_DATE(ApptDate||' '||ApptTime,'RRRR-MM-DD HH:MI PM') AS ApptDate
FROM Appointment;
DROP TABLE Appointment;
RENAME Appointment2 TO Appointment
Demo

How to use complex condition in insert into select query in oracle

I want to insert some records with insert into select query in oracle. My condition should be when month of CREATE_DATE in SITA_HOSTS table is equal with month of sysdate - 1. Now my question is what should I write for the where statement?
This is my code:
DECLARE
p_year VARCHAR2(50);
n_year NUMBER;
n_month NUMBER;
j_year VARCHAR2(4);
j_month VARCHAR2(4);
c_month NUMBER;
BEGIN
SELECT TO_CHAR(sysdate, 'YYYY-MM-DD','nls_calendar=persian') INTO p_year FROM dual; --Change sysdate to jalali date
SELECT regexp_substr(p_year,'[^-]+', 1, 1) INTO j_year
FROM dual; -- Get year of jalalian sysdate
SELECT regexp_substr(p_year,'[^-]+', 1, 2) INTO j_month
FROM dual;--Get month of jalalian sysdate
n_year := TO_NUMBER(j_year);
n_month := TO_NUMBER(j_month);
insert into sita_orders(REL_MODULE,REL_ID,CREATE_DATE,AMOUNT,CUSTOMER_ID,PROJECT_ID,ORDER_STATUS,TITLE,YEAR)
SELECT 1,ID,sysdate,78787878,CUSTOMER_ID,PROJECT_ID,0,HOSTING_TITLE,j_year
FROM SITA_HOSTS
WHERE ????;
END;
At the end I should say that my date is Jalali date
Here is one way:
WHERE TRUNC(create_date,'MM') = ADD_MONTHS(TRUNC(SYSDATE,'MM'), -1)
TRUNC(date, 'MM') truncates to midnight on the first day of the month of the date.
It really depends on the content/meaning and data type of create_date within sita-hosts table. In addition to that is the requirement also unclear. Shall the insert also cover hosts that were created a couple of years ago or only the ones created last month.
solution for the hosts created during the last month. With trying to enforce the usage of indexes if there are some.
select <your select list>
from sita_hosts
where create_date between add_months(trunc(sysdate,'mm')-1) and trunc(sysdate,'mm')
and create_date < trunc(sysdate,'mm')
the second where clause will exclude all times that are on the start of this month just at midnight.
Thanks a lot guys. I have written this code and it works fine:
insert into sita_orders(REL_MODULE,REL_ID,CREATE_DATE,AMOUNT,CUSTOMER_ID,PROJECT_ID,ORDER_STATUS,TITLE,YEAR)
SELECT 1,ID,sysdate,100000,CUSTOMER_ID,PROJECT_ID,0,HOSTING_TITLE,TO_CHAR(sysdate, 'YYYY','nls_calendar=persian')
FROM SITA_HOSTS
WHERE
to_number(TO_CHAR(CREATE_DATE, 'MM','nls_calendar=persian')) <= to_number(TO_CHAR(sysdate, 'MM','nls_calendar=persian') - 1)
and ID not in (
select REL_ID from sita_orders where REL_MODULE=1 and YEAR=TO_CHAR(sysdate, 'YYYY','nls_calendar=persian')
);

Error: ORA-01848: day of year must be between 1 and 365 (366 for leap year) while extracting month and year from DateColumn(varchar(10))

SELECT TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'YYYY-MM') as Date_y FROM Table_d
Even want to get quarter from the same date which is again giving me the error ORA-01848 like
SELECT (CASE WHEN (TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'mm')) IN ('01','02','03') THEN 'Q1'
WHEN (TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'mm')) IN ('04','05','06') THEN 'Q2'
WHEN (TO_CHAR(TO_DATE(Column_d, 'dd/mm/yyyy'), 'mm')) IN ('07','08','09') THEN 'Q3'
ELSE 'Q4' END as QTR
FROM Table_d
The way I see it, nothing of what you posted returns ORA-01848. It is - usually, if not always - related to the DDD date format mask which represents day number within the year.
For example, this is correct, as day number 001 equals the 1st of January:
SQL> select to_date('001-2020', 'ddd-yyyy') from dual;
TO_DATE('0
----------
01.01.2020
This returns ORA-01848 as there's no day 405 in this (nor any) year:
SQL> select to_date('405-2020', 'ddd-yyyy') from dual;
select to_date('405-2020', 'ddd-yyyy') from dual
*
ERROR at line 1:
ORA-01848: day of year must be between 1 and 365 (366 for leap year)
So: if you're doing anything like this, make sure that stored values are correct; I presume that not all of them are.
Besides, that's what happens when people store dates as strings into VARCHAR2 (instead of DATE datatype) columns. I'm not saying that you're the cause, but you certainly are a victim here.
[EDIT]
Julian date, eh? In a comment, you said that you used such a query:
Select TO_CHAR(TO_DATE(Julian_dateColumn+1900000, 'YYDDD'), 'YYDDD'), 'DD/MM/YYYY') as column_d from sometable
I doubt it as it is invalid (I suppose you have superfluous , 'YYDDD')).
Anyway, I have no idea why you tried to "convert" Julian date in such a manner. There's a simple and correct way to do so. Here's how:
This is today's date (21.05.2020) presented as Julian date:
SQL> select to_char(sysdate, 'j') julian from dual;
JULIAN
-------
2458991
That's kind of values you have stored in the table. In order to convert it to format you wanted (yyddd), you'd
SQL> select to_char(to_date(2458991, 'j'), 'yyddd') as column_d from dual;
COLUM
-----
20142
I suggest you use this instead of code you currently have, i.e.
SQL> create or replace view table_d as
2 select to_char(to_date(julian_datecolumn, 'j'), 'yyddd') as column_d
3 from sometable;
View created.
SQL> select * From table_d;
COLUM
-----
20142
SQL>

Delete from Oracle table rows older than 1 month

In Oracle I have a table with a DB_FLD_4 defined as VARCHAR2(20 BYTE) but actually holds DATE information with looks like this:
select DB_FLD_4 from DM_SUPDES_DISTRIB order by DB_FLD_4 desc;
4/9/2017
4/7/2017
4/6/2017
Kind of m/d/yyyy format.
I would like to create SP that would delete every day rows from the table older than 1 month.
My sysdate looks like this:
select sysdate from dual;
SYSDATE
24-APR-17 04.41:00
Please help to manipulate formats to make this possible.
Many thanks !!!
Use to_date() on your column, then trunc the sysdate to "round" to the day
delete
from MyTable
where to_date(MyColumn, 'MM/DD/YYYY') < add_months(trunc(sysdate), -1)

Oracle TIMESTAMP Comparison with TO_TIMESTAMP function

I am having a problem getting the result I expect from an Oracle query.
The TO_TIMESTAMP I am using appears to work fine:
SELECT TO_TIMESTAMP('11-16-2014 00:00:00', 'mm-dd-yyyy hh24:mi:ss') FROM DUAL
Returns
2014-11-16 00:00:00
My table AUDIT has a column CURRENT_TIMESTAMP of Oracle type TIMESTAMP(6). I don't know if it helps but this column also has these attributes:
DATATYPE=93
COLUMN_SIZE=11
DECIMAL_DIGITS=6
NUM_PREC_RADIX=10
CHAR_OCTET_LENGTH=11
Lets look at the table size:
SELECT count(*) FROM RPT.AUDIT
returns
623981
This table grows about 500 rows a day. So I would expect this query to return a number under 1000.
Instead I get the whole table:
SELECT count(*) FROM RPT.AUDIT WHERE CURRENT_TIMESTAMP > TO_TIMESTAMP('11-16-2014 00:00:00', 'mm-dd-yyyy hh24:mi:ss')
returns
623981
Thanks if you can help.
Because CURRENT_TIMESTAMP is the name of an Oracle function the database prefers to use the function instead of your column - and thus, since CURRENT_TIMESTAMP (the function) is always greater than a time in the past the predicate returns TRUE for every row in the table, and thus every row gets counted. If you put a table alias in your query and qualify the column name with the alias you should get what you expected:
SELECT count(*)
FROM RPT.AUDIT a
WHERE a.CURRENT_TIMESTAMP > TO_TIMESTAMP('11-16-2014 00:00:00', 'mm-dd-yyyy hh24:mi:ss')
Or you can just refer to the column as RPT.AUDIT.CURRENT_TIMESTAMP if you like.
Share and enjoy.

Resources