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

.NET 連接 Oracle 資料庫完整實戰:環境配置、連線字串與查詢範例

     編輯:Oracle 教學

.NET 連接 Oracle 資料庫完整實戰

在 .NET Framework 應用程式中存取 Oracle 資料庫,需正確安裝資料提供者、配置連線字串、處理常見參考缺失與編碼問題。本文以 Windows Forms 專案為例,完整呈現從 NuGet 套件安裝、連線池管理、參數化查詢到 UI 整合的端到端實作。

1. 環境準備與套件安裝

推薦:Oracle.ManagedDataAccess (官方純管理代碼提供者)

# Package Manager Console
Install-Package Oracle.ManagedDataAccess

或透過 NuGet 圖形介面搜尋「Oracle.ManagedDataAccess」安裝。此套件無需安裝 Oracle Client,部署極簡單。

舊版專案若使用 System.Data.OracleClient (已淘汰)

  • 需在「參考」→「加入參考」→「Framework」勾選 System.Data.OracleClient。
  • .NET Core / .NET 5+ 不支援,必須遷移至 Oracle.ManagedDataAccess.Core。

2. 連線字串最佳實踐

// app.config / web.config
<connectionStrings>
  <add name="OracleConn"
       connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.100)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=myuser;Password=mypwd;Pooling=true;Min Pool Size=1;Max Pool Size=100;Connection Lifetime=120;"
       providerName="Oracle.ManagedDataAccess.Client" />
</connectionStrings>

關鍵參數說明

參數說明建議值
Data Source易記名稱 (tnsnames.ora) 或完整 EZCONNECT 描述EZCONNECT 免維護 tnsnames.ora
User Id / Password認證帳密從設定檔讀取,勿硬編碼
Pooling啟用連線池true (生產環境必開)
Min Pool Size池最小連線數1~5
Max Pool Size池最大連線數50~200 視負載調整
Connection Lifetime連線存活秒數 (0=永久)120~300 定期回收避免殭屍連線
Validate Connection取出池時驗證連線有效性true (犧牲微小效能換穩定)
Unicode啟用 Unicode 支援true (含中文資料必開)

3. 核心資料存取類別實作

using System;
using System.Data;
using Oracle.ManagedDataAccess.Client;
using System.Configuration;

public static class OracleHelper
{
    private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["OracleConn"].ConnectionString;

    // 執行查詢回傳 DataTable
    public static DataTable ExecuteQuery(string sql, params OracleParameter[] parameters)
    {
        using (var conn = new OracleConnection(ConnStr))
        using (var cmd = new OracleCommand(sql, conn))
        {
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            using (var adapter = new OracleDataAdapter(cmd))
            {
                var dt = new DataTable();
                adapter.Fill(dt);
                return dt;
            }
        }
    }

    // 執行非查詢 (INSERT/UPDATE/DELETE/存儲過程)
    public static int ExecuteNonQuery(string sql, params OracleParameter[] parameters)
    {
        using (var conn = new OracleConnection(ConnStr))
        using (var cmd = new OracleCommand(sql, conn))
        {
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            conn.Open();
            return cmd.ExecuteNonQuery();
        }
    }

    // 執行純量查詢
    public static object ExecuteScalar(string sql, params OracleParameter[] parameters)
    {
        using (var conn = new OracleConnection(ConnStr))
        using (var cmd = new OracleCommand(sql, conn))
        {
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            conn.Open();
            return cmd.ExecuteScalar();
        }
    }

    // 呼叫存儲過程回傳游標 (OracleRefCursor)
    public static DataTable ExecuteProcCursor(string procName, params OracleParameter[] parameters)
    {
        using (var conn = new OracleConnection(ConnStr))
        using (var cmd = new OracleCommand(procName, conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            using (var adapter = new OracleDataAdapter(cmd))
            {
                var dt = new DataTable();
                adapter.Fill(dt);
                return dt;
            }
        }
    }
}

4. Windows Forms 整合範例

登入表單

public partial class LoginForm : Form
{
    private void btnLogin_Click(object sender, EventArgs e)
    {
        // 動態建構連線字串 (實務建議從加密設定檔讀取)
        var builder = new OracleConnectionStringBuilder
        {
            DataSource = txtDataSource.Text.Trim(),  // EZCONNECT 字串
            UserID = txtUser.Text.Trim(),
            Password = txtPwd.Text,
            Pooling = true
        };

        using (var conn = new OracleConnection(builder.ConnectionString))
        {
            try
            {
                conn.Open();
                MessageBox.Show("連線成功!");
                this.Hide();
                new MainForm(builder.ConnectionString).Show();
            }
            catch (OracleException ex)
            {
                MessageBox.Show($"連線失敗: {ex.Message}\n錯誤碼: {ex.Number}");
            }
        }
    }
}

主表單 - DataGridView 綁定查詢結果

public partial class MainForm : Form
{
    private readonly string _connStr;

    public MainForm(string connStr) { InitializeComponent(); _connStr = connStr; }

    private void MainForm_Load(object sender, EventArgs e)
    {
        LoadUserData();
    }

    private void LoadUserData()
    {
        const string sql = "SELECT user_id, user_name, email, created_date FROM app_users WHERE status = :status ORDER BY created_date DESC";
        var param = new OracleParameter("status", OracleDbType.Varchar2, "A", ParameterDirection.Input);

        try
        {
            using (var conn = new OracleConnection(_connStr))
            using (var cmd = new OracleCommand(sql, conn))
            using (var adapter = new OracleDataAdapter(cmd))
            {
                cmd.Parameters.Add(param);
                var dt = new DataTable();
                adapter.Fill(dt);
                dataGridView1.DataSource = dt;
                dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show($"查詢失敗: {ex.Message}");
        }
    }
}

5. 常見問題排查清單

  1. ORA-12154: TNS:could not resolve the connect identifier specified
    → 使用 EZCONNECT 完整描述繞過 tnsnames.ora,或確認 tnsnames.ora 路徑在 TNS_ADMIN 環境變數中。
  2. ORA-12514: TNS:listener does not currently know of service requested
    → 檢查 Service Name/SID 拼寫,確認 Listener 已註冊該服務 (lsnrctl status)。
  3. ORA-28040: No matching authentication protocol
    → 12c+ 預設停用舊式密碼驗證,需在 sqlnet.ora 設定 SQLNET.ALLOWED_LOGON_VERSION_SERVER=11 或升級客戶端驅動。
  4. 中文亂碼
    → 連線字串加 Unicode=True,資料庫字符集為 AL32UTF8,NLS_LANG 環境變數設為 TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950 或 AMERICAN_AMERICA.AL32UTF8。
  5. 連線洩漏導致 ORA-00020: maximum number of processes exceeded
    → 嚴格使用 using 區塊確保連線釋回池,調整 Max Pool Size 與資料庫 PROCESSES 參數。

6. 進階主題

  • 非同步操作:.NET 4.5+ 使用 OpenAsync()、ExecuteReaderAsync() 避免阻塞 UI 執行緒。
  • 批次作業:OracleCommand.ArrayBindCount 搭配參數陣列執行批次 INSERT/UPDATE,效能優於迴圈。
  • 依賴注入:ASP.NET Core 中註冊 OracleConnection 為 Scoped 服務,配合 IOptions<OracleSettings> 管理設定。

總結

採用 Oracle.ManagedDataAccess、EZCONNECT 連線字串、參數化查詢與連線池配置,能構建穩定、高效、可維護的 .NET-Oracle 資料存取層。嚴格遵循 using 模式管理連線生命週期,善用非同步 API 提升回應性,並建立完善的錯誤碼對應與監控機制,是企業級應用的關鍵成功因素。

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