Соответствует OBR
в OBRIEN
в шапке.Просто предварительно обработайте строку, чтобы отделить заголовок от тела, и затем вы можете выполнить итерацию только по телу сообщения:
Настройка Oracle :
CREATE TABLE test_hl7_message_split ( file_content ) AS
SELECT 'MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN
OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN' FROM DUAL;
Запрос :
SELECT c.COLUMN_VALUE AS obr_seq,
head
|| REGEXP_SUBSTR( t.body, 'OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, c.COLUMN_VALUE ) AS split_value
FROM ( SELECT REGEXP_SUBSTR( file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) ) AS head,
REGEXP_REPLACE( file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) ) AS body
FROM test_hl7_message_split ) t
LEFT OUTER JOIN
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT( t.body, 'OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*' )
) AS SYS.ODCINUMBERLIST
)
) c
ON ( 1 = 1 );
Вывод :
OBR_SEQ | SPLIT_VALUE
------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2<br>PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|<br>OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F<br>OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X<br>OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN<br>
2 | MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2<br>PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|<br>OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F<br>OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X<br>OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN
Запрос 2 :
Другой альтернативой является использование параметра совпадения m
в регулярном выражении для обработки строки как нескольких строк, после чего вы можете сопоставить ^OBR
, чтобы найти OBR
только в начале строки:
SELECT c.COLUMN_VALUE AS obr_seq,
REGEXP_SUBSTR( t.file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) )
|| REGEXP_SUBSTR( t.file_content, '^OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, c.COLUMN_VALUE, 'm' ) AS split_value
FROM test_hl7_message_split t
LEFT OUTER JOIN
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT( t.file_content, '^OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, 'm' )
) AS SYS.ODCINUMBERLIST
)
) c
ON ( 1 = 1 );
дБ <> скрипка здесь