-4

これを行うための回避策/より良い方法はありますか?

長い文字列を含むフィールド(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
);

データの挿入:

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'));

私の質問:

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;

最後のレコード(10:15)でエラーが発生します。それをバイパスする方法は?また、スクリプトが冗長すぎるように感じます。あなたの訂正、提案、例をいただければ幸いです。ありがとう!

4

1 に答える 1

6

Alexがコメントしたように、これは明らかに正規表現のタスクです。

これが現在のデータで機能するものです。

select regexp_substr( teremarks
                   , '^TE=[[:space:]]?[[:digit:]]{2}[[:print:]]?:[[:digit:]]{2}')
     , regexp_substr( teremarks
                   , '([(][[:alpha:]]+[)]|:[[:alpha:]]+$)')
from te_entry

これは、文字列の先頭から、、、TEその後=にオプションのスペース、2つの数字、オプションの文字、:さらに2つの数字に一致します。

秒は、行の終わりに任意の数の文字が続き、その後に続くか、または(任意の数の文字が続くかのいずれかに一致します。):

または、時間と名前だけを取得するには、余分なものをすべて削除します。

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

これがデモンストレーション用のSQLフィドルです。また、正規表現はOracle10g以降でのみ使用可能であることに注意してください。

これは現在のデータで機能しますが、永久に機能するという意味ではないことを強調したいと思います。あなたが考えもしなかったケースは常にもっとあるでしょう。このクエリの結果が重要な場合は、テーブルを変更して、測定が行われた日付(時刻ではない)を含む列と、測定を行った人の名前を含む別の列を含める必要があります。

これは、データが正しいことを確認できる唯一の方法です。

于 2012-08-25T08:52:12.217 に答える