如何标记分号分隔的列值以传递给 Oracle DB 函数中的 IF 语句

How to tokenize semicolon separated column value to pass to IF statement in a function in Oracle DB

我有一个名为 'config' 的 table,当我按以下方式查询时:

SELECT value FROM config WHERE property = 'SPECIAL_STORE_ID'

其响应将是:59216;131205;76707;167206 //... (1)

我想使用分号作为分隔符对上述值进行标记化,然后在用户定义函数的 IF 语句中使用它们进行比较,如下所示:

IF in_store_id exists in (<delimited response from (1) above>)//...(2)
THEN do some stuff

其中in_store_id是传入函数的参数

这是否可以作为上面(2)中的一行来做?

我在 Oracle 12c

单线?我不这么认为,但是 - 如果您对这样的事情感到满意,那很好。

SQL> select * From config;

VALUE          PROPERTY
-------------- ----------------
7369;7499;7521 SPECIAL_STORE_ID

SQL> declare
  2    in_store_id varchar2(20) := 7369;
  3    l_exists    number;
  4  begin
  5    select instr(value, ';' || in_store_id || ';')
  6      into l_exists
  7      from config
  8      where property = 'SPECIAL_STORE_ID';
  9
 10    if l_exists > 0 then
 11       dbms_output.put_line('that STORE_ID exists in the value');
 12    else
 13       dbms_output.put_line('that STORE_ID does not exist in the value');
 14    end if;
 15  end;
 16  /
that STORE_ID exists in the value

PL/SQL procedure successfully completed.

SQL>

如果分隔响应是一个集合,那么您可以使用 member of 检查集合是否包含 ID,例如

create or replace procedure test_procedure2(p_property in varchar2, p_id in varchar2) is
    type test_t is table of varchar2(20);
    l_ids test_t;
begin
    select regexp_substr(value, '[^;]+', 1, level) bulk collect into l_ids
    from (select value from config where property = p_property)
    connect by level <= regexp_count(value, ';')+1;
    
    if(p_id member of (l_ids)) then
        dbms_output.put_line('Do stuff for '||p_property||' '||p_id);
    end if;
end;
/

或者不使用中间 select 的集合,比如

create or replace procedure test_procedure1(p_property in varchar2, p_id in varchar2) is
    l_flag number(3);
begin
    select count(1) into l_flag from dual where p_id in (
        select regexp_substr(value, '[^;]+', 1, level)
        from (select value from config where property = p_property)
        connect by level <= regexp_count(value, ';')+1
    );
    
    if(l_flag > 0) then
        dbms_output.put_line('Do stuff for '||p_property||' '||p_id);
    end if;
end;
/

fiddle