Store Procedure的效能比較好,這點就不再討論,但有時不是想用就能用,這時可以用DbCommand的Prepare功能,來產生一個暫時的SP,藉此來提升效能.
Store Procedure的效能比較好,這點就不再討論,但有時不是想用就能用,這時可以用DbCommand的Prepare功能,來產生一個暫時的SP,藉此來提升效能.
這個例子是使用MS SQL 2005資料庫,而同一段語法,只傳不同的值去異動資料,看看它有什麼不同.
先來看看平時一般的寫法,與Profiler所抓到的Script.
程式 :
SqlConnection conn = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=SSPI;");
SqlCommand cmd = conn.CreateCommand();
try
{
cmd.CommandText = "update customers set companyname=1 where customerid=@id";
cmd.Parameters.Add("@id", SqlDbType.NChar, 5);
conn.Open();
for (int i = 0; i < 3; i++)
{
cmd.Parameters["@id"].Value = i;
cmd.ExecuteNonQuery();//每次均傳完整的Script及Value
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
cmd.Dispose();
conn.Dispose();
}
可以看到,跑了三次迴圈去異動DB的資料,在Profiler裡所看到的是三個一樣的完整Script.
使用SqlCommand.Prepare()來產生暫存的Store Procedure
SqlConnection conn = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=SSPI;");
SqlCommand cmd = conn.CreateCommand();
try
{
cmd.CommandText = "update customers set companyname=1 where customerid=@id";
cmd.Parameters.Add("@id", SqlDbType.NChar,5);
conn.Open();
cmd.Prepare();//產生暫存Store Procedure,但必需連往DB動作時,才會真正產生,此時並不會
for (int i = 0; i < 3; i++)
{
cmd.Parameters["@id"].Value = i;
cmd.ExecuteNonQuery();//只有第一次會產生SP,之後的異動,都只會傳參數,使用暫存的SP,所以Script就不會再傳.
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
cmd.Dispose();
conn.Dispose();
}
可以發現到,第一次連往DB時,跟之前的寫法就有所不同了,多了exec sp_prepexec,這就是產生一個暫存的SP,而後續的異動,就只是傳參數進去就好,不需要再傳完整的Script.
但這裡有幾個地方要注意的
1. 長度截斷
看一下程式碼第6行,我有宣告這個變數的長度(也必需宣告),如果傳進去的值大於我們宣告的Size,那就會被截斷,而且"不會傳回這個截斷錯誤"!!
2. 支援環境
MS SQL 2000及以上的DB支援
.Net 1.0及以上支援
*在Oracle上有試過,是可以執行,但因為我的環境權限的關係,無法Profiler,不確定是否跟MS SQL一樣的效果
3. CommandType
如果為TableDirect,Prepare不會有任何作用.
如果為StoreProcedure,呼叫應該會成功,但Prepare也不會有作用.
4. 效能
量愈大,效能的提升才更明顯,如果只有很少數的幾筆或一筆,就用第一種寫法就好了.因為產生暫存的Store Procedure也是有Cost的.
5.此暫存Store Procedure只有Current Session才會用的到.
6.暫存的Store Procedure在Connection Close後,就會消失了.
因為我的環境是SQL 2005 Express,所以我沒用MS SQL Profiler,而是用AnjLab SQL Profiler去監視,這是Free的,需要的人可以抓來用~
下載 : AnjLab SQL Profiler
參考 :