当前位置:首页 > 技术教程 > 正文

如何实现ASP.NET调用Oracle存储过程返回游标

在 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}"); } }

关键点说明

  1. 游标参数处理

    • 使用 OracleDbType.RefCursor 声明游标参数
    • 方向设置为 ParameterDirection.Output
    • 通过 ((OracleRefCursor)parameter.Value).GetDataReader() 获取数据
  2. 数据类型映射

    | Oracle 类型 | .NET 类型 | ODP.NET 类型 |

    |————|—————-|———————-|

    | NUMBER | int/decimal | OracleDbType.Int32 |

    | VARCHAR2 | string | OracleDbType.Varchar |

    | DATE | DateTime | OracleDbType.Date |

    | REF CURSOR | OracleRefCursor| OracleDbType.RefCursor|

    如何实现ASP.NET调用Oracle存储过程返回游标 第1张

  3. 错误处理

    • 始终使用 using 语句确保资源释放
    • 捕获 OracleException 处理数据库错误
    • 常见问题解决

      1. “ORA-06550: 参数数量或类型错误”

        • 检查参数名称和类型是否与存储过程完全一致
        • 确保参数顺序正确(按存储过程声明顺序添加)
      2. 游标返回空数据

        • 检查输入参数值是否正确传递
        • 直接在 Oracle 中测试存储过程:DECLARE c SYS_REFCURSOR; BEGIN GetEmployees(10, c); END;
        • 连接问题

          如何实现ASP.NET调用Oracle存储过程返回游标 第2张

          • 验证 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)避免一次性加载过多数据。

            如何实现ASP.NET调用Oracle存储过程返回游标 第3张

0