Альтернатива REGEXP_LIKE из-за слишком длинного регулярного выражения

Я получаю ошибку ORA-12733: слишком длинное регулярное выражение при попытке определить, есть ли определенные идентификаторы в базе данных.

regexp_like (','||a.IDs||',',',('||replace(b.IDs,',','|')||'),')

Идентификаторы a.ID и b.ID имеют следующий формат: id = 16069,16070,16071,16072,16099,16100.

я заменю запятую на | в b, чтобы он сказал мне, совпадает ли какой-либо из номеров. Длина обоих идентификаторов a.ID и b может варьироваться в зависимости от запроса. Ограничение Oracle regexp_like составляет всего 512. Кто-нибудь знает, есть ли другие возможные решения?


person Fiona    schedule 26.12.2017    source источник
comment
Лучшее решение: не храните списки, разделенные запятыми, в текстовых строках.   -  person Bob Jarvis - Reinstate Monica    schedule 26.12.2017
comment
вы можете написать сохраненную функцию, которая проверяет   -  person Turo    schedule 26.12.2017


Ответы (1)


Почему вы храните список чисел в виде строки?

В любом случае, одно из возможных решений - это одно. Создайте ТИП и ФУНКЦИЮ следующим образом:

CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;


CREATE OR REPLACE FUNCTION SplitArray(LIST IN VARCHAR2, Separator IN VARCHAR2) RETURN NUMBER_TABLE_TYPE IS
    OutTable NUMBER_TABLE_TYPE; 
BEGIN

    IF LIST IS NULL THEN
        RETURN NULL;
    ELSE
        SELECT REGEXP_SUBSTR(LIST, '[^'||Separator||']+', 1, LEVEL)
        BULK COLLECT INTO OutTable
        FROM dual
        CONNECT BY REGEXP_SUBSTR(LIST, '[^'||Separator||']+', 1, LEVEL) IS NOT NULL;
    END IF;

    IF OutTable.COUNT > 0 THEN
        RETURN OutTable;
    ELSE
        RETURN NULL;
    END IF;

END SplitArray;

Затем вы запрашиваете одно число следующим образом:

WHERE 16071 MEMBER OF SplitArray(a.IDs, ',')

или для нескольких чисел, например:

WHERE SplitArray(b.IDs, ',') SUBMULTISET OF SplitArray(a.IDs, ',')

Ознакомьтесь с Условиями нескольких наборов

person Wernfried Domscheit    schedule 26.12.2017