一次搞定新增或異動資料

寫程式一段時間,發現每次遇到如果資料不存在就新增,如果存在就異動的這個情況,總是要用DBCommand去Execute個兩次,總是沒有辨法一次搞定,現在想到的方法就是從Script著手.

寫程式一段時間,發現每次遇到如果資料不存在就新增,如果存在就異動的這個情況,總是要用DBCommand去Execute個兩次,總是沒有辨法一次搞定,現在想到的方法就是從Script著手.

比如說,現在有個Table如下 :

Table Name : ExchangeRate

Column Name : CurrencyName , Rate

CurrencyNameRate
USD35
HKD4

現在有一筆資料進來,要去異動資料庫,如果沒有就新增,有就異動Rate,原有的做法如下 :

DBCmd.CommandText = "update ExchangeRate set Rate=:Rate where CurrencyName=:CurrencyName";

DBCmd.Parameters.Add(.........

if (DBCmd.ExecuteNonQuery()==0)

{

    DBCmd.CommandText="insert into ExchangeRate (CurrencyName,Rate) values (:CurrencyName,:Rate)"

    DBCmd.ExecuteNonQuery();

}

 

現在想到ExecuteNonQuery一次就搞定,就是從CommandText的Script著手.

 

DBCmd.CommandText = "
DECLARE

   cnt number;

begin

   select count(*) into cnt from ExchangeRate where CurrencyName=:CurrencyName;

   if cnt>0

       then update ExchangeRate  set Rate=:Rate where CurrencyName=:CurrencyName;

       else insert into ExchangeRate (CurrencyName, Rate) values (:CurrencyName,:Rate);

   end if;

end;
";

DBCmd.ExecuteNonQuery();

這樣就可以在呼叫ExecuteNonQuery()一次搞定,

 

這個Script是用Oracle的寫法,MS SQL也是一樣的原理.

至於那種效能好,看情況~~

 

===2010/7/9 補充 ===

這種方式在一般情況看來,似乎也沒比較好,這想法也沒錯,這要看資料情況及整體架構來決定,就假設一個情境來說.

現在有一個WinForm的程式,Client可能透過多種網路連結方式到Server,而有些據點只有ADSL 2M/256K,而這樣的頻寬下,有5台電腦共用,以ADSL的折耗以7成來算(很客氣了,有的只有5成),上傳頻寬約180K左右,有些人員在外面用NB是透過3.5G行動上網,所以這個情況看來,Client到Server這中間的網路頻寬是個瓶頸,尤其上傳頻寬.

Client現有一些有就異動,沒有就新增的資料要上傳到資料庫去,那要怎麼做,才能減輕網路的負擔?

如果是用第一種方式ExecuteNonQuery()兩次,那就無法使用DBCommand.Prepare()產生暫存的Store Procedure,因為沒有異動到資料,就要新增,CommandText就需要再異動,所以在每次ExecuteNonQuery()時,都會傳輸全部的CommandText及Parameters過去.

而第二種方式,雖然要Select之後再去判斷要Insert還是Update,但這個CommandText是固定的,就不需要再異動,這時就可以使用DBCommand.Prepare()產生暫存的SP,所以在每次ExecuteNonQuery()時,傳輸的資料量就較少,只要Parameters及系統會自動去Execute那個暫存SP.

當然這時如果能直接在資料庫新增一個Store Procedure去呼叫就好,就不需要使用DBCommand.Prepare()產生暫存的,但這個SP要怎麼寫? 難不成還是讓Client去ExecuteNonQuery()一或兩次嗎^^.

這個情境並不是什麼Worst Case,這是過去遇到的經驗,曾經有個據點把他們的網路頻寬吃光,什麼事都不用做了,客戶急的跳腳,我也想過,怎麼那個據點的網路不升速?確認後才知道,那個據點在郊區,那邊沒有鋪線,沒辨法申請更快的頻寬,除非自己出錢鋪線,那3.5G呢,該點也很不幸的,也沒有~~

所以我只能說看情況,選方法~