執行最佳化與參數傳遞

一、SqlConnection 連線狀態判斷

屬性:conn.State

列舉型別 ConnectionState

// 若連線尚未開啟,就開啟連線
if (conn.State != ConnectionState.Open)
{
    conn.Open();
}Code language: JavaScript (javascript)

注意:搭配 using 使用時,連線釋放後狀態會自動變成 Closed。
常見狀態:Open / Closed / Connecting 等。

二、ExecuteScalar 空值判斷重點

要對 ExecuteScalar 的回傳值做判斷,避免空值引發錯誤

object obj = sqlCom.ExecuteScalar();

// 必須同時判斷 null 與 DBNull.Value
if (obj == null || obj == System.DBNull.Value)
{
    MessageBox.Show("查詢結果為null");
}
else
{
    MessageBox.Show(obj.ToString());
}Code language: JavaScript (javascript)

區分:

  • null:沒有回傳任何一列資料
  • DBNull.Value:有查到資料列,但該欄位在資料庫內的值是 NULL

三、SqlCommand 參數機制(防SQL注入核心)

1. 核心物件

SqlCommand.Parameters 集合,存放多個 SqlParameter 參數。使用參數化查詢,可以完全避免SQL注入漏洞。

2. 建立參數範例
// 參數名稱、型別、長度
SqlParameter paramSql = new SqlParameter("@Title", SqlDbType.NVarChar, 250);

// 指定參數值
paramSql.Value = model.Title;

// 加入命令物件
sqlCom.Parameters.Add(paramSql);Code language: JavaScript (javascript)
3. 參數方向 ParameterDirection(列舉)
paramSql.Direction = ParameterDirection.Output;
列舉成員數值說明
Input1預設值,輸入參數(傳入值給SQL)
Output2輸出參數,執行預存程序後取得回傳結果
InputOutput3可輸入資料,執行完畢後也可輸出結果

完整範例

private void button1_Click(object sender, EventArgs e)
{
    string connectionString = "Data Source=.;Initial Catalog=db;User ID=sa;Password=xxx";
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        // 安全開啟連線
        if (conn.State != ConnectionState.Open)
        {
            conn.Open();
        }

        SqlCommand sqlCom = new SqlCommand();
        sqlCom.Connection = conn;
        sqlCom.CommandTimeout = 60;
        // 使用參數化SQL,千萬不要直接拼接字串!
        sqlCom.CommandText = "SELECT [Title] FROM [dbo].[Article] WHERE Title = @Title";

        // 建立參數
        SqlParameter paramTitle = new SqlParameter("@Title", SqlDbType.NChar, 10);
        paramTitle.Value = "測試標題";
        sqlCom.Parameters.Add(paramTitle);

        object obj = sqlCom.ExecuteScalar();
        if (obj == null || obj == DBNull.Value)
        {
            MessageBox.Show("查詢結果為null");
        }
        else
        {
            MessageBox.Show(obj.ToString());
        }
    }
}Code language: JavaScript (javascript)

重要開發規範

  1. 禁止直接拼接SQL字串,務必使用 SqlParameter 做參數化;
  2. 所有 SqlConnectionSqlCommand 優先透過 using 自動釋放資源;
  3. 呼叫 ExecuteScalar 一定要同時判斷 null + DBNull.Value
  4. 區分 CommandTimeout(SQL執行逾時)與連線字串內的 Connect Timeout(建立連線逾時)。

執行最佳化與參數傳遞

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *