# C#中怎么調用Oracle帶有游標的存儲過程
## 一、前言
在Oracle數據庫開發中,存儲過程是封裝復雜業務邏輯的重要方式。當存儲過程需要返回多行數據時,通常會使用游標(Cursor)作為輸出參數。本文將詳細介紹如何在C#中調用Oracle帶有游標的存儲過程,包括參數綁定、游標處理等關鍵步驟。
---
## 二、準備工作
### 1. 環境要求
- Oracle數據庫(10g/11g/12c等版本)
- .NET Framework 4.0+ 或 .NET Core 3.1+
- Oracle Data Provider for .NET (ODP.NET)
### 2. 引用Oracle庫
通過NuGet安裝Oracle官方驅動:
```bash
Install-Package Oracle.ManagedDataAccess
假設存在以下存儲過程,返回員工信息游標:
CREATE OR REPLACE PROCEDURE GetEmployeesByDept(
p_dept_id IN NUMBER,
p_emp_cursor OUT SYS_REFCURSOR
) AS
BEGIN
OPEN p_emp_cursor FOR
SELECT employee_id, first_name, salary
FROM employees
WHERE department_id = p_dept_id;
END;
using Oracle.ManagedDataAccess.Client;
string connString = "User Id=scott;Password=tiger;Data Source=orcl";
using (var conn = new OracleConnection(connString))
{
conn.Open();
// 后續代碼...
}
using (var cmd = new OracleCommand("GetEmployeesByDept", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// 添加輸入參數
cmd.Parameters.Add("p_dept_id", OracleDbType.Int32).Value = 10;
// 添加輸出游標參數
var outParam = new OracleParameter(
"p_emp_cursor",
OracleDbType.RefCursor,
ParameterDirection.Output
);
cmd.Parameters.Add(outParam);
// 執行存儲過程
cmd.ExecuteNonQuery();
// 處理游標結果
using (var reader = ((OracleRefCursor)outParam.Value).GetDataReader())
{
while (reader.Read())
{
Console.WriteLine($"ID: {reader["employee_id"]}, " +
$"Name: {reader["first_name"]}, " +
$"Salary: {reader["salary"]}");
}
}
}
ParameterDirection.Input(可省略)ParameterDirection.Output必須使用OracleDbType.RefCursor類型,對應Oracle的SYS_REFCURSOR
通過((OracleRefCursor)param.Value).GetDataReader()將游標轉換為DataReader
public List<Employee> GetEmployees(int deptId)
{
var employees = new List<Employee>();
using (var conn = new OracleConnection(connString))
using (var cmd = new OracleCommand("GetEmployeesByDept", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("p_dept_id", OracleDbType.Int32).Value = deptId;
var outParam = cmd.Parameters.Add("p_emp_cursor", OracleDbType.RefCursor,
ParameterDirection.Output);
conn.Open();
cmd.ExecuteNonQuery();
using (var reader = ((OracleRefCursor)outParam.Value).GetDataReader())
{
while (reader.Read())
{
employees.Add(new Employee
{
Id = Convert.ToInt32(reader["employee_id"]),
Name = reader["first_name"].ToString(),
Salary = Convert.ToDecimal(reader["salary"])
});
}
}
}
return employees;
}
ORA-06550錯誤
檢查參數名稱、類型是否與存儲過程定義完全一致(區分大小寫)
游標未關閉
確保使用using語句或手動調用Dispose()釋放資源
性能優化
對于大數據集,建議使用分頁游標或限制返回行數
通過ODP.NET調用Oracle游標存儲過程的關鍵在于:
1. 正確配置OracleDbType.RefCursor參數
2. 妥善處理游標到DataReader的轉換
3. 注意資源釋放和異常處理
掌握這些技術后,可以高效地在C#應用中集成Oracle的復雜數據處理邏輯。 “`
注:實際使用時請根據您的Oracle版本和.NET環境調整代碼細節,建議添加適當的異常處理機制。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。