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

C# 呼叫 SQL Server 2005 預存程序完整範例 (ADO.NET SqlCommand)

     編輯:關於SqlServer

前言

在 .NET 應用中透過 ADO.NET 呼叫 SQL Server 預存程序,核心類別為 SqlCommand (CommandType = StoredProcedure)。本文提供完整 ASP.NET WebForms 範例,涵蓋連線字串設定、參數綁定 (輸入/輸出/傳回值)、SqlDataAdapter 填充 DataSet 綁定 GridView、資源釋放模式與最佳實踐。

一、資料庫端預存程序

CREATE PROCEDURE dbo.TestProc
    @InputParam NVARCHAR(3000),
    @OutputParam INT OUTPUT,
    @ReturnStatus INT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    -- 範例邏輯:依輸入參數查詢,回傳結果集與輸出參數
    SELECT * FROM SomeTable WHERE Name LIKE @InputParam + '%';
    SET @OutputParam = @@ROWCOUNT;
    SET @ReturnStatus = 0;  -- 0 成功,非 0 為自訂錯誤碼
    RETURN @ReturnStatus;
END;

二、Web.config 連線字串

<connectionStrings>
    <add name="StrCon"
         connectionString="Data Source=.;Initial Catalog=MyDB;User ID=app_user;Password=StrongPwd;Encrypt=True;TrustServerCertificate=True"
         providerName="System.Data.SqlClient" />
</connectionStrings>

三、完整 Code-Behind 範例

using System;
using System.Data;
using System.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            BindData();
    }

    protected void Btn_ok_Click(object sender, EventArgs e)
    {
        BindData();
    }

    private void BindData()
    {
        string connStr = ConfigurationManager.ConnectionStrings["StrCon"].ConnectionString;

        using (SqlConnection conn = new SqlConnection(connStr))
        using (SqlCommand cmd = new SqlCommand("dbo.TestProc", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;

            // 1. 輸入參數
            cmd.Parameters.Add("@InputParam", SqlDbType.NVarChar, 3000).Value = txt_Message.Text.Trim();

            // 2. 輸出參數
            SqlParameter outParam = cmd.Parameters.Add("@OutputParam", SqlDbType.Int);
            outParam.Direction = ParameterDirection.Output;

            // 3. 傳回值參數 (必須為第一個參數或明確指定 Direction=ReturnValue)
            SqlParameter retParam = cmd.Parameters.Add("@ReturnStatus", SqlDbType.Int);
            retParam.Direction = ParameterDirection.ReturnValue;

            try
            {
                conn.Open();

                // 4. 執行並填充 DataSet (適用回傳結果集)
                using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    DataSet ds = new DataSet();
                    da.Fill(ds);
                    ShowList.DataSource = ds;
                    ShowList.DataBind();
                }

                // 5. 讀取輸出參數與傳回值 (在 DataAdapter.Fill 完成後讀取)
                int rowCount = (int)outParam.Value;
                int returnStatus = (int)retParam.Value;

                lbl_Info.Text = $"查詢筆數: {rowCount}, 執行狀態: {returnStatus}";
            }
            catch (SqlException ex)
            {
                lbl_Info.Text = "資料庫錯誤: " + ex.Message;
                // 記錄完整堆疊至 Log 系統
            }
        } // using 區塊自動釋放連線、命令、DataAdapter
    }
}

四、關鍵 API 對照表

需求SqlParameter 設定讀取時機
輸入參數.Value = val (預設 Direction=Input)Execute 前
輸出參數Direction = ParameterDirection.OutputExecute 後
輸入/輸出參數Direction = ParameterDirection.InputOutputExecute 後
傳回值 (RETURN)Direction = ParameterDirection.ReturnValueExecute 後

五、進階場景

1. 多結果集處理

using (SqlDataReader dr = cmd.ExecuteReader())
{
    do
    {
        if (dr.HasRows)
        {
            // 處理第 N 個結果集
            while (dr.Read()) { /* ... */ }
        }
    } while (dr.NextResult());
}

2. 非查詢異動 (INSERT/UPDATE/DELETE)

int affected = cmd.ExecuteNonQuery();  // 回傳影響列數
// 輸出參數、傳回值同樣在 ExecuteNonQuery 後讀取

3. 交易控制

using (SqlConnection conn = new SqlConnection(connStr))
{
    conn.Open();
    SqlTransaction txn = conn.BeginTransaction();
    try
    {
        cmd.Transaction = txn;
        // 多個命令...
        txn.Commit();
    }
    catch
    {
        txn.Rollback();
        throw;
    }
}

4. 非同步執行 (SQL Server 2005+ / .NET 4.5+)

await cmd.ExecuteNonQueryAsync();
await cmd.ExecuteReaderAsync();
await cmd.ExecuteScalarAsync();

六、最佳實踐清單

  1. 連線字串加密:web.config 使用 aspnet_regiis -pef connectionStrings 加密區段。
  2. 參數化查詢:永不 字串拼接 SQL,所有輸入皆用參數。
  3. using 區塊:確保 IDisposable 物件 (Connection, Command, DataAdapter, DataReader) 確定釋放。
  4. 連線池:連線字串相同即自動共用池,勿手動關閉連線池,conn.Close() 即歸還池中。
  5. 命令逾時:長時間運行預存程序設定 cmd.CommandTimeout = 300 (秒)。
  6. 異常處理:捕捉 SqlException,依 ex.Number (如 2627 PK 違規、1205 死結) 給予使用者友善訊息,詳細錯誤寫入 Log (Serilog/NLog/ELMAH)。

七、常見錯誤排除

錯誤原因解決
Procedure 'TestProc' expects parameter '@InputParam', which was not supplied參數名稱拼寫錯誤 / 未加入 Parameters 集合核對預存程序定義與 C# 參數名稱 (含 @)
Parameter '@OutputParam' has not been set to a value未設定 Direction=Output加入 param.Direction = ParameterDirection.Output
Connection property has not been initializedSqlCommand 未指定 Connectioncmd.Connection = conn 或建構子傳入
ExecuteNonQuery requires an open and available Connection連線未 Open / 已關閉確認 conn.Open() 在 Execute 前

結語

ADO.NET SqlCommand 呼叫預存程序是 .NET 資料存取的基石。掌握 CommandType.StoredProcedure、參數方向設定、SqlDataAdapter/SqlDataReader 選擇、using 資源管理、交易與非同步模式,並落實參數化、連線字串加密、異常分級處理,即能建構安全、高效、可維護的資料存取層。

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