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

C# 透過 ODBC 呼叫 Sybase 預存程序完整實作指南

     編輯:關於C語言

前言

企業級應用常需整合既有 Sybase 資料庫,C# 透過 System.Data.Odbc 呼叫預存程序是標準作法。本文詳細說明連線字串設定、參數綁定、執行與資源釋放完整流程,並補充異常處理與最佳實務。

必要條件

  • 已安裝 Sybase ODBC 驅動程式 (如 Sybase SYSTEM 11、Adaptive Server Enterprise)
  • 專案參考 System.Data (內建)
  • 目標資料庫具備預存程序執行權限

連線字串組態

// 標準 ODBC 連線字串格式
string connStr = "Driver={Sybase SYSTEM 11};" +
                 "Srvr=MyServerName;" +      // ODBC 系統 DSN 或 Server 名稱
                 "Uid=myUser;" +
                 "Pwd=myPassword;" +
                 "Database=myDatabase;";     // 可選,若 DSN 已指定資料庫可省略

注意:驅動程式名稱需與 ODBC 資料來源管理員 中「驅動程式」頁籤顯示的完全一致 (含大小寫、空白)。

完整呼叫範例

using System;
using System.Data;
using System.Data.Odbc;

public class SybaseRepository
{
    private readonly string _connectionString;

    public SybaseRepository(string connectionString)
    {
        _connectionString = connectionString;
    }

    public void ExecuteStoredProc(string procName, params (string Name, OdbcType Type, ParameterDirection Dir, object Value)[] parameters)
    {
        using (var conn = new OdbcConnection(_connectionString))
        using (var cmd = conn.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            // Sybase 預存程序呼叫語法: "owner.proc_name ?, ?, ?"
            cmd.CommandText = $"{procName} {string.Join(", ", parameters.Select(_ => "?"))}";

            foreach (var (name, type, dir, value) in parameters)
            {
                var param = cmd.Parameters.Add(name, type);
                param.Direction = dir;
                param.Value = value ?? DBNull.Value;
            }

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

                // 若有 OUTPUT 參數,執行後可從 param.Value 取得
                foreach (var (name, _, dir, _) in parameters.Where(p => p.Dir != ParameterDirection.Input))
                {
                    var outParam = cmd.Parameters[name];
                    // 由呼叫端自行處理 outParam.Value
                }
            }
            catch (OdbcException ex)
            {
                // 錯誤碼對照: ex.Errors 集合包含多個 OdbcError
                throw new InvalidOperationException($"Sybase 執行失敗: {ex.Message}", ex);
            }
        } // using 區塊自動 Dispose 連線與命令
    }
}

呼叫端使用範例

var repo = new SybaseRepository(connStr);

// 僅輸入參數
repo.ExecuteStoredProc("dbo.sp_InsertOrder",
    ("@OrderId", OdbcType.Int, ParameterDirection.Input, 1001),
    ("@CustName", OdbcType.VarChar, ParameterDirection.Input, "Acme Corp"),
    ("@Amount", OdbcType.Decimal, ParameterDirection.Input, 1234.56m));

// 包含輸出參數
var outParams = new (string, OdbcType, ParameterDirection, object)[]
{
    ("@OrderId", OdbcType.Int, ParameterDirection.Input, 1002),
    ("@NewSeq", OdbcType.Int, ParameterDirection.Output, null),
    ("@StatusMsg", OdbcType.VarChar, ParameterDirection.Output, null)
};
repo.ExecuteStoredProc("dbo.sp_ProcessOrder", outParams);

// 取得輸出值需在 ExecuteStoredProc 內部暴露或改回傳 Dictionary
// 此處簡化示意,實務建議回傳 Dictionary<string, object>

關鍵技術細節

項目說明
CommandText 語法Sybase ODBC 需使用 proc_name ?, ?, ? 佔位符號,而非 @param 直接列出
參數順序嚴格依預存程序定義順序新增 cmd.Parameters.Add,名稱僅供可讀性
資料型別對應OdbcType.VarChar→VARCHAR、OdbcType.Int→INTEGER、OdbcType.Decimal→NUMERIC/DECIMAL、OdbcType.DateTime→DATETIME
DBNull.ValueC# null 傳給資料庫必須轉為 DBNull.Value,否則會拋例外
連線池ODBC 連線字串相同會自動啟用連線池,using 區塊結束時實際歸還池而非關閉

常見錯誤與排查

  • ERROR [IM002] 資料來源名稱未找到:驅動程式名稱錯誤、未安裝 32/64 位元對應驅動、專案平台目標與驅動位元不符 (x86 vs x64)。
  • ERROR [42000] 預存程序不存在:確認擁有者名稱 (dbo/owner)、資料庫內容、大小寫敏感度。
  • 參數數目不符:佔位符 ? 數量與 Parameters.Count 必須一致。
  • 輸出參數為空:ParameterDirection 必須設為 Output 或 InputOutput,且預存程序需 SELECT @param = value 或 SET @param = value。

進階:非同步與交易支援

public async Task ExecuteInTransactionAsync(Action action)
{
    using (var conn = new OdbcConnection(_connectionString))
    {
        await conn.OpenAsync();
        using (var trans = conn.BeginTransaction())
        using (var cmd = conn.CreateCommand())
        {
            cmd.Transaction = trans;
            try
            {
                action(cmd);
                trans.Commit();
            }
            catch
            {
                trans.Rollback();
                throw;
            }
        }
    }
}

替代方案比較

方案優點缺點
ODBC (本文)標準化、跨平台、無額外套件效能較低、功能受限
ASE Client (AdoNet)原生效能最佳、支援完整 Sybase 功能需安裝專屬 Provider、僅 Windows
Dapper + ODBC微型 ORM、程式碼簡潔仍受限於 ODBC 效能
Entity Framework Core完整 ORM 體驗需第三方 Provider (如 Sap.Data.Sybase.EF)、配置複雜
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved