首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

C# 呼叫 Oracle 預存程序並接收輸出參數完整範例

     編輯:Oracle 資料庫基礎

資料庫端:建立測試程序

CREATE OR REPLACE PACKAGE test_pkg AS
  PROCEDURE test_pro(
    p_input  IN  VARCHAR2,
    p_output OUT NUMBER
  );
END test_pkg;
/

CREATE OR REPLACE PACKAGE BODY test_pkg AS
  PROCEDURE test_pro(p_input IN VARCHAR2, p_output OUT NUMBER) IS
  BEGIN
    -- 示範邏輯:回傳輸入字串長度
    p_output := LENGTH(p_input);
  END;
END test_pkg;
/

C# 端完整程式碼

using System;
using System.Data;
using Oracle.ManagedDataAccess.Client;  // 官方 Managed Driver

namespace OracleProcDemo
{
    class Program
    {
        static string ConnStr = "User Id=scott;Password=tiger;Data Source=ORCL;";

        static int ExecuteProc(string input)
        {
            int result = 0;
            using (var conn = new OracleConnection(ConnStr))
            using (var cmd = new OracleCommand("test_pkg.test_pro", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;

                // 輸入參數
                cmd.Parameters.Add("p_input", OracleDbType.Varchar2, input, ParameterDirection.Input);

                // 輸出參數:必須指定型別與大小
                var outParam = cmd.Parameters.Add("p_output", OracleDbType.Int32, ParameterDirection.Output);
                // OracleDbType.Int32 對應 NUMBER,無需 Size

                conn.Open();
                cmd.ExecuteNonQuery();

                // 取得輸出值
                result = Convert.ToInt32(outParam.Value);
            }
            return result;
        }

        static void Main()
        {
            try
            {
                int len = ExecuteProc("Hello Oracle");
                Console.WriteLine($"Input length: {len}");  // 輸出 12
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }
}

關鍵點總結

項目說明
CommandTypeCommandType.StoredProcedure
參數命名與 PL/SQL 參數名一致(不區分大小寫),建議加 p_ 前綴
輸出參數ParameterDirection.Output 或 InputOutput
OracleDbType必須精確對應:Varchar2, Int32, Decimal, Date, RefCursor 等
REF CURSOROracleDbType.RefCursor,取得後轉 OracleDataReader
陣列綁定批次執行時使用 cmd.ArrayBindCount + 參數 Value 為陣列

常見錯誤與解決

  • ORA-06550: PLS-00306: wrong number or types of arguments → 參數名稱/型別/順序不符,檢查 cmd.Parameters 對應。
  • ORA-01008: not all variables bound → 遺漏參數,確認所有 IN/OUT/IN OUT 皆已 Add。
  • 輸出參數為 DBNull → PL/SQL 程式未賦值,或例外導致未執行到賦值語句。
  • 連線字串:Managed Driver 使用 Data Source= (Easy Connect 或 TNS 別名);若用 TNS_ADMIN 確保環境變數正確。

進階:回傳 REF CURSOR

-- PL/SQL
PROCEDURE get_emps(p_deptno IN NUMBER, p_rc OUT SYS_REFCURSOR) IS
BEGIN
  OPEN p_rc FOR SELECT * FROM emp WHERE deptno = p_deptno;
END;

-- C#
var rcParam = cmd.Parameters.Add("p_rc", OracleDbType.RefCursor, ParameterDirection.Output);
conn.Open();
cmd.ExecuteNonQuery();
using (var reader = ((OracleRefCursor)rcParam.Value).GetDataReader())
{
    while (reader.Read()) Console.WriteLine(reader["ename"]);
}

結語

使用 Oracle.ManagedDataAccess.Client 為官方推薦、無需安裝 Client 的純 .NET 驅動。核心在於:**精確對應參數型別、正確設定 Direction、using 區塊確保連線釋放**。掌握此模式即可涵蓋 90% 的預存程序呼叫場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved