Oracle APEX - converting a field from collection to type DATE - oracle-apex-5.1

I have a page that grabs data from apex collection and one of the fields is date but since it is coming from collection it comes up as text. What is the best way to convert it to date?

Generally speaking, text (string) is converted to DATE with TO_DATE function, by applying the correct format mask. For example:
SQL> with test (text_value) as
2 (select '23.04.2019' from dual union all
3 select '04-2019-23' from dual union all
4 select '04 April 2019' from dual
5 )
6 select to_date(text_value, 'dd.mm.yyyy') result from test
7 where text_value = '23.04.2019'
8 union all
9 select to_date(text_value, 'mm-yyyy-dd') from test
10 where text_Value = '04-2019-23'
11 union all
12 select to_date(text_value, 'dd month yyyy', 'nls_date_language=english')
13 from test
14 where text_value = '04 April 2019'
15 /
RESULT
----------
23/04/2019
23/04/2019
04/04/2019
SQL>

Related

Last record saved in a table over one column

I have data:
CLIENT_NO , DATE , TYPE
CLIENT 1- 22/09/2014 -001
CLIENT 1- 19/09/2014 -002
CLIENT 1- 10/09/2014 -005
CLIENT 2- 15/09/2014 -012
CLIENT 2- 20/09/2014 -011
I want to have latest TYPE stored in this table over time for each client. How can I do that using PL/SQL?
Well, you don't really need PL/SQL; pure SQL will do.
One option is to sort them (analytic functions as row_number or rank help in this case), and then fetch rows with row number = 1 (because of order by clause which sorts them by date value in descending order).
SQL> with
2 test (client_no, datum, type) as
3 -- sample data
4 (select 'client 1', date '2014-09-22', '001' from dual union all
5 select 'client 1', date '2014-09-19', '002' from dual union all
6 select 'client 1', date '2014-09-10', '005' from dual union all
7 select 'client 2', date '2014-09-15', '012' from dual union all
8 select 'client 2', date '2014-09-20', '011' from dual
9 ),
10 -- sort them
11 sorted as
12 (select client_no, datum, type,
13 row_number() over (partition by client_no order by datum desc) rn
14 from test
15 )
16 -- select the one with RN = 1
17 select client_no, datum, type
18 from sorted
19 where rn = 1;
CLIENT_NO DATUM TYPE
---------- ---------- ----
client 1 22/09/2014 001
client 2 20/09/2014 011
SQL>

Using a case when to know if date format is right

I want to migrate a table which contains some columns with dates. The issue is my dates are often in dd/mm/yyyyy HH24:MM:YYYY format. But sometimes it appears that the format is only dd/mm/yyyy, or blank.
I guess that's why I'm getting ORA-01830 when I'm trying to migrate the datas.
I tried
CASE
WHEN TO_DATE(MYDATE,'DD/MM/YYYY')
then TO_DATE(MYDATE,'DD/MM/YYYY 00:00:00')
END AS MYDATE
But I'm not sure if it is possible to test the date format (and ofcourse it's not working).
Thank you
TO_DATE cannot test date format, but you can do it. If Lalit's answer would not be enough, try something like
select
case when my_date like '__/__/__' then to_date(my_date, 'dd/mm/yy')
when my_date like '__-__-__' then to_date(my_date, 'dd-mm-yy')
...
end
So you have the data type issue. DATE is stored as string literal. As you have mentioned that the date model has the DD/MM/YYYY part same, just that the time portion is either missing for some rows or the entire value is NULL.
For example, let's say your table have the values like -
SQL> WITH dates AS(
2 SELECT 1 num, '29/12/2014 16:38:57' dt FROM dual UNION ALL
3 SELECT 2, '29/12/2014' FROM dual UNION ALL
4 SELECT 3, NULL FROM dual
5 )
6 SELECT num, dt
7 FROM dates
8 /
NUM DT
---------- -------------------
1 29/12/2014 16:38:57
2 29/12/2014
3
SQL>
TO_DATE with proper format model should do the trick.
Let's stick to a format model first.
SQL> alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';
Session altered.
Now, let's use TO_DATE to explicitly convert the string literal to date.
SQL> WITH dates AS(
2 SELECT 1 num, '29/12/2014 16:38:57' dt FROM dual UNION ALL
3 SELECT 2, '29/12/2014' FROM dual UNION ALL
4 SELECT 3, NULL FROM dual
5 )
6 SELECT num, to_date(dt, 'dd/mm/yyyy hh24:mi:ss') dt
7 FROM dates
8 /
NUM DT
---------- -------------------
1 29/12/2014 16:38:57
2 29/12/2014 00:00:00
3
SQL>

Getting the previous occurrence and next occurrence in oracle

Hi I am working on oracle DB. The DB has one column date. It consists of the dates of 5 years with the dates model will be refreshed. Ex
DATE_TABLE
DATE
------------
1-jan-2013
15-jan-2013
31-jan-2013
6-feb-2013
etc.........
now for today's date suppose 13th jan 2013. The next refresh date will be 15th jan. and previous refresh date is 1st jan. to retrieve these two dates. Can i have any way without using PL/SQL. using regular select queries?. Thanks in advance
There are two functions LAG() (allows you to reference previous record) and LEAD() allows you to reference next record. Here is an example:
SQL> with t1(col) as(
2 select '1-jan-2013' from dual union all
3 select '15-jan-2013' from dual union all
4 select '31-jan-2013' from dual union all
5 select '6-feb-2013' from dual
6 )
7 select col as current_value
8 , lag(col, 1) over(order by col) as prev_value
9 , lead(col, 1) over(order by col)as next_value
10 from t1
11 ;
Result:
CURRENT_VALUE PREV_VALUE NEXT_VALUE
------------- ----------- -----------
1-jan-2013 NULL 15-jan-2013
15-jan-2013 1-jan-2013 31-jan-2013
31-jan-2013 15-jan-2013 6-feb-2013
6-feb-2013 31-jan-2013 NULL
We can simply use the below query, plain and simple. No need of pl/sql
SELECT MIN(DATE) FROM DATE_TABLE WHERE DATE > SYSDATE ;

Get Gap between time range

In WORK_TIME column in my database table (EMP_WORKS), i have records as below.
WORK_TIME
19:03:00
20:00:00
21:02:00
21:54:00
23:04:00
00:02:00
i want to create a database view using these data. for it i need to get Gap between these times as below.
WORK_TIME GAP
19:03:00 -
20:00:00 00:57:00 (Gap between 19:03:00 and 20:00:00)
21:02:00 01:02:00 (Gap between 20:00:00 and 21:02:00)
21:54:00 00:52:00 (Gap between 21:02:00 and 21:54:00)
23:04:00 01:10:00 (Gap between 21:54:00 and 23:04:00)
00:02:00 00:58:00 (Gap between 23:04:00 and 00:02:00)
How could i do this ?
This query will get you the differences in hours:
SELECT
work_time,
( work_time - LAG(work_time) OVER (ORDER BY work_time) ) * 24 AS gap
FROM emp_works
Example on SQL Fiddle returns this:
WORK_TIME GAP
November, 07 2012 19:03:00+0000 (null)
November, 07 2012 20:00:00+0000 0.95
November, 07 2012 21:02:00+0000 1.033333333333
November, 07 2012 21:54:00+0000 0.866666666667
November, 07 2012 23:04:00+0000 1.166666666667
November, 08 2012 00:02:00+0000 0.966666666667
First you will need to have a primary key in the table containing the DATE/TIME field.
I have set up this demo on SQL Fiddle .. Have a look
I have represented the gap as a factor of hours between the two times. You can manipulate the figure to represent minutes, or days, whatever.
SELECT
TO_CHAR(A.WORK_TIME,'HH24:MI:SS') WORK_FROM,
TO_CHAR(B.WORK_TIME,'HH24:MI:SS') WORK_TO,
ROUND(24*(B.WORK_TIME-A.WORK_TIME),2) GAP FROM
sample A,
SAMPLE B
WHERE A.ID+1 = B.ID(+)
If your primary key values have difference greater than 1 (gaps within the values of the primary key) then you will need to offset the value dynamically like this:
SELECT
TO_CHAR(A.WORK_TIME,'HH24:MI:SS') WORK_FROM,
TO_CHAR(B.WORK_TIME,'HH24:MI:SS') WORK_TO,
ROUND(24*(B.WORK_TIME-A.WORK_TIME),2) GAP FROM
sample A,
SAMPLE B
WHERE b.ID = (select min(C.ID) from sample c where c.id>A.ID)
According to your desired result, provided in the question, you want to see time interval. And also I suppose that the WORK_TIME column is of date datatype and there is a date part(otherwise there will be a negative result of subtraction (previous value of WORK_TIME from 00.02.00)).
SQL> create table Work_times(
2 work_time
3 ) as
4 (
5 select to_date('01.01.2012 19:03:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
6 select to_date('01.01.2012 20:00:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
7 select to_date('01.01.2012 21:02:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
8 select to_date('01.01.2012 21:54:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
9 select to_date('01.01.2012 23:04:00', 'dd.mm.yyyy hh24:mi:ss') from dual union all
10 select to_date('02.01.2012 00:02:00', 'dd.mm.yyyy hh24:mi:ss') from dual
11 )
12 /
Table created
SQL>
SQL> select to_char(t.work_time, 'hh24.mi.ss') work_time
2 , (t.work_time -
3 lag(t.work_time) over(order by WORK_TIME)) day(1) to second(0) Res
4 from work_times t
5 ;
WORK_TIME RES
--------- -------------------------------------------------------------------------------
19.03.00
20.00.00 +0 00:57:00
21.02.00 +0 01:02:00
21.54.00 +0 00:52:00
23.04.00 +0 01:10:00
00.02.00 +0 00:58:00
6 rows selected

Oracle: TIMESTAMP data type

i am using timestamp for a field to store date and time, however when i fetch the rows from the table i get loads of zeros in the timestamp field.
SQL> select * from booking_session;
BK_ID|BK_DATE
----------|-------------------------
1|18-MAR-12 10.00.00.000000
2|18-MAR-12 10.25.00.000000
3|18-MAR-12 10.30.00.000000
4|18-MAR-12 10.35.00.000000
5|18-MAR-12 10.40.00.000000
The following is the insert statement
INSERT INTO BOOKING_SESSION VALUES (1,TO_TIMESTAMP('18/03/2012 10:00',
'DD/MM/YYYY HH24:MI')
Can someone please tell me how can the bk_date format be stored like 18-MAR-12 10.00 or at least have AM or PM next to it.
Thanks in advance.
You can declare BK_DATE column as timestamp(precision) where precision is a number of decimal digits to store fraction of a second. So you might have declared BK_DATE timestamp(0). If you do not need track time down to a fraction of a second use date data type to store dates. In any case time part (hh:mi:ss) will be there and if you insert data as you did, specifying only hour and minutes, then seconds will be fill in with zeros. You can use to_char function and appropriate date format mask to get rid of those trailing zeros at display time:
-- sample of data
SQL> with t1(BK_ID, BK_DATE) as(
2 select 1, to_timestamp('18-MAR-12 10.00.00.000000', 'DD-MON-RR HH:MI:SSxFF6') from dual union all
3 select 2, to_timestamp('18-MAR-12 10.25.00.000000', 'DD-MON-RR HH:MI:SSxFF6') from dual union all
4 select 3, to_timestamp('18-MAR-12 10.30.00.000000', 'DD-MON-RR HH:MI:SSxFF6') from dual union all
5 select 4, to_timestamp('18-MAR-12 10.35.00.000000', 'DD-MON-RR HH:MI:SSxFF6') from dual union all
6 select 5, to_timestamp('18-MAR-12 10.40.00.000000', 'DD-MON-RR HH:MI:SSxFF6') from dual
7 )
8 select bk_id
9 , to_char(bk_date, 'DD-MON-RR HH:MI') bk_date
10 from t1
11 ;
BK_ID BK_DATE
---------- ------------------------
1 18-MAR-12 10:00
2 18-MAR-12 10:25
3 18-MAR-12 10:30
4 18-MAR-12 10:35
5 18-MAR-12 10:40
Try the following query:
select * from booking_session where trunc(bk_date) = to_date('18-03-2012', 'dd-mm-yyyy');

Resources