将:var与"IN"一起使用WHERE子句中的运算符
我通常使用MySQL或SQL Server,并且在Oracle SQL Developer中遇到了相当大的问题.
I'm usually working with MySQL or SQL Server and I've experienced quite a problem in Oracle SQL Developer.
我有这样的查询(使复制问题变得简单)
I have query like this (making it simple just to replicate my issue):
SELECT *
FROM table t1
WHERE t1.date > :START_DATE AND t1.date < :END_DATE AND t1.id IN (:IDS)
当我运行此查询时,对话框窗口将打开,并提示我输入变量.
When I run this query, the dialog window opens and I'm prompted to enter the variables.
问题是当我输入逗号分隔的ID(例如5,6,7
或带引号'5,6,7'
)时,出现此错误:
Problem is when I enter comma separated ids like 5,6,7
or with quotes '5,6,7'
I get this error:
ORA-01722:无效的号码
01722. 00000-无效编号"
*原因:
*动作:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
这里有什么想法吗?
PS:必须有对话框提示才能输入变量.同事对SQL不友好. ;)
PS: There has to be dialog prompt to enter variables. Colleagues are not SQL friendly. ;)
问题在于绑定变量:ids
包含文字值(而不是文字值列表),因此您的查询是:
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' )
代替:
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 )
或使用LIKE
比较列表:
SELECT *
FROM table t1
WHERE t1.date > :START_DATE
AND t1.date < :END_DATE
AND ',' || :ids || ',' LIKE '%,' || t1.id || ',%'
或传入分隔字符串文字并将其拆分:
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
子句中起作用.)
(Or, a comma spearated list of numbers would work in the IN
clause if you used a substitution variable instead of a bind variable.)