调用Oracle存储过程遇ORA-01858错误:非数值字符问题
解决C#调用Oracle存储过程时的ORA-01858错误
问题现象
通过C#代码调用Oracle存储过程pr_my_proc时,抛出错误:{"ORA-01858: a non-numeric character was found where a numeric was expected"},但使用exec命令直接执行该存储过程可成功运行。
相关代码
C#调用代码
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew, TimeSpan.FromMinutes(GlobalVariables.CommandTimeOut))) { ds = DataHelper.FillDS(dataAccessLayer, GlobalVariables.ConnectionString, "pr_my_proc", new Dictionary<string, DlmsParameter>() { { "pc", new CustomParameter() { Name = "pc", ParameterDirection = ParameterDirection.Input, ParamType = "VARCHAR2", Value = pc} }, { "sp", new CustomParameter() { Name = "sp", ParameterDirection = ParameterDirection.Input, ParamType = "VARCHAR2", Value = sp }}, { "pt", new CustomParameter() { Name = "pt", ParameterDirection = ParameterDirection.Input, ParamType = "INT64", Value = Convert.ToInt64(pt)} }, { "rt", new CustomParameter() { Name = "rt", ParameterDirection = ParameterDirection.Input, ParamType = "VARCHAR2", Value = rt } }, { "rv", new CustomParameter() { Name = "rv", ParameterDirection = ParameterDirection.Input, ParamType = "VARCHAR2", Value = rv.ToUpper() } } }, new string[] { "AD" }); }
Oracle存储过程定义
CREATE OR REPLACE PROCEDURE pr_my_proc ( pc VARCHAR2, sp VARCHAR2, pt NUMBER, rt VARCHAR2, rv VARCHAR2, RS1 OUT ReturnType.GenericRecordSet )
排查与解决方案
核对参数值一致性
确认C#代码传入的所有参数值(pc、sp、pt、rt、rv)与直接执行exec时使用的参数完全一致,重点检查rt、rv等字符串参数是否包含可能触发日期转换的内容(存储过程内部可能用这些参数做日期解析)。修正参数类型映射
存储过程中pt参数为NUMBER类型,C#代码中指定ParamType = "INT64"可能存在类型映射不匹配问题。将pt的ParamType改为"NUMBER",确保与Oracle参数类型完全对应:{ "pt", new CustomParameter() { Name = "pt", ParameterDirection = ParameterDirection.Input, ParamType = "NUMBER", Value = Convert.ToInt64(pt)} }检查DataHelper参数处理逻辑
确认CustomParameter的ParamType字段是如何映射到Oracle原生参数类型的。如果"INT64"被错误转换为字符串类型传入Oracle,存储过程内部处理时会因字符串转数字失败触发ORA-01858错误。需保证参数类型转换逻辑正确,将INT64值以数字类型而非字符串类型传递。启用参数日志排查
若DataHelper支持日志功能,开启参数日志,查看实际传递给Oracle的参数值和类型,对比直接执行exec时的参数,定位差异点。
内容的提问来源于stack exchange,提问作者Varun Rajput
相关产品推荐
相关产品推荐

