2012年2月8日 星期三

C# : 使用 Prepare 處理 MySQL 資料的執行請求

在【C# : 對 MySQL 查詢資料】及【C# : 對 MySQL 新增、修改、刪除資料】二篇文章中說明的都是單次請求單次處理的做法,但如果同一句 MySQL 語句需要多次重複請求處理時,或是看起來很類似的多句 MySQL 語句,只有某些欄位值不同而已,要不斷的解析 MySQL 語句再處理,並不是好的做法,這種狀況我們就可以考慮使用 Prepare,不用每次都解析 MySQL 語句再做處理,只需要在 Prepare 時解析,之後只要不斷改變欄位值重新處理就好了。


新增、修改、刪除...

//開啟連線
MySqlConnection conn = new MySqlConnection("server=127.0.0.1;user=root;database=test;port=3306;password=1111;");
conn.Open();

//建立命令,並指定命令內容文字(MySQL 語句)
//這裡也可以直接寫成 preCmd = new MySqlCommand("INSERT INTO test_table ( `id` , `name`) VALUES ( ?id , ?name)",conn);
preCmd = conn.CreateCommand();
preCmd.CommandText = "INSERT INTO test_table ( `id` , `name`) VALUES ( ?id , ?name)";

// 對應 MySQL 語句定義參數並執行 prepare
MySqlParameter pId = preCmd.Parameters.Add("?id" , MySqlDbType.Int32);
MySqlParameter pName = preCmd.Parameters.Add("?name" , MySqlDbType.VarChar);
preCmd.prepare();

// 指定參數值並執行
pId.Value = 1;
pName.Value = "testName1";
preCmd.ExecuteNonQuery();

// 再次指定參數值並執行
pId.Value = 2;
pName.Value = "testName2";
preCmd.ExecuteNonQuery();

//也可以不宣告 MySqlParameter 變數而直接指定參數值給 preCmd.Parameters 並執行
preCmd.Parameters[0].Value = 5;
preCmd.Parameters[1].Value = "testName5";
preCmd.ExecuteNonQuery();

preCmd.Parameters[0].Value = DBNull.Value;
preCmd.Parameters[1].Value = "testName6";
preCmd.ExecuteNonQuery();



查詢單筆&單一欄位資料,如果查無資料則結果為 null

//開啟連線
MySqlConnection conn = new MySqlConnection("server=127.0.0.1;user=root;database=test;port=3306;password=1111;");
conn.Open();

//建立命令,並指定命令內容文字(MySQL 語句)
preCmd = conn.CreateCommand();
preCmd.CommandText = "SELECT name FROM test_table WHERE id=?id";

// 對應 MySQL 語句定義參數並執行 prepare
MySqlParameter pId = preCmd.Parameters.Add("?id" , MySqlDbType.Int32);
preCmd.prepare();

// 指定參數值並執行
pId.Value = 1;
string _name = preCmd.ExecuteScalar();

/ 再次指定參數值並執行
pId.Value = 2;
_name = preCmd.ExecuteScalar();

//直接指定參數值給 preCmd.Parameters 並執行
preCmd.Parameters[0].Value = 3;
_name = preCmd.ExecuteScalar();


查詢多筆資料

//開啟連線
MySqlConnection conn = new MySqlConnection("server=127.0.0.1;user=root;database=test;port=3306;password=1111;");
conn.Open();

//建立命令,並指定命令內容文字(MySQL 語句)
preCmd = new MySqlCommand("SELECT * FROM test_table WHERE id=?id",conn);

// 對應 MySQL 語句定義參數並執行 prepare
MySqlParameter pId = preCmd.Parameters.Add("?id" , MySqlDbType.Int32);
preCmd.prepare();

// 指定參數值並列出查詢結果
pId.Value = 1;
MySqlDataReader data = preCmd.ExecuteReader();
while(data.Read()){
Console.WriteLine("id={0} , name={1}", data["id"], data["name"]);
}
data.Close();

// 再次指定參數值並列出查詢結果
pId.Value = 2;
data = preCmd.ExecuteReader();
while(data.Read()){
Console.WriteLine("id={0} , name={1}", data["id"], data["name"]);
}
data.Close();

//直接指定參數值給 preCmd.Parameters 並列出查詢結果
preCmd.Parameters[0].Value = 5;
data = preCmd.ExecuteReader();
while(data.Read()){
Console.WriteLine("id={0} , name={1}", data["id"], data["name"]);
}
data.Close();

善用 Prepare 不但可以提升效能且讓程式結構更為穩固之外,如同【C# : 使用 Parameters 處理 MySQL 語句】一文提到的,Prepare 也使用 Parameters 處理欄位值,所以 Prepare 同時也增加資料的安全性;另外,因為 Prepare 傳送的資料比直接執行的語句更少,所以可使網路傳輸速度更快,還有,就是 Prepare 使用二進制處理 client 與 server 雙方的資料轉換,所以效能更佳。