The issue is that the bind variable :ids
contains a literal value (rather than a list of literal values) so your query is:
AND t1.id IN ( '5,6,7' )
instead of:
AND t1.id IN ( 5, 6, 7 )
What you need to do is either pass in a collection (which you could define from an array in an external language and pass in directly as a bind variable):
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 )
Or compare the list using LIKE
:
SELECT *
FROM table t1
WHERE t1.date > :START_DATE
AND t1.date < :END_DATE
AND ',' || :ids || ',' LIKE '%,' || t1.id || ',%'
Or pass in a 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+' ) );
(Or, a comma spearated list of numbers would work in the IN
clause if you used a substitution variable instead of a bind variable.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…