Извлечь часть строки, используя 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 (. +) (. +. \ "(. +) \")'

  1. "^" - начало строки
  2. "ORA-" - простая строка "ORA-"
  3. "\ d +" - серия цифр
  4. ":" - простая двоеточие
  5. "\ s" - пробел
  6. "(.+)" - самая длинная строка из любых символов. А также () означает, что это будет захвачено как группа (\ 1).
  7. "(" - левая скобка
  8. ".+" - самая длинная строка из всех символов.
  9. "." - простая точка
  10. \ "- двойная цитата
  11. (.+) - самая длинная строка из любых символов. И следующая группа (\ 2)
  12. \ "- двойная цитата
  13. )' - правая скобка

Регулярное выражение в точках 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")
Другие вопросы по тегам