Is there a workaround/better way to do this:
I have a field (TEREMARKS) which contains a long string and out of that string I need to get the times and names that I can find in there. I extract the time and name when I encounter this format: TE=<HH:MM>(<NAME>)
My problem is sometimes the format is not followed by the encoder which would throw the ORA-01722. I would have wanted my program to skip the erroneous record and return the ones that are OK. Would that be possible? Here are the scripts:
Create table:
CREATE TABLE HPACC.TE_ENTRY
(
TENUMBER VARCHAR2(20 BYTE) NOT NULL,
TEREMARKS VARCHAR2(100 BYTE),
TEUPDATEBY VARCHAR2(15 BYTE),
TETRXDT DATE
);
Insert Data:
Insert into HPACC.TE_ENTRY (TENUMBER, TEREMARKS, TEUPDATEBY, TETRXDT)
Values ('115118002', 'TE=10:03 CU ANTI SEIZZURE ', 'ME1', TO_DATE('08/24/2012 10:00:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into HPACC.TE_ENTRY (TENUMBER, TEREMARKS, TEUPDATEBY, TETRXDT)
Values ('1151180025 ', 'TE= 10:19 ON AND OFF FEVER', 'ME2', TO_DATE('08/24/2012 10:01:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into HPACC.TE_ENTRY (TENUMBER, TEREMARKS, TEUPDATEBY, TETRXDT)
Values ('1153053592', 'TE=10:40(DIANE) PRE''EMP', 'ME1', TO_DATE('08/24/2012 10:05:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into HPACC.TE_ENTRY (TENUMBER, TEREMARKS, TEUPDATEBY, TETRXDT)
Values ('1157019820', 'TE=10:45(KRISTEN), CU,MONITORING,RASHE,FEVER LAST MONDAY ', 'ME1', TO_DATE('08/24/2012 10:12:00', 'MM/DD/YYYY HH24:MI:SS'));
Insert into HPACC.TE_ENTRY (TENUMBER, TEREMARKS, TEUPDATEBY, TETRXDT)
Values ('1157019832', 'TE=11-:13 PRE EMP EXTRACTED BY:CAMILLA', 'ME3', TO_DATE('08/24/2012 10:15:00', 'MM/DD/YYYY HH24:MI:SS'));
My Query:
SELECT TO_CHAR(DECODE(ORIGTIME, '1', '13','2', '14','3', '15','4', '16',ORIGTIME),'FM00') ATIME
, DONEBY
, COUNT(TENUMBER) AS CTOTAL
FROM (
SELECT TENUMBER
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'TE=',1,1) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,1)+3,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,1)),':',1,1))-4)
, ' +-.0123456789', ' '))) IS NULL)
THEN TO_NUMBER(REPLACE(TO_CHAR(TO_NUMBER(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,1)+3,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,1)),':',1,1))-4)),'FM99'),'-'))
ELSE 0 END) AS ORIGTIME
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'(',1,1) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,1)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,1)+1),')',1,1))-1), ' +-.0123456789', ' '))) IS NULL)
THEN SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,1)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,1)+1),')',1,1))-1)
ELSE TEUPDATEBY END) AS DONEBY
FROM HPACC.TE_ENTRY
Where TETRXDT BETWEEN TO_DATE('08-24-2012 10:00:00','MM-DD-YYYY HH24:MI:SS') AND TO_DATE('08-24-2012 10:59:59','MM-DD-YYYY HH24:MI:SS')
GROUP BY TENUMBER, TEREMARKS, TEUPDATEBY
UNION
SELECT TENUMBER
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'TE=',1,2) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,2)+3,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,2)),':',1,1))-4), ' +-.0123456789', ' '))) IS NULL)
THEN TO_NUMBER(REPLACE(TO_CHAR(TO_NUMBER(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,2)+3,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,2)),':',1,1))-4)),'FM99'),'-'))
ELSE 0 END) AS ORIGTIME
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'(',1,2) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,2)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,2)+1),')',1,1))-1), ' +-.0123456789', ' '))) IS NULL)
THEN SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,2)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,2)+1),')',1,1))-1)
Else 'NONE' END) AS DONEBY
FROM HPACC.TE_ENTRY
Where TETRXDT BETWEEN TO_DATE('08-24-2012 10:00:00','MM-DD-YYYY HH24:MI:SS') AND TO_DATE('08-24-2012 10:59:59','MM-DD-YYYY HH24:MI:SS')
GROUP BY TENUMBER, TEREMARKS
UNION
SELECT TENUMBER
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'TE=',1,3) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,3)+3, (INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,3)),':',1,1))-4), ' +-.0123456789', ' '))) IS NULL)
THEN TO_NUMBER(REPLACE(TO_CHAR(TO_NUMBER(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,3)+3, (INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,3)),':',1,1))-4)),'FM99'),'-'))
ELSE 0 END) AS ORIGTIME
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'(',1,3) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,3)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,3)+1),')',1,1))-1), ' +-.0123456789', ' '))) IS NULL)
THEN SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,3)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,3)+1),')',1,1))-1)
Else 'NONE' END) AS DONEBY
FROM HPACC.TE_ENTRY
Where TETRXDT BETWEEN TO_DATE('08-24-2012 10:00:00','MM-DD-YYYY HH24:MI:SS') AND TO_DATE('08-24-2012 10:59:59','MM-DD-YYYY HH24:MI:SS') GROUP BY TENUMBER, TEREMARKS
UNION
SELECT TENUMBER
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'TE=',1,4) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,4)+3, (INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,4)),':',1,1))-4), ' +-.0123456789', ' '))) IS NULL)
THEN TO_NUMBER(REPLACE(TO_CHAR(TO_NUMBER(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,4)+3, (INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,4)),':',1,1))-4)),'FM99'),'-'))
ELSE 0 END) AS ORIGTIME,
(CASE WHEN (INSTR(UPPER(TEREMARKS),'(',1,4) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,4)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,4)+1),')',1,1))-1), ' +-.0123456789', ' '))) IS NULL)
THEN SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,4)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,4)+1),')',1,1))-1)
Else 'NONE' END) AS DONEBY
FROM HPACC.TE_ENTRY
Where TETRXDT BETWEEN TO_DATE('08-24-2012 10:00:00','MM-DD-YYYY HH24:MI:SS') AND TO_DATE('08-24-2012 10:59:59','MM-DD-YYYY HH24:MI:SS')
GROUP BY TENUMBER, TEREMARKS
UNION
SELECT TENUMBER
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'TE=',1,5) <> 0)
AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,5)+3,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,5)),':',1,1))-4), ' +-.0123456789', ' '))) IS NULL)
THEN TO_NUMBER(REPLACE(TO_CHAR(TO_NUMBER(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,5)+3,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'TE=',1,5)),':',1,1))-4)),'FM99'),'-'))
ELSE 0 END) AS ORIGTIME
, (CASE WHEN (INSTR(UPPER(TEREMARKS),'(',1,5) <> 0) AND (LENGTH(TRIM(TRANSLATE(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,5)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,5)+1),')',1,1))-1), ' +-.0123456789', ' '))) IS NULL)
THEN
SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,5)+1,(INSTR(SUBSTR(TEREMARKS,INSTR(UPPER(TEREMARKS),'(',1,5)+1),')',1,1))-1)
Else 'NONE' END) AS DONEBY
FROM HPACC.TE_ENTRY Where TETRXDT BETWEEN TO_DATE('08-24-2012 10:00:00','MM-DD-YYYY HH24:MI:SS') AND TO_DATE('08-24-2012 10:59:59','MM-DD-YYYY HH24:MI:SS')
GROUP BY TENUMBER, TEREMARKS
)
Where ORIGTIME <> 0
Group By ORIGTIME, DONEBY
Order By TO_CHAR(TO_NUMBER(ATIME),'FM00') , DONEBY;
The last record (10:15) causes the error. How to bypass that one?
I also feel like my script is too verbose. Would appreciate your corrections, suggestions and examples. Thanks!
As Alex commented this is obviously a task for regular expressions.
Here’s one that will work with your current data.
This matches, from the beginning of the string,
TE, followed by an=, then an optional space, two numbers an optional character,:then another two numbers.The seconds matches either
(followed by any number of letters followed by), or:followed by any number of letters at the end of the line.Or, to get out just the time and name, removing all the extra stuff:
Here’s a SQL Fiddle to demonstrate. Please also note that regular expressions are only available in Oracle 10g or later.
I would just like to emphasise that while this will work on your current data it does not mean that it will work forever. There will always be more cases that you hadn’t thought of. If the results of this query are important you should change your table to include a column that has the date (not time) the measurements were taken and another column that has the name of the person taking it.
This is the only way you can be certain that your data is correct.