inlist oracle,sql中一个字符串的in-list判断问题

本文介绍了一种在Oracle数据库中使用DUAL表和连接级别语法来解析绑定变量中的列表值的方法。通过创建一个简单的视图和存储过程,可以有效地处理包含多个元素的逗号分隔字符串,并将其用于查询条件,简化了复杂查询的编写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

你同事的方法没用上绑定变量。

转帖:

http://tkyte.blogspot.com/2006/06/varying-in-lists.html

......

If you are in 9iR2 and above

Then we can skip the function all together and just use DUAL to generate rows and parse the string. Consider:

SQL> select level l

2    from dual

3  connect by level <= 5;

L

----------

1

2

3

4

5

So, we can use DUAL to generate rows and then using substr/instr – effectively parse the bind variable and return the i'th element from it. For example:

SQL> exec :txt := 'SYS, SYSTEM'

PL/SQL procedure successfully completed.

SQL> with data

2  as

3  (

4  select

5    trim( substr (txt,

6          instr (txt, ',', 1, level  ) + 1,

7          instr (txt, ',', 1, level+1)

8             - instr (txt, ',', 1, level) -1 ) )

9      as token

10    from (select ','||:txt||',' txt

11            from dual)

12  connect by level <=

13     length(:txt)-length(replace(:txt,',',''))+1

14  )

15  select * from data;

TOKEN

----------------------------------

SYS

SYSTEM

Once we have that accomplished – the rest is easy:

SQL> with data

2  as

3  (

4  select

5    trim( substr (txt,

6          instr (txt, ',', 1, level  ) + 1,

7          instr (txt, ',', 1, level+1)

8             - instr (txt, ',', 1, level) -1 ) )

9      as token

10    from (select ','||:txt||',' txt

11            from dual)

12  connect by level <=

13     length(:txt)-length(replace(:txt,',',''))+1

14  )

15  select *

16    from all_users

17   where username in (select * from data);

USERNAME      USER_ID CREATED

---------- ---------- ---------

SYSTEM              5 30-JUN-05

SYS                 0 30-JUN-05

Now, some people look at that “with data” bit and say “that is too much, too hard to code that every time”. We can use a VIEW to hide the complexity here – and use a stored procedure as our way to “bind to the view” (this is sort of a parameterized view in effect). It would look like this:

SQL> create or replace context my_ctx using my_ctx_procedure

2  /

Context created.

SQL> create or replace

2  procedure my_ctx_procedure

3  ( p_str in varchar2 )

4  as

5  begin

6          dbms_session.set_context

7          ( 'my_ctx', 'txt', p_str );

8  end;

9  /

Procedure created.

SQL> create or replace view IN_LIST

2  as

3  select

4    trim( substr (txt,

5          instr (txt, ',', 1, level  ) + 1,

6          instr (txt, ',', 1, level+1)

7             - instr (txt, ',', 1, level) -1 ) )

8      as token

9    from (select ','||sys_context('my_ctx','txt')||',' txt

10            from dual)

11  connect by level <=

12     length(sys_context('my_ctx','txt'))

13       -length(replace(sys_context('my_ctx','txt'),',',''))+1

14  /

View created.

SQL> exec my_ctx_procedure( :txt )

PL/SQL procedure successfully completed.

SQL> select *

2    from all_users

3   where username in

4   (select * from IN_LIST);

USERNAME      USER_ID CREATED

---------- ---------- ---------

SYSTEM              5 30-JUN-05

SYS                 0 30-JUN-05

Now, you “bind” your queries in-list by calling MY_CTX_PROCEDURE and the view does the rest.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值