是否有解决方法/更好的方法来执行此操作:
我有一个字段(TEREMARKS),其中包含一个长字符串,在该字符串中我需要获取我可以在那里找到的时间和名称.当我遇到这种格式时,我会提取时间和名字: TE=<HH:MM>(<NAME>)
我的问题是有时格式化的编码器不会抛出ORA-01722.我本来希望我的程序跳过错误的记录并返回那些没问题的记录.这可能吗?以下是脚本:
创建表格:
CREATE TABLE HPACC.TE_ENTRY
(
TENUMBER VARCHAR2(20 BYTE) NOT NULL,
TEREMARKS VARCHAR2(100 BYTE),
TEUPDATEBY VARCHAR2(15 BYTE),
TETRXDT DATE
);
Run Code Online (Sandbox Code Playgroud)
插入数据:
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'));
Run Code Online (Sandbox Code Playgroud)
我的查询:
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;
Run Code Online (Sandbox Code Playgroud)
最后一条记录(10:15)导致错误.如何绕过那一个?我也觉得我的剧本太冗长了.非常感谢您的更正,建议和示例.谢谢!
正如Alex评论的那样,这显然是正则表达式的任务.
这是一个可以处理您当前数据的方法.
select regexp_substr( teremarks
, '^TE=[[:space:]]?[[:digit:]]{2}[[:print:]]?:[[:digit:]]{2}')
, regexp_substr( teremarks
, '([(][[:alpha:]]+[)]|:[[:alpha:]]+$)')
from te_entry
Run Code Online (Sandbox Code Playgroud)
这匹配,从字符串的开头TE,后跟一个=,然后是一个可选空格,两个数字是一个可选字符,:然后是另外两个数字.
秒匹配(后跟任意数量的字母后跟),或:后跟行尾的任意数量的字母.
或者,为了获得时间和名称,删除所有额外的东西:
with matched as (
select regexp_substr( teremarks
, '^TE=[[:space:]]?[[:digit:]]{2}[[:print:]]?:[[:digit:]]{2}'
) as time
, regexp_substr( teremarks
, '([(][[:alpha:]]+[)]|:[[:alpha:]]+$)'
) as name
from te_entry
)
select regexp_replace( time
, '[^([:digit:]|:)]')
, regexp_replace( name
, '[^[:alpha:]]')
from matched
Run Code Online (Sandbox Code Playgroud)
这是一个演示的SQL小提琴.另请注意,正则表达式仅适用于Oracle 10g或更高版本.
我想强调的是,虽然这将对您当前的数据起作用,但这并不意味着它将永远有效.总会有更多你没想过的案例.如果此查询的结果很重要,则应更改表格以包含具有测量日期(而非时间)的列以及具有接受测量的人员姓名的另一列.
这是您可以确定数据正确的唯一方法.
| 归档时间: |
|
| 查看次数: |
554 次 |
| 最近记录: |