In my table I have 3 dates that are important:
Scrap_Date
Due_Date
Follow_Up_Date
The Scrap Date is entered into a form. I would like to have the form to where once the "Scrap_Date" is entered, "Due_Date" would automatically populate a date 7 days later, and "Follow_Up_Date" would automatically populate t a date 14 days later.
I still want these dates to display on the form, but for them to automatically populate to these dates without being able to be changed.
What is the best way to go about this?
I've tried setting up a Select List, but struggled with what to code with SQL.
I have also tried this to no success:
select SCRAP_DATE,
DUE_DATE,
FOLLOW_UP_DATE,
from SCRAP_BODY_SYSTEM
where DUE_DATE = SCRAP_DATE + 7
AND FOLLOW_UP_DATE = SCRAP_DATE + 14
I appreciate any help, thank you!
Not sure about APEX GUI issues but two points:
you seem to select rows which already satisfy your "T, T+7, T+14" condition. You might rather want to somehow derive them, for instance compute in select clause?
the syntax for date addition is
select SCRAP_DATE, SCRAP_DATE + interval '7' day, SCRAP_DATE + interval '14' day
from SCRAP_BODY_SYSTEM
You shouldn't be doing it that way. If due_date and follow_up_date are always 7/14 days after scrap_date, then what's their purpose? You can always calculate them when you need them.
If you still want to have them in the table, make them virtual (see lines #5 and 6); doing so, Oracle will do everything for you.
SQL> create table test
2 (id number generated always as identity,
3 scrap_date date,
4 --
5 due_date date as (scrap_date + 7),
6 follow_up_date date as (scrap_date + 14),
7 --
8 constraint pk_test primary key (id)
9 );
Table created.
(just to know what is what; you don't have to do this):
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
In your Apex form, you'd insert only scrap_date:
SQL> insert into test (scrap_date) values (date '2022-06-15');
1 row created.
Table contents is then:
SQL> select * from test;
ID SCRAP_DATE DUE_DATE FOLLOW_UP_
---------- ---------- ---------- ----------
1 15.06.2022 22.06.2022 29.06.2022
SQL>
See? Everything is already set.
Related
This question already has answers here:
adding months to a date SQL
(3 answers)
Closed 11 months ago.
I need to be able to update a specific column in a table that is a time stamp. Its an expirationdate column and I need to add 5 years to the values in that. For these specific ids that are set to expire at some future date.Could anyone provide an example?
I presume that expiration date doesn't actually contain fractional seconds; that's most probably truncated to day, so date datatype is date. If that's so, then add_months is one option: 5 (years) * 12 (months) = 60 monts:
SQL> create table test as
2 select sysdate as expiration_date from dual;
Table created.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select expiration_date,
2 add_months(expiration_date, 12 * 5) new_value
3 from test;
EXPIRATION_DATE NEW_VALUE
------------------- -------------------
06.04.2022 21:28:13 06.04.2027 21:28:13
SQL>
In order to update current values, you'd
update test set
expiration_date = add_months(expiration_date, 12 * 5)
where ...
I have a datetime column.
I want two columns: a date and a time column.
How can I split my column into two?
Use:
a DATE data-type with the time component set to midnight for the date (you can enforce this with a check constraint); and
an INTERVAL DAY(0) TO SECOND data-type for the time component.
CREATE TABLE table_name(
datetime_column DATE,
date_column DATE,
time_column INTERVAL DAY(0) TO SECOND,
CONSTRAINT table_name__date_column__chk CHECK (date_column = TRUNC(date_column))
)
If you want to get the combined date-time then you can easily add the two to get back to a date-time value.
How can I split my column into two?
Assuming you have the columns you can use:
UPDATE table_name
SET date_column = TRUNC(datetime_column),
time_column = (datetime_column - TRUNC(datetime_column)) DAY TO SECOND;
db<>fiddle here
As Gordon commented, there's no time datatype in Oracle.
Though, literally answering what you asked, you can separate date and time and store each of them into their own columns - it's just that these will be VARCHAR2 columns and you can only look at how pretty they are. You can't, for example, do any date arithmetic on them; first you'd have to convert them back to date datatype, so question is what you really want to do with what you get.
Anyway, here you are:
SQL> create table test
2 (datum date,
3 date_only varchar2(10),
4 time_only varchar2(8)
5 );
Table created.
Sample value:
SQL> insert into test (datum) values (sysdate);
1 row created.
Split date to two parts:
SQL> update test set
2 date_only = to_char(datum, 'dd.mm.yyyy'),
3 time_only = to_char(datum, 'hh24:mi:ss');
1 row updated.
What's in there?
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select * from test;
DATUM DATE_ONLY TIME_ONL
------------------- ---------- --------
05.08.2021 21:05:06 05.08.2021 21:05:06
SQL>
Since there is no specific datatype for time, here my suggestion would be to keep the datetime in main column and add two VIRTUAL COLUMN for date value and time value respectively.
Oracle 11g has introduced a new feature that allows you to create a VIRTUAL COLUMN, an empty column that contains a function upon other table columns (the function itself is stored in the data dictionary).
However, it all depends on what you are going to do with it.
Please elaborate your requirement so that you will get a more specific answer.
I am just trying to calculate and store age attribute derivedly from dob(date of birth). How can ı do that in Oracle SQL Developer?
CREATE TABLE Patient (
dob DATE,
age NUMBER(3));
I mean when de dob inserted like that 01/01/2000 the age will automatically calculated to 21.
No, you're planning to do it in a wrong way. Why would you so badly want to do that?
It's the same as people - who fill their profile - say "I've got 5 years of experience with Oracle". That was probably true at the moment of writing that text, but - is it still valid now? Two years later it should be "I've got 7 years of experience".
So, what kind of information would be storing fixed age into that column? That person was 21 years old at the moment of insert, but they won't stay forever young. Believe me, I know.
You were suggested to create a virtual column. Well, you can't. Why? Because - in order to calculate someone's age - you have to refer to today's date. Function that returns it is SYSDATE. Bad luck - it is not deterministic, which means that it doesn't return the same value each time you call it with the same parameters. It doesn't accept any, that's true, but it doesn't matter. If you try it, it'll fail:
SQL> create table patient
2 (id number constraint pk_pat primary key,
3 date_of_birth date not null,
4 age number generated always as
5 (round(months_between(sysdate, date_of_birth)/12, 0))
6 virtual
7 );
(round(months_between(sysdate, date_of_birth)/12, 0))
*
ERROR at line 5:
ORA-54002: only pure functions can be specified in a virtual column expression
SQL>
So, what can you do? You can create a view.
SQL> create table patient
2 (id number constraint pk_pat primary key,
3 date_of_birth date not null
4 );
Table created.
SQL> create or replace view v_patient as
2 select id,
3 date_of_birth,
4 round(months_between(sysdate, date_of_birth)/12, 0) as age
5 from patient;
View created.
SQL>
Let's test it.
SQL> insert into patient (id, date_of_birth) values (1, date '2000-01-01');
1 row created.
SQL> select * from v_patient;
ID DATE_OF_BI AGE
---------- ---------- ----------
1 01.01.2000 21
SQL>
Looks OK to me.
I have a column 'creation_date' which is of type 'date', when I am querying my table for distinct records based on 'creation_date' I am getting 6 records:
select distinct creation_date from test_table;
output:
06-APR-11
06-APR-11
28-MAR-11
06-APR-11
06-APR-11
18-MAR-11
In this output 6th April is displayed 4 times even when I used distinct in my query. Also when I am trying to find out all records which are matching with creation_date of 6th April 2011 I am not getting any results. Below is my query:
select * from test_table where creation_date = to_date('06-APR-11','DD-MON-YY');
Please help me where I am doing wrong in these two queries.
The problem is twofold. Firstly the dates almost definitely have time-components. to_date('06-MAR-11','DD-MON-YY') is equivalent to 2011/03/06 00:00:00. If you use the TRUNC() function you will be able to see everything for that day:
select *
from test_table
where trunc(creation_date) = to_date('06-MAR-11','DD-MON-YY');
I would not use the MON datetime format model. As I explain here it depends on your region and settings. It's safer to use a numeric month format model instead. Equally, always specify century as part of the year.
where trunc(creation_date) = to_date('06-03-YY11','DD-MM-YYYY');
Your second problem is almost definitely your NLS_DATE_FORMAT; it appears to not take into account the time, hence why you see 4 identical dates. This only governs the manner in which data is displayed not how it is stored.
You can change this using something like:
ALTER SESSION SET NLS_DATE_FORMAT = "DD/MM/YYYY HH24:MI:SS"
If I set up a test environment using the following:
create table test_table ( creation_date date );
insert into test_table values ( sysdate );
insert into test_table values ( sysdate - 0.01 );
alter session set nls_date_format = "YYYY/MM/DD";
You can see the data returned does not include time (though SYSDATE does):
SQL> select * from test_table;
CREATION_D
----------
2013/04/12
2013/04/12
Altering the NLS_DATE_FORMAT and performing the same SELECT, you now get a time component:
SQL> alter session set nls_date_format = "YYYY/MM/DD HH24:MI:SS";
Session altered.
SQL> select * from test_table;
CREATION_DATE
-------------------
2013/04/12 12:48:41
2013/04/12 12:34:17
Lastly, when trying to select today's date alone no rows will be returned:
SQL> select *
2 from test_table
3 where creation_date = to_date('20130412','yyyymmdd');
no rows selected
But, when using TRUNC() to compare on only the date portion of the field you get all your rows again:
SQL> select *
2 from test_table
3 where trunc(creation_date) = to_date('20130412','yyyymmdd');
CREATION_DATE
-------------------
2013/04/12 12:48:41
2013/04/12 12:34:17
To actually answer your second question, if you want unique dates you can re-use the TRUNC() function:
select distinct trunc(creation_date)
from test_table
The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight). You must also consider this.
I understand that Oracle sysdate returns the current date AND time. That's great for timestamp or datetime columns.
Now let's say I have a DATE only column. What keywords should I use on my insert query?
insert into myTable1(myDateOnlyColumn) values(???)
And let's say I have a TIME only column. What keywords should I use on my insert query?
insert into myTable2(myTimeOnlyColumn) values(???)
Thanks!
To remove time from sysdate you can just write TRUNC(sysdate).
For example:
SELECT TRUNC(SYSDATE) "TODAY" FROM DUAL;
will give you:
TODAY
-------------------------
'2012-10-02 00:00:00'
There is no such thing as a DATE only column in Oracle. The DATE datatype stores date and time.
If you only care about the date, you can:
INSERT INTO tbl (dtCol) VALUES (TO_DATE('20110929','YYYYMMDD');
This leaves the time component at 00:00:00. You don't have to display it though.
If you're only interested in the time component, you still have a date stored in the column. You'll just have to handle that on output. For example:
SQL> CREATE TABLE dt (d DATE);
SQL> INSERT INTO dt VALUES (TO_DATE('1:164800','J:HH24MISS'));
1 row inserted
Showing the actual contents of the column reveals a date was inserted:
SQL> SELECT * FROM dt;
D
--------------------
0/0/0000 4:48:00 PM
Selecting only the time component from the column gives you the output you want:
SQL> SELECT TO_CHAR(d, 'HH24:MI:SS') d FROM dt;
D
--------
16:48:00
SQL>
If you think you need only a time column, you'll want to make sure you always insert the same date component.
select sysdate, to_date(to_char(sysdate, 'dd/mm/yyyy'),'dd/mm/yyyy') d
from dual
For whoever is looking for a simple solution for returning only date without time, I found this:
to_date(SYSDATE,'dd/mm/yyyy')
Works like a charm. ;-)