在WHERE子句

时间:2017-05-23 07:31:34

标签: sql oracle

我经常使用MySQL或SQL Server,而且我在Oracle SQL Developer中遇到了很多问题。

我有这样的查询(简单地复制我的问题):

SELECT *
FROM table t1
WHERE t1.date > :START_DATE AND t1.date < :END_DATE AND t1.id IN (:IDS)

当我运行此查询时,对话框窗口打开,我被提示输入变量。

问题是当我输入逗号分隔的ID,例如5,6,7或引号'5,6,7'时,我收到此错误:

  

ORA-01722:无效的号码
  01722. 00000 - “无效号码”
  *原因:
  *操作:

这里有什么想法吗?

PS:必须有提示输入变量的对话框。同事不是SQL友好的。 ;)

2 个答案:

答案 0 :(得分:0)

ID是NUMBERS还是VARCHAR2?

这个简单的案例对我有用。请试一试:

select id from
(
select 1 id from dual
union
select 2 id from dual
union
select 3 id from dual
)
where id in (:IDS)

答案 1 :(得分:0)

问题是绑定变量:ids包含文字值(而不是文字值列表),因此您的查询是:

AND t1.id IN ( '5,6,7' )

而不是:

AND t1.id IN ( 5, 6, 7 )

您需要做的是pass in a collection(您可以使用外部语言从数组定义并直接作为绑定变量传递):

CREATE OR REPLACE TYPE intlist IS TABLE OF INTEGER;
/

SELECT *
FROM table t1
WHERE t1.date > :START_DATE
AND   t1.date < :END_DATE
AND   t1.id MEMBER OF intlist( 5, 6, 7 )

或传递delimited string literal and split that

SELECT *
FROM table t1
WHERE t1.date > :START_DATE
AND   t1.date < :END_DATE
AND   t1.id   IN ( SELECT TO_NUMBER( REGEXP_SUBSTR( :ids, '\d+', 1, LEVEL ) )
                   FROM   DUAL
                   CONNECT BY LEVEL <= REGEXP_COUNT( :ids, '\d+' ) );

(或者,如果使用替换变量而不是绑定变量,则逗号分隔的数字列表将在IN子句中起作用。)