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

ASP.NET 2.0 執行資料庫操作命令:Command 物件完整解析與 SqlCommand 實戰

     編輯:關於ASP.NET

ADO.NET Command 物件三大家族

提供者Command 類別命名空間適用資料庫
SQL ServerSqlCommandSystem.Data.SqlClientSQL Server 7.0+
OLE DBOleDbCommandSystem.Data.OleDbAccess, Oracle, Excel, 文本檔...
ODBCOdbcCommandSystem.Data.Odbc任何支援 ODBC 的資料庫

核心功能相同:執行 SQL 陳述式、預存程序、資料表直接存取;差異在連線字串、參數標記 (@param vs ?)、特有屬性方法。

SqlCommand 核心屬性

屬性型別說明
CommandTextstringSQL 陳述式、預存程序名、資料表名
CommandTimeoutint逾時秒數 (預設 30),0 為無限等待
CommandTypeCommandTypeText(預設)、StoredProcedure、TableDirect
ConnectionSqlConnection關聯的連線物件
ParametersSqlParameterCollection參數集合,防 SQL Injection、支援輸出參數
TransactionSqlTransaction交易物件,納入交易範圍
UpdatedRowSourceUpdateRowSourceDataAdapter 更新時如何取回伺服器產生值

SqlCommand 五大執行方法

建立 SqlCommand 三種方式

// 1. 無參數建構子,後續設定屬性
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Products";
cmd.Connection = conn;

// 2. 指定 CommandText
SqlCommand cmd = new SqlCommand("SELECT * FROM Products", conn);

// 3. 指定 CommandText 與 Connection
SqlCommand cmd = new SqlCommand("SELECT * FROM Products", conn);

// 4. 從 Connection 建立 (較少用)
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM Products";

參數化查詢:防 SQL Injection 的金鑰

string sql = "INSERT INTO Products (ProductName, UnitPrice, Discontinued) VALUES (@Name, @Price, @Disc)";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
    cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 40).Value = productName;
    cmd.Parameters.Add("@Price", SqlDbType.Money).Value = unitPrice;
    cmd.Parameters.Add("@Disc", SqlDbType.Bit).Value = discontinued;
    // 或使用 AddWithValue (型別推斷,效能稍差)
    // cmd.Parameters.AddWithValue("@Name", productName);
    conn.Open();
    int affected = cmd.ExecuteNonQuery();
}

優點:型別安全、自動處理引號/日期格式、計畫快取重用、防注入。

預存程序呼叫

using (SqlCommand cmd = new SqlCommand("usp_GetProductsByCategory", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@CategoryID", SqlDbType.Int).Value = categoryId;
    // 輸出參數
    SqlParameter retParam = cmd.Parameters.Add("@RowCount", SqlDbType.Int);
    retParam.Direction = ParameterDirection.ReturnValue;

    conn.Open();
    using (SqlDataReader dr = cmd.ExecuteReader())
    {
        while (dr.Read()) { /* 讀取資料 */ }
    }
    int rowCount = (int)retParam.Value;
}

非同步執行 (ASP.NET 2.0+ / .NET 4.5+ Task 化)


// APM 模式 (2.0)
cmd.BeginExecuteReader(ar => {
    SqlDataReader dr = cmd.EndExecuteReader(ar);
    // 處理資料
}, null);

// Task 模式 (4.5+ 推薦)
SqlDataReader dr = await cmd.ExecuteReaderAsync();

完整範例:新增產品並取回 Identity

public int InsertProduct(string name, decimal price, bool discontinued)
{
    const string sql = @"
        INSERT INTO Products (ProductName, UnitPrice, Discontinued)
        VALUES (@Name, @Price, @Disc);
        SELECT CAST(SCOPE_IDENTITY() AS INT);";

    using (SqlConnection conn = new SqlConnection(_connStr))
    using (SqlCommand cmd = new SqlCommand(sql, conn))
    {
        cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 40).Value = name;
        cmd.Parameters.Add("@Price", SqlDbType.Money).Value = price;
        cmd.Parameters.Add("@Disc", SqlDbType.Bit).Value = discontinued;
        conn.Open();
        return (int)cmd.ExecuteScalar(); // 取回 SCOPE_IDENTITY()
    }
}

效能與最佳實務

  • 參數化:永遠使用參數,絕不字串拼接 SQL。
  • CommandType.StoredProcedure:複雜邏輯封裝於 SP,減少網路往返、利用執行計畫快取。
  • using 區塊:確保連線、命令、讀取器正確釋放。
  • 避免 SELECT *:明確列出欄位,減少傳輸、利用覆蓋索引。
  • 設定 CommandTimeout:長跑報表查詢適當調長 (如 120 秒)。
  • 非同步:高併發 Web 應用採用 ExecuteReaderAsync 釋放執行緒。

常見錯誤與解決

方法回傳用途典型 SQL
ExecuteNonQuery()int (影響列數)INSERT、UPDATE、DELETE、DDL、無結果集預存程序UPDATE Products SET Price=10 WHERE ID=1
ExecuteReader()SqlDataReaderSELECT、TableDirect、有結果集預存程序 (前向唯讀)SELECT * FROM Products
ExecuteScalar()object (第一欄第一列)單一值查詢 (COUNT、MAX、IDENTITY、SCOPE_IDENTITY)SELECT COUNT(*) FROM Products
ExecuteXmlReader()XmlReaderFOR XML 查詢,僅 SqlCommand 支援SELECT * FROM Products FOR XML AUTO
Cancel()void取消正在執行的命令 (非同步/長時間查詢)—
錯誤原因修正
SqlException: 無效的物件名稱資料表/預存程序名稱拼寫錯誤、或未指定 Schema (dbo.)使用雙部分名稱 dbo.Table、檢查資料庫上下文
ExecuteReader 要求開啟的連線未呼叫 conn.Open()、或連線已關閉確保執行前連線狀態為 Open
參數數量不符SQL 參數標記與 Parameters 集合數量/名稱不符仔細核對 @Name 大小寫、數量
資料截斷參數 Size 過小、或資料型別不符設定足夠 Size (NVarChar 4000)、確認 SqlDbType

結語

SqlCommand 是 ADO.NET 執行資料庫操作的核心物件。掌握五大執行方法、參數化查詢、預存程序呼叫、非同步模式與最佳實務,即能寫出安全、高效、可維護的資料存取程式碼,奠定 BLL/DAL 堅實基礎。

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