Извлечь часть строки, используя REGEXP_SUBSTR
Я использую таблицу журнала ошибок через dbms_errlog.create_error_log для массовых ошибок операций DML и возвращаю ORA_ERR_MESG$ обратно клиенту. Однако мне нужно игнорировать код ошибки, поэтому он выглядит удобным для пользователя.
Пример: ORA-01400: невозможно вставить NULL в ("ABC_OWNER"."ABC_PART"."REGION")
это нужно изменить на "Невозможно вставить NULL в РЕГИОН"
Я попытался REGEXP_SUBSTR для поиска шаблона "ORA-" и сделать некоторые извлечения, но мне удалось только в определенной степени. Подскажите, пожалуйста, как это сделать.
С уважением.
2 ответа
Существует много исключений и оракулов, и есть разные маски. Вы хотите, чтобы они все были закодированы?
Ваше текущее регулярное выражение может выглядеть так:
select regexp_replace('ORA-01400: cannot insert NULL into ("ABC_OWNER"."ABC_PART"."REGION")'
,'^ORA-\d+:\s(.+)\(.+\.\"(.+)\"\)', '\1 \2') from dual
РЕДАКТИРОВАТЬ: описание регулярного выражения '^ ORA- \ d +: \ s (. +) (. +. \ "(. +) \")'
- "^" - начало строки
- "ORA-" - простая строка "ORA-"
- "\ d +" - серия цифр
- ":" - простая двоеточие
- "\ s" - пробел
- "(.+)" - самая длинная строка из любых символов. А также
()
означает, что это будет захвачено как группа (\ 1). - "(" - левая скобка
- ".+" - самая длинная строка из всех символов.
- "." - простая точка
- \ "- двойная цитата
- (.+) - самая длинная строка из любых символов. И следующая группа (\ 2)
- \ "- двойная цитата
- )' - правая скобка
Регулярное выражение в точках 6,8 и 11 будет голодным поиском, оно попытается оштрафовать самую длинную строку из первой группы. Это означает, что есть несколько вариантов между длиной "6", "8" и "11". "6" выберет первое и возьмет все, что может, "8" выберет следующее, а "11" - наименьшее. Например, если у вас есть строка aaaaaa
и регулярное выражение (.+)(.+)
первая группа займет aaaaa
а второй a
Если вам просто нужно удалить код ошибки, это можно сделать с помощью обычного instr
а также substr
, которые быстрее, чем регулярное выражение. Но это зависит от того, что вам действительно нужно сделать (например, здесь я не стал использовать заглавные буквы в первой букве, поскольку ваше требование, скорее всего, будет разъяснено позже).
with
error_messages ( str ) as (
select 'ORA-01400: cannot insert NULL into ("ABC_OWNER"."ABC_PART"."REGION")'
from dual
)
select substr( str, instr(str, ' ') + 1) as modified_err_msg from error_messages
;
MODIFIED_ERR_MSG
----------------
cannot insert NULL into ("ABC_OWNER"."ABC_PART"."REGION")