REGEXP_SUBSTR 无法仅处理当前行

REGEXP_SUBSTR not able to process only current row

(SELECT LISTAGG(EVENT_DESC, ',') WITHIN GROUP (ORDER BY EVENT_DESC) FROM EVENT_REF WHERE EVENT_ID IN 
                                    (   SELECT REGEXP_SUBSTR(AFTER_VALUE,'[^,]+', 1, level) FROM DUAL
                                        CONNECT BY REGEXP_SUBSTR(AFTER_VALUE, '[^,]+', 1, level) IS NOT NULL
                                    )
                                )

我正在从中获取 AFTER_VALUE 的 table 具有整数值,它们以逗号分隔,如

AFTER_VALUE数据 预期输出
1 事件 1
1,2 事件 1、事件 2
1,12,2,5 事件 1、事件 12、事件 2、事件 5
15,13 事件 15、事件 13

这些是 EVENT_REF table 中的 ID,其中有一些描述。我试图基本上呈现 前任。 1,2 作为 Event1、Event2 并从查询发回。有多个事件,所以使用 REPLACE 会非常乏味。

使用上述查询时,只要 AFTER_VALUE 列 Ex 中有多个值,我就会收到“ORA-01722:无效数字”错误。如果只有一个 id ,则查询有效,但对于 1,2 或 1,13 等值,它会抛出无效数字错误。

PS: 事件名称不是Event1,Event2之类的,我只是放上去供参考。

不需要拆分和连接子字符串,只需使用regexp_replace:

with EVENT_REF (AFTER_VALUE) as (
select '1' from dual union all
select '1,2' from dual union all
select '1,12,2,5' from dual union all
select '15,13' from dual
)
select regexp_replace(AFTER_VALUE,'(\d+)','Event') from EVENT_REF;

REGEXP_REPLACE(AFTER_VALUE,'(\D+)','EVENT')
-----------------------------------------------
Event1
Event1,Event2
Event1,Event12,Event2,Event5
Event15,Event13

您甚至不需要为此作业使用正则表达式。标准字符串函数 replace() 可以做同样的事情,而且速度更快。您只需要在字符串的开头添加一个额外的 'Event',因为那个不会“替换”任何东西。

像这样:(请注意,您不需要 with 子句;我包含它只是为了快速测试)

with
  event_ref (after_value) as (
    select '1'        from dual union all
    select '1,2'      from dual union all
    select '1,12,2,5' from dual union all
    select '15,13'    from dual
  )
select after_value,
       'Event' || replace(after_value, ',', ',Event') as desired_output
from   event_ref
;

AFTER_VALUE  DESIRED_OUTPUT     
-----------  -----------------------------
1            Event1                   
1,2          Event1,Event2      
1,12,2,5     Event1,Event12,Event2,Event5
15,13        Event15,Event13         

啊,好的,看起来,您的逗号分隔列表中还有其他字符,因此您可以使用此查询:

with EVENT_REF(EVENT_ID,EVENT_DESC) as (
  select  1, 'Desc 1' from dual union all
  select  2, 'Desc 2' from dual union all
  select  3, 'Desc 3' from dual union all
  select  4, 'Desc 4' from dual union all
  select  5, 'Desc 5' from dual union all
  select 12, 'Desc12' from dual union all
  select 13, 'Desc13' from dual union all
  select 15, 'Desc15' from dual
)
select
(SELECT LISTAGG(EVENT_DESC, ',') 
   WITHIN GROUP (ORDER BY EVENT_DESC)
 FROM EVENT_REF 
 WHERE EVENT_ID IN 
          (   SELECT to_number(REGEXP_SUBSTR(AFTER_VALUE,'\d+', 1, level))
              FROM DUAL
              CONNECT BY level<=REGEXP_COUNT(AFTER_VALUE, '\d+')
          )
      )
from (
  select '1'        AFTER_VALUE from dual union all
  select '1,2'      AFTER_VALUE from dual union all
  select '1,12,2,5' AFTER_VALUE from dual union all
  select '15,13'    AFTER_VALUE from dual
);

PS。并且不要忘记 to_number 现在有 'default on conversion error':https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/TO_NUMBER.html