如何实现ASP.NET调用Oracle存储过程返回游标
- 技术教程
- 2026-02-08
- 4141
在 ASP.NET 中调用 Oracle 存储过程并返回游标(Ref Cursor)的完整步骤如下,这里使用 Oracle Managed Data Access (ODP.NET) 作为数据库驱动(推荐):
安装 NuGet 包
Install-Package Oracle.ManagedDataAccess.Core
Oracle 存储过程示例
CREATE OR REPLACE PROCEDURE GetEmployees ( p_department_id IN NUMBER, p_employees OUT SYS_REFCURSOR ) AS BEGIN OPEN p_employees FOR SELECT employee_id, first_name, last_name FROM employees WHERE department_id = p_department_id; END;
ASP.NET 后端代码(C#)
using Oracle.ManagedDataAccess.Client; using System.Data; public DataTable GetEmployeesByDepartment(int departmentId) { // 连接字符串(根据实际配置修改) string connString = "User Id=your_user;Password=your_pwd;Data Source=your_tns;"; using (OracleConnection conn = new OracleConnection(connString)) { conn.Open(); using (OracleCommand cmd = new OracleCommand("GetEmployees", conn)) { cmd.CommandType = CommandType.StoredProcedure; // 输入参数 cmd.Parameters.Add("p_department_id", OracleDbType.Int32).Value = departmentId; // 输出参数(游标) OracleParameter cursorParam = new OracleParameter(); cursorParam.ParameterName = "p_employees"; cursorParam.OracleDbType = OracleDbType.RefCursor; cursorParam.Direction = ParameterDirection.Output; cmd.Parameters.Add(cursorParam); // 执行存储过程 cmd.ExecuteNonQuery(); // 获取游标数据 using (OracleDataReader dr = ((OracleRefCursor)cmd.Parameters["p_employees"].Value).GetDataReader()) { DataTable dt = new DataTable(); dt.Load(dr); // 将 DataReader 转换为 DataTable return dt; } } } }
在 ASP.NET Web API/Controller 中使用
[HttpGet] public IActionResult GetEmployees(int deptId) { try { var data = GetEmployeesByDepartment(deptId); return Ok(data); } catch (Exception ex) { return StatusCode(500, $"Error: {ex.Message}"); } }
关键点说明
-
游标参数处理:
- 使用 OracleDbType.RefCursor 声明游标参数
- 方向设置为 ParameterDirection.Output
- 通过 ((OracleRefCursor)parameter.Value).GetDataReader() 获取数据
-
数据类型映射:
| Oracle 类型 | .NET 类型 | ODP.NET 类型 |
|————|—————-|———————-|
| NUMBER | int/decimal | OracleDbType.Int32 |
| VARCHAR2 | string | OracleDbType.Varchar |
| DATE | DateTime | OracleDbType.Date |
| REF CURSOR | OracleRefCursor| OracleDbType.RefCursor|

-
错误处理:
- 始终使用 using 语句确保资源释放
- 捕获 OracleException 处理数据库错误
-
“ORA-06550: 参数数量或类型错误”:
- 检查参数名称和类型是否与存储过程完全一致
- 确保参数顺序正确(按存储过程声明顺序添加)
-
游标返回空数据:
- 检查输入参数值是否正确传递
- 直接在 Oracle 中测试存储过程:DECLARE c SYS_REFCURSOR; BEGIN GetEmployees(10, c); END;
-
连接问题:

- 验证 TNS 名称配置(或使用 EZ Connect://host:port/service_name)
- 检查防火墙和数据库权限
替代方案:使用 DataAdapter
// 替代 dt.Load(dr) 的写法 using (OracleDataAdapter da = new OracleDataAdapter(cmd)) { DataSet ds = new DataSet(); da.Fill(ds); // 自动处理游标 return ds.Tables[0]; }
提示:对于大型数据集,建议使用分页(在存储过程中实现 LIMIT/OFFSET)避免一次性加载过多数据。

常见问题解决