C#调用Oracle存储过程报Value does not fall within the expected range错误求解决
问题排查思路
- 优先核对存储过程参数匹配度:你定义的Oracle存储过程共有3个参数,2个输入参数uNAME、pWORD,1个输出游标参数po_refcsr,但C#代码中仅添加了2个输入参数,未声明输出游标参数,这是触发该异常的最常见原因。
- 检查参数类型兼容性:Oracle参数应使用
OracleDbType枚举,你代码中用的SqlDbType是SQL Server专用类型枚举,类型不匹配也会触发范围异常。 - 确认参数方向设置:输出游标必须显式设置
ParameterDirection.Output,同时指定类型为OracleDbType.RefCursor。 - 排查资源释放逻辑:using代码块会自动释放连接资源,不需要手动调用
Close()和Dispose(),多余的释放操作可能引发异常。 - 验证参数大小写匹配:部分Oracle驱动对参数名大小写敏感,需保证C#中定义的参数名和存储过程定义完全一致。
代码修正说明
本次核心改动如下:
- 补充缺失的输出游标参数po_refcsr,指定类型为
OracleDbType.RefCursor,方向设为输出 - 将原代码中
SqlDbType.VarChar替换为OracleDbType.Varchar2,匹配Oracle字符串类型 - 给
OracleCommand添加using块避免资源泄漏,删除using块内多余的手动连接释放代码 - 建议使用Oracle官方维护的
Oracle.ManagedDataAccessNuGet包,已弃用的System.Data.OracleClient可能存在兼容性问题
using Oracle.ManagedDataAccess.Client; using System.Data; public bool checkUser(string uName, string pWord) { bool result = false; try { string dbUName = string.Empty; string dbPWord = string.Empty; using (OracleConnection conn = new OracleConnection(TNS)) using (OracleCommand objCmd = new OracleCommand()) { objCmd.Connection = conn; objCmd.CommandText = "PKGFAETEST.CheckUser"; objCmd.CommandType = CommandType.StoredProcedure; // 适配Oracle专用参数类型 objCmd.Parameters.Add("uNAME", OracleDbType.Varchar2).Value = uName; objCmd.Parameters.Add("pWORD", OracleDbType.Varchar2).Value = pWord; // 补充输出游标参数 objCmd.Parameters.Add("po_refcsr", OracleDbType.RefCursor).Direction = ParameterDirection.Output; conn.Open(); using (OracleDataReader reader = objCmd.ExecuteReader()) { while (reader.Read()) { if (reader["USERNAME"] != DBNull.Value) { dbUName = Convert.ToString(reader["USERNAME"]); } if (reader["PASS"] != DBNull.Value) { dbPWord = Convert.ToString(reader["PASS"]); } result = true; } } } } catch (Exception e) { Console.WriteLine("Exception caught: {0}", e); } return result; }
内容的提问来源于stack exchange,提问作者Ann
相关产品推荐
相关产品推荐

