PL/SQL query IN comma deliminated string

前端 未结 10 2128
攒了一身酷
攒了一身酷 2021-01-02 04:46

I am developing an application in Oracle APEX. I have a string with user id\'s that is comma deliminated which looks like this,

45,4932,20,19
10条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-02 05:34

    Please dont use: WHERE ','||to_char(:P5_USER_ID_LIST)||',' like '%,'||to_char(u.user_id)||',%' because you'll force a full table scan although with the users table you may not have that many so the impact will be low but against other tables in an enterprise environment this is a problem.

    EDIT: I have put together a script to demonstrate the differences between the regex method and the wildcard like method. Not only is regex faster but it's also a lot more robust.

    -- Create table
    create table CSV_TEST
    (
      NUM NUMBER not null,
      STR VARCHAR2(20)
    );
    
    
    create sequence csv_test_seq;
    
    begin
      for j in 1..10 loop
        for i in 1..500000 loop
         insert into csv_test( num, str ) values ( csv_test_seq.nextval, to_char( csv_test_seq.nextval ));
        end loop;
        commit;
      end loop;
    end;
    /
    
    -- Create/Recreate primary, unique and foreign key constraints 
    alter table CSV_TEST
      add constraint CSV_TEST_PK primary key (NUM)
      using index ;
    alter table CSV_TEST
      add constraint CSV_TEST_FK unique (STR)
      using index;
    
    select sysdate from dual;
    select *
    from csv_test t
    where t.num in ( Select Regexp_Substr('100001, 100002,   100003   ,      100004, 100005','[^,]+', 1, Level) From Dual
                     Connect By Regexp_Substr('100001, 100002,100003, 100004, 100005', '[^,]+', 1, Level) Is Not Null);
    select sysdate from dual;
    
    select *
    from csv_test t
    where ('%,' || '100001,100002,   100003,  100004  ,100005' || ',%') like '%,' || num || ',%';
    select sysdate from dual;
    select *
    from csv_test t
    where t.num in ( Select Regexp_Substr('100001, 100002,   100003   ,      100004, 100005','[^,]+', 1, Level) From Dual
                     Connect By Regexp_Substr('100001, 100002,100003, 100004, 100005', '[^,]+', 1, Level) Is Not Null);
    select sysdate from dual;
    
    select *
    from csv_test t
    where ('%,' || '100001,100002,   100003,  100004  ,100005' || ',%') like '%,' || num || ',%';
    select sysdate from dual;
    
    drop table csv_test;
    drop sequence csv_test_seq;
    

提交回复
热议问题