一、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;
| 列舉成員 | 數值 | 說明 |
|---|---|---|
| Input | 1 | 預設值,輸入參數(傳入值給SQL) |
| Output | 2 | 輸出參數,執行預存程序後取得回傳結果 |
| InputOutput | 3 | 可輸入資料,執行完畢後也可輸出結果 |
完整範例
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)
重要開發規範
- 禁止直接拼接SQL字串,務必使用
SqlParameter做參數化; - 所有
SqlConnection、SqlCommand優先透過using自動釋放資源; - 呼叫 ExecuteScalar 一定要同時判斷
null + DBNull.Value; - 區分
CommandTimeout(SQL執行逾時)與連線字串內的Connect Timeout(建立連線逾時)。
執行最佳化與參數傳遞
Previous: CommandTimeout
Next: ExecuteNonQuery