在 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) - 检查防火墙和数据库权限
- 验证 TNS 名称配置(或使用 EZ Connect:
替代方案:使用 DataAdapter
// 替代 dt.Load(dr) 的写法
using (OracleDataAdapter da = new OracleDataAdapter(cmd))
{
DataSet ds = new DataSet();
da.Fill(ds); // 自动处理游标
return ds.Tables[0];
}
提示:对于大型数据集,建议使用分页(在存储过程中实现 LIMIT/OFFSET)避免一次性加载过多数据。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/286909.html

