- PVSM.RU - https://www.pvsm.ru -
Сталкивались ли вы с кейсом, когда по заданному списку email или номеров телефонов необходимо проверить всех клиентов на совпадение с ними? Поиск через интерфейс в различных системах не всегда удобен или даже невозможен. В этой статье я расскажу, как организовать универсальное хранилище объектов различного типа под разные цели. Мы создадим единый справочник в базе данных и организуем поиск по нему. Примеры кода будут приведены на языке Oracle PL/SQL, но их легко можно адаптировать под другие СУБД.
Основная таблица для хранения объектов содержит следующие поля:
create table OBJ_LST
(
iid NUMBER not null,
cacc VARCHAR2(2000),
ctype VARCHAR2(10),
ddate DATE default trunc(Sysdate)
);
объект хранения — строка,
тип объекта — это бизнес‑тип, определенный в отдельном справочнике типов (например, ИНН, email или номер банковской карты),
дата добавления в справочник — дает возможность вести аудит изменений и хранения историчных данных.
В справочнике типов заводятся бизнес‑типы данных с указанием их id, описания и регулярного выражения.
Объекты удобно группировать, чтобы работать с их подмножествами. Для этого есть справочник групп (или видов). В данном примере заведены группы для организации различных проверок в банке:
А сами группировки хранятся в отдельной таблице.
Для работы с данным хранилищем необходимо решить две задачи — работу с данными и организацию поиска.
При работе с данными помимо функций добавления, редактирования и удаление записей будем автоматизировать их группировку, а также массовое заведение. С первыми операциями проблем быть не должно, там будут простые CRUD‑операции. А вот массовое заведение по списку значений, заданных одной строкой, представляет бОльший интерес. Для этого используем процедуру, на вход которой подаем строку со списком объектов, тип объекта и группу (необязательный параметр) для автоматической группировки:
parse_str(pMess => cMess, pType => 'EMAIL', pStr => 'invanov@gmail.ru; petrov@mail.ru; sidorov@inbox.ru', pCtrl => 4)
Результатом выполнения будет заполнение хранилища объектами заданного типа.
Исходный код процедуры:
PROCEDURE parse_str(pMess OUT VARCHAR2, pType IN VARCHAR2, pStr IN CLOB, pCtrl IN NUMBER)
IS
cPatt VARCHAR2(254);
vStr CLOB := pStr;
CURSOR curTypes IS
SELECT CREGEXP FROM obj_types
WHERE CTYPE = pType;
BEGIN
OPEN curTypes;
FETCH curTypes INTO cPatt;
CLOSE curTypes;
IF cPatt IS NULL THEN
pMess := 'Не указано регулярное выражение для типа данных '||pType; RETURN;
END IF;
dbms_output.put_line('Строка для анализа: '||vStr);
FOR rOBJ IN (SELECT SUBSTR(regexp_substr(obj, patt, 1, rownum),2) rez_obj
FROM (SELECT vStr AS obj
, cPatt AS patt FROM dual) dual
CONNECT BY level <= regexp_count(obj, patt)
)
LOOP
IF rOBJ.rez_obj IS NOT NULL THEN
begin
ins_obj(rOBJ.rez_obj,pType,pCtrl);
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
END;
END IF;
END LOOP;
pMess := 'Разбор успешно завершен.';
EXCEPTION WHEN OTHERS THEN
pMess := 'Непредвиденная ошибка обработки: '||SQLERRM;
END parse_str;
Для организации поиска объекта по хранилищу создадим функцию, на вход которой подаем строку/объект для анализа, тип объекта (если пусто — то ищем по всем), номер группы (если пусто — то по всем) и дату загрузки данных (если пусто, то по всем):
check_str('Назначение платежа с указание номера банковской карты № 4976980039148296 договор ДГ45', 'CARD', 4, to_date('01.07.2026','dd.mm.rrrr'))
Если функция нашла совпадение исходной строки с объектом в базе, то она вернет этот самый объект.
Исходный код функции:
FUNCTION check_str(pStr IN VARCHAR2
, pType IN VARCHAR2 DEFAULT 'ALL'
, pCtrl IN NUMBER DEFAULT NULL
, pDate IN DATE DEFAULT NULL
) RETURN VARCHAR2
IS
BEGIN
FOR rOBJ IN (SELECT CACC
FROM obj_lst a
JOIN obj_grp_ctrl c ON c.idata_id = a.iid AND c.ictrl_id = nvl(pCtrl,c.ictrl_id)
WHERE CTYPE = DECODE(pType ,'ALL',CTYPE, pType)
AND DDATE >= nvl(pDate,to_date('01.01.1900','dd.mm.rrrr')))
LOOP
IF UPPER(pStr) LIKE '%'||UPPER(rOBJ.CACC)||'%' THEN
RETURN rOBJ.CACC;
END IF;
END LOOP;
RETURN NULL;
END check_str;
Таким образом, мы получили удобный справочник для хранения различных объектов и инструменты для его заполнения и поиска.
Автор: NikanCode
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sql/455702
Ссылки в тексте:
[1] Источник: https://habr.com/ru/articles/1064040/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1064040
Нажмите здесь для печати.