Итак, при условии, что такие тестовые данные
DETAIL_LOG
-----------------------------------------------------------------------------------------
USER_1; Salary: from '25' to '30'; Dept_ID: from '001' to '';
USER_1; Dept_ID: from '' to '001';
USER_1; Salary: from '25' to '30'; Dept_ID: from '001' to '002'; Prdeel: from '0' to '1':
USER_1; Dept_ID: from '' to '';
Если я вас правильно понял, вы хотите удалить запись Dept_ID
из первой и второй строки, потому что одно из значений - NULL. Я добавил четвертую строку со значением NULL, которое также должно быть удалено.
Третья строка остается неизменной, поскольку оба значения заполнены.
Вам нужно это регулярное выражение для замены данных
q'[(Dept_ID: from '.*' to '';|Dept_ID: from '' to '.*';)]'
Обратите внимание, что столбец в середине представляет ИЛИ. Левая часть соответствует отделам со значением to
NULL, а правая часть - отделу со значением from
NULL.
Соответствующая строка заменяется пустой строкой.
Чтобы ограничить область действия обновляемых записей, необходимо определить точный логик ошибочных записей. Вот пример, где я ожидаю, что обе записи должны иметь одинаковые e_id
и упорядочены по t_id
Используя LEAD
и LAG
, вы проверяете следующие и предыдущие повторы, чтобы убедиться, что условие изменяется на emtpy и меняется с пустого заполнено.
Обратите внимание, что я использую LIKE
для фильтрации строк, чтобы повысить производительность.
Запрос окончательной проверки перед обновлением:)
with al as (
select T_ID, E_ID, DETAIL_LOG,
lead(DETAIL_LOG) over (partition by e_id order by t_id) DETAIL_LOG_LEAD,
lag(DETAIL_LOG) over (partition by e_id order by t_id) DETAIL_LOG_LAG
from AUDIT_TABLE)
select T_ID, E_ID,
/* updated entry */
regexp_replace(detail_log, q'[(Dept_ID: from '.*' to '';|Dept_ID: from '' to '.*';)]', '') DETAIL_LOG
from al
where (DETAIL_LOG like q'[%Dept_ID: from '_%' to '';%]' and /* first wrong record */
DETAIL_LOG_LEAD like q'[%Dept_ID: from '' to '_%';%]') OR
(DETAIL_LOG like q'[%Dept_ID: from '' to '_%';%]' and /* second wrong record */
DETAIL_LOG_LAG like q'[%Dept_ID: from '_%' to '';%]')
;
возврат
T_ID E_ID DETAIL_LOG
---------- ---------- ------------
1 111 USER_1; Salary: from '25' to '30';
2 111 USER_1;
Обновление
Оператор UPDATE
представляет собой простую переформулировку вышеприведенного запроса с использованием IN
(подзапрос) для ограничения области действия.
update AUDIT_TABLE
set DETAIL_LOG = regexp_replace(detail_log, q'[(Dept_ID: from '.*' to '';|Dept_ID: from '' to '.*';)]', '')
where (T_ID, E_ID) in
-- query from above that limits the updated rows
Удаление пустых записей аудита после этой очистки является тривиальным шагом.