我有一个使用IN子句的参数化SQL语句,以便通过一个查询更新多个记录。它是一个整数字段,即RID(记录ID),用于进行更新。如果仅传递一个RID,则可以使用,但如果传递多个值,则会得到Error: ORA-01722: invalid number
。
这是代码:
sbQuery.Append("update EXC_LOG set supv_emp_id=:userId, status=:exceptionStatus, supv_comments=:exceptionComment ");
sbQuery.Append("where RID in (:rid)");
ctx.Database.ExecuteSqlCommand(sbQuery.ToString(),
new OracleParameter("userId", UserId),
new OracleParameter("exceptionStatus", exceptionStatus),
new OracleParameter("exceptionComment", comment),
new OracleParameter("rid", rid));
如果我传递一个值RID,它可以工作,但是如果我传递多个逗号分隔(例如:1234,5566,8899),则会收到无效数字错误。
使用参数时如何传递多个整数值?
答案 0 :(得分:2)
您正在将单个字符串参数传递给IN()
。如果该数字恰好包含一个数字,那么您实际上是在做:
where RID in ('12345')
,由于您的RID
列为数字,因此将进行隐式转换,处理方式为:
where RID in (to_number('12345'))
这很好。但是在单个字符串参数中包含多个值,您实际上是在尝试这样做:
where RID in (to_number('12345,5566,8899'))
和to_number('12345,5566,8899')
将抛出ORA-01722:无效的数字。
有多种方法可以将定界的字符串解包为单个值,但是一种简单的方法是将它们视为XPath序列,并通过XMLTable调用进行放置:
sbQuery.Append("where RID in (select RID from XMLTable(:rid columns RID number path '.'))");
作为该方法的演示,首先XMLTable调用如何使用SQL * Plus绑定变量扩展字符串:
var rid varchar2(30);
exec :rd := '12345,5566,8899';
select RID from XMLTable('12345,5566,8899' columns RID number path '.');
RID
----------
12345
5566
8899
,然后在针对虚拟表的虚拟查询中:
with EXC_LOG (RID, SUPV_EMP_ID, STATUS, SUPV_COMMENT) as (
select 12345, 123, 'OK', 'Blah blah' from dual
union all select 8899, 234, 'Failed', 'Some comment' from dual
union all select 99999, 456, 'Active', 'Workign on it' from dual
)
select *
from EXC_LOG
where RID in (select RID from XMLTable('12345,5566,8899' columns RID number path '.'));
RID SUPV_EMP_ID STATUS SUPV_COMMENT
---------- ----------- ------ -------------
12345 123 OK Blah blah
8899 234 Failed Some comment
您的代码将使用相同的过滤器进行更新而不是选择。