【问题标题】:Alternative to REGEXP_LIKE due to regular expression too long由于正则表达式太长而替代 REGEXP_LIKE
【发布时间】:2017-12-26 08:48:55
【问题描述】:

我在尝试查找数据库中是否已存在某些 ID 时收到 ORA-12733:正则表达式太长错误。

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

a.ID 和 b.ID 的格式类似于 id=16069,16070,16071,16072,16099,16100。

我会将逗号替换为 |在 b 所以它会告诉我是否有任何数字匹配。 a.IDs 和 b.IDs 的长度可能因不同的查询而异。 Oracle regexp_like 限制只有 512。谁知道是否有其他可能的解决方案?

【问题讨论】:

  • 最佳解决方案:不要将逗号分隔的列表存储在文本字符串中。
  • 你可以写一个存储函数来做检查

标签: oracle regexp-like


【解决方案1】:

你到底为什么将数字列表存储为字符串?

无论如何,一种可能的解决方案就是这个。像这样创建 TYPE 和 FUNCTION:

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, ',')

看看Multiset Conditions

【讨论】:

    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多