我不想使用动态SQL,所以我正在尝试其他方式来更改where语句。
在我的WHERE语句中,有一行:
AND c.nregion = pnregion
pnregion
是俄罗斯的一些地区。该语句可帮助我的光标更快地工作,因为Oracle不必浏览整个表。
问题在于,如果pnregion
等于47或78,则此行应如下所示
AND c.nregion in (47, 78)
该怎么做?我应该以某种方式使用CASE还是在光标之外可以做一些事情?
答案 0 :(得分:2)
您可以使用:
WHERE ( c.nregion = pnregion
OR ( pnregion IN ( 47, 78 )
AND c.nregion IN ( 47, 78 )
)
)
如果您想要两个以上的值,则可以轻松扩展此值,因为可以将这些值添加到两个IN
过滤器中。
答案 1 :(得分:1)
您可以使用decode函数根据代码47/78添加另一个选项:
AND (c.nregion = pnregion OR c.nregion = decode(pnregion, 47, 78, 78, 47))
答案 2 :(得分:1)
如果我理解这个问题,则是 IN列表中的各种元素困扰着您。换句话说,除非您使用
,否则不能将逗号分隔的值放入IN列表中这是一个基于斯科特模式的示例;希望您能理解。
这是您当前拥有的:
SQL> create or replace procedure p_test (pnregion in varchar2)
2 is
3 cursor c1 is select empno, ename from emp
4 where deptno in pnregion;
5 begin
6 for cr in c1 loop
7 dbms_output.put_line(cr.ename);
8 end loop;
9 end;
10 /
Procedure created.
SQL> -- This is OK
SQL> exec p_test('10');
CLARK
KING
MILLER
PL/SQL procedure successfully completed.
SQL> -- This is not OK
SQL> exec p_test('10, 20');
BEGIN p_test('10, 20'); END;
*
ERROR at line 1:
ORA-01722: invalid number
ORA-06512: at "SCOTT.P_TEST", line 6
ORA-06512: at line 1
SQL>
现在,将逗号分隔的值拆分为行,并观察其工作:
SQL> create or replace procedure p_test (pnregion in varchar2)
2 is
3 cursor c1 is select empno, ename from emp
4 where deptno in (select regexp_substr(pnregion, '[^,]+', 1, level)
5 from dual
6 connect by level <= regexp_count(pnregion, ',') + 1
7 );
8 begin
9 for cr in c1 loop
10 dbms_output.put_line(cr.ename);
11 end loop;
12 end;
13 /
Procedure created.
SQL> -- This is OK
SQL> exec p_test('10');
CLARK
KING
MILLER
PL/SQL procedure successfully completed.
SQL> -- This is also OK now
SQL> exec p_test('10, 20');
SMITH
JONES
CLARK
SCOTT
KING
ADAMS
FORD
MILLER
PL/SQL procedure successfully completed.
SQL> -- Or even some more values:
SQL> exec p_test('10, 20,30');
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
PL/SQL procedure successfully completed.
SQL>