線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1746
推到 Plurk!
推到 Facebook!

這樣做批次更新對嗎?(觀念問題)

尚未結案
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-16 21:58:58 IP:218.165.xxx.xxx 未訂閱
若底下為借書的procedure,那每借一本書就執行此procedure一次,假設執行了n次,那當我下batchupdate時,是不是就會把這n筆借書記錄一一更新???    
procedure tform4.borrow_book(borrow_nu: string); 
begin
   with datamodule3 do
   begin
      adoquery1.active:=true;
      adoquery1.Close;
      adoquery1.SQL.Add('insert into 借閱記錄(姓名,借書,日期,還書情形)values(:bname,:bbook,:bdate,:bstate)');
      adoquery1.Parameters.ParamByName(':bname').Value:=adoquery3.fieldbyname('姓名').AsString;
      adoquery1.Parameters.ParamByName(':bbook').Value:=adoquery2.fieldbyname('書名').AsString;
      adoquery1.Parameters.ParamByName(':bdate').Value:=AnsiReplaceText(FormatDateTime('eee,mm,dd', monthcalendar1.Date), ',', '/');
      adoquery1.Parameters.ParamByName(':bstate').Value:=false;
   end;
end;
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-16 22:19:57 IP:218.16.xxx.xxx 未訂閱
我沒用過 ADO 也跑來答,哈哈哈。    應該不是罷 @@"    UpdateBatch 是給你的 ADOTable 或 RequestLive 的 ADOQuery Edit / Insert / delete 先不存回數據庫待你    ADODataSet.UpdateBatch 時一次過將所有變更存回的。    若使用 Update Statement 是直接存回的與 Batch Update Mode 無關    不過即使不論 Batch Update Mode, 你的程式有大問題和可以改善效率的地方耶....    下回繼續....< > ----------------------------------- 第二回 : 我打字慢怕每次都遲貼所以採取兩段式答題,第一段先針對問題作答,第二段補充參考資料< > 大問題 : 你不Clear SQL 一直 Add 資料庫太笨不會看的啦 :P 改善效率 : 既然 SQL 一樣最好先設定好,然後程式開始時修便 ADOQuery.Prepare; 之後只是改 Param 及 ExecSQL, 這樣效率會比較好啊 發表人 - Justmade 於 2003/05/16 22:32:37
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-16 23:54:07 IP:218.165.xxx.xxx 未訂閱
我每借一次便新增一次,也是還沒回存,不是嗎?    clear~啊!沒打到,待會補上...< > 寫了一天,寫的頭都暈了...< > 既然 SQL 一樣最好先設定好,然後程式開始時修便 ADOQuery.Prepare; 之後只是改 Param 及 ExecSQL, 這樣效率會比較好啊.... 紅字的地方不太明瞭ㄟ
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-17 00:08:46 IP:218.16.xxx.xxx 未訂閱
batchupdate 只在修改 ADODataSet 內的數據有效,就像是 ADOQuery1.Edit; ADOQuery1.FieldByName('姓名').Value := Edit1.Text; ADOQuery1.FieldByName(....... ADOQuery1.Post; 這類的修改新增移除才有效,因為資料都記在 Memory 裡,到你 UpdateBatch 時才一次過自動產生 SQL 更新進數據庫 但你若自己執行 SQL Statement , SQL Statment 不是在你的程式執行的而是直接傳到數據庫執行的,試問你的程式又甚能 Batch Update 它呢? 若你想將這個 Procedure 完成執行 n 次沒問題才更新否則便全部不更新,方法又二 : 1. 使用 Transaction,中間出問題便 rollback 全成功才 commit; 2. 用這個 procedure 來做一個一次 update 多個記錄的 SQL 最後才 給 ADOQuery1 來執行 a) 設個變數 = 'insert into 借閱記錄(姓名,借書,日期,還書情形)values ' b) 每次執行這個變數加上 '(所有值),' c) 最後減去最後的 ',' d) 傳給 ADOQuery1.SQL 並 ExecSQL 修正 既然 SQL 一樣最好先設定好,然後程式開始時便先 ADOQuery1.Prepare; 之後只是改 Param 及 ExecSQL, 這樣效率會比較好啊
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-05-17 00:32:38 IP:61.64.xxx.xxx 未訂閱
引言: batchupdate 只在修改 ADODataSet 內的數據有效,就像是 ADOQuery1.Edit; ADOQuery1.FieldByName('姓名').Value := Edit1.Text; ADOQuery1.FieldByName(....... ADOQuery1.Post; 這類的修改新增移除才有效,因為資料都記在 Memory 裡,到你 UpdateBatch 時才一次過自動產生 SQL 更新進數據庫 但你若自己執行 SQL Statement , SQL Statment 不是在你的程式執行的而是直接傳到數據庫執行的,試問你的程式又甚能 Batch Update 它呢? 若你想將這個 Procedure 完成執行 n 次沒問題才更新否則便全部不更新,方法又二 : 1. 使用 Transaction,中間出問題便 rollback 全成功才 commit; 2. 用這個 procedure 來做一個一次 update 多個記錄的 SQL 最後才 給 ADOQuery1 來執行 a) 設個變數 = 'insert into 借閱記錄(姓名,借書,日期,還書情形)values ' b) 每次執行這個變數加上 '(所有值),' c) 最後減去最後的 ',' d) 傳給 ADOQuery1.SQL 並 ExecSQL 修正 既然 SQL 一樣最好先設定好,然後程式開始時便先 ADOQuery1.Prepare; 之後只是改 Param 及 ExecSQL, 這樣效率會比較好啊
ADO 可以一次執行多個 SQL 敘述 再者,若只是要執行insert、update、delete等 SQL 敘述,建議使用 TADOCommand,比較節省資源 多個SQL一起執行範例: ADOCommand1.CommandText := 'insert into TableA (F1, F2) values (1, ''AAA'');' 'insert into TableA (F1, F2) values (2, ''BBB'');' 'insert into TableA (F1, F2) values (3, ''CCC'');' 'insert into TableA (F1, F2) values (4, ''DDD'');' 'insert into TableA (F1, F2) values (5, ''EEE'');' 'insert into TableA (F1, F2) values (6, ''FFF'')'; ADOCommand1.Execute; SQL 指令的總長度在 8k 以內的話,就可以一起執行,否則需要分批 而且這樣只會有一次的網路 round-trip (若分批的話,是分批的次數) 加油喔,喵~
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-05-17 02:09:28 IP:61.216.xxx.xxx 未訂閱
hi..nachi..請問一下你這段是要放在你原來程式的那一各Form裡面ㄋ??
引言: 若底下為借書的procedure,那每借一本書就執行此procedure一次,假設執行了n次,那當我下batchupdate時,是不是就會把這n筆借書記錄一一更新???
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-17 09:34:27 IP:218.165.xxx.xxx 未訂閱
chih~這段程式要放在"借閱管理"裡的~    我先去思考justmade、sryang的建議....
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-17 10:10:36 IP:218.16.xxx.xxx 未訂閱
引言: ADO 可以一次執行多個 SQL 敘述 再者,若只是要執行insert、update、delete等 SQL 敘述,建議使用 TADOCommand,比較節省資源 多個SQL一起執行範例: ADOCommand1.CommandText := 'insert into TableA (F1, F2) values (1, ''AAA'');' 'insert into TableA (F1, F2) values (2, ''BBB'');' 'insert into TableA (F1, F2) values (3, ''CCC'');' 'insert into TableA (F1, F2) values (4, ''DDD'');' 'insert into TableA (F1, F2) values (5, ''EEE'');' 'insert into TableA (F1, F2) values (6, ''FFF'')'; ADOCommand1.Execute; SQL 指令的總長度在 8k 以內的話,就可以一起執行,否則需要分批 而且這樣只會有一次的網路 round-trip (若分批的話,是分批的次數)
沒用過 ADO 果然差些,我就沒想起 ADOCommand 不過我想總是 一句 insert statement 插入所有記錄比較好罷 ? 因為 1. SQL 比較短,傳輸快 2. 數據庫只執行一句statement , 速度快 3. 若中間某筆資料有問題, 一句 SQL statement 能一貫處理不會執行了部份後才發現問題 ? 只是我的想法若不對歡迎指正 若有一堆不同的 SQL command, 使用 ADOCommand 真的會很好用。
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-17 11:08:18 IP:218.165.xxx.xxx 未訂閱
終於理出個頭緒來了,>(>;'第一筆 '>(>;'第二筆 > 紅字部份想不出該如何解決< > 用
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-05-17 11:10:19 IP:61.216.xxx.xxx 未訂閱
你應該是要放在儲存Button裡面的吧,所以你可以考慮sryang及Justmade所述,我看你的畫面並沒有很複雜,應該沒有需要批次的功能吧,其實如果需要的話可以把你寫的程式中adoquery1用另外一各Query來下你原來寫的語法回寫資料就可以了,試試看吧<>< face="Verdana, Arial, Helvetica">引言: chih~這段程式要放在"借閱管理"裡的~ 我先去思考justmade、sryang的建議.... < face="Verdana, Arial, Helvetica">
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-05-17 11:14:40 IP:218.165.xxx.xxx 未訂閱
引言: 你應該是要放在儲存Button裡面的吧,所以你可以考慮sryang及Justmade所述,我看你的畫面並沒有很複雜,應該沒有需要批次的功能吧,其實如果需要的話可以把你寫的程式中adoquery1用另外一各Query來下你原來寫的語法回寫資料就可以了,試試看吧 < face="Verdana, Arial, Helvetica"> chih~用另一個query下原來寫的語法回寫資料?我不懂ㄟ,該如何下呢?
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-05-17 11:31:56 IP:218.16.xxx.xxx 未訂閱
我是說在你這個 Case 用我上面第二個提議應會較好,不是說用 ADOCommand    ADOCommand1.CommandText :=  'insert into 借閱記錄 (姓名, 書名) values (1, ''AAA'');' +'insert into 借閱記錄 (姓名, 書名) values (2, ''BBB'');' ADOCommand1.Execute;    ADOQuery1.SQL.Text :=  'insert into 借閱記錄 (姓名, 書名) values (1, ''AAA''), (2, ''BBB'');' ADOCommand1.ExecSQL;    那個較短?    而且 ADOCommand 雖只用一個 Connection 但到了數據庫還是要一句句執行的若第二句出問題第一句已更新到數據庫了。 但用我提議的只有一個 SQL Statement 只執行一次較快且若有問題應整體不會被更新。    所以要看你甚樣用了。    
var
  Form4 : TForm4;
  zSQL : String;    procedure tForm4.SaveButtonClick(Sender : TObject);
var i : integer;
begin
  zSQL := 'insert into 借閱記錄(姓名,借書,日期,還書情形) values ';
  for i := 0 to .... do
  begin
    ....
    borrow_book(..);
  end;
  zSQL := copy(zSQL, 1, Length(zSQL) -1) // delete the trailing ,
  with datamodule3 do
  begin
    AdoQuery1.SQL.Text := zSQL;
    AdoQuery1.ExecSQL;
  end;
end;      procedure tform4.borrow_book(borrow_nu: string); 
begin
  zSQL := zSQL   '('   QuotedStr(adoquery3.fieldbyname('姓名').AsString)   ','   
          QuotedStr(adoquery2.fieldbyname('書名').AsString)   ','  
          QuotedStr(AnsiReplaceText(FormatDateTime('eee,mm,dd', monthcalendar1.Date), ',', '/'))   
          ',false),'
end;
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-05-17 13:22:59 IP:61.217.xxx.xxx 未訂閱
另外放一各Query放在datamodule3上面,如果Databse跟執行檔在同一各目錄下,這各Query完全不用設定屬性..
procedure tform4.borrow_book;//我改為這樣 
begin
   with datamodule3 do
   begin
      Query1.Close;
      Query1.SQL.Add('insert into 借閱記錄(姓名,借書,日期,還書情形)values(:bname,:bbook,:bdate,:bstate)');
      Query1.Parameters.ParamByName(':bname').Value:=adoquery3.fieldbyname('姓名').AsString;
      Query1.Parameters.ParamByName(':bbook').Value:=adoquery2.fieldbyname('書名').AsString;
      Query1.Parameters.ParamByName(':bdate').Value:=AnsiReplaceText(FormatDateTime('eee,mm,dd', monthcalendar1.Date), ',', '/');
      Query1.Parameters.ParamByName(':bstate').Value:=false;
      Query1.ExecSQL; 
      Query1.Close;
   end; 
end;
TRY TRY SEE PS:你這段語法我並沒有去check可不可以Run..你自己試吧.. <>< face="Verdana, Arial, Helvetica">引言: chih~用另一個query下原來寫的語法回寫資料?我不懂ㄟ,該如何下呢?
發表人 - chih 於 2003/05/17 13:24:16
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-05-17 13:32:27 IP:218.165.xxx.xxx 未訂閱
因為justmade的想法和我的有出入,現在正在做修正、理解中~ 你的建議,我會再找時間test
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-05-17 14:23:56 IP:218.165.xxx.xxx 未訂閱
justmade兄...下面是我對你程式的解讀    這行執行一次: zSQL := 'insert into 借閱記錄(姓名,借書,日期,還書情形) values ';    底下放在儲存鈕: zSQL := copy(zSQL, 1, Length(zSQL) -1) // delete the trailing ,   with datamodule3 do   begin     AdoQuery1.SQL.Text := zSQL;     AdoQuery1.ExecSQL;   end;    每借一本書執行一次: procedure tform4.borrow_book(borrow_nu: string);  begin   zSQL := zSQL + '(' + QuotedStr(adoquery3.fieldbyname('姓名').AsString) + ',' +            QuotedStr(adoquery2.fieldbyname('書名').AsString) + ',' +           QuotedStr(AnsiReplaceText(FormatDateTime('eee,mm,dd', monthcalendar1.Date), ',', '/')) +            ',false),' end;    我在想我是否解讀錯誤,因為儲存後只能記錄到最後借閱的那一本書,之前的書都沒記錄到 且不知是否為 >
nachi
初階會員


發表:40
回覆:116
積分:31
註冊:2003-02-26

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-05-18 11:38:42 IP:218.165.xxx.xxx 未訂閱
justmade~做不出想要的樣子,但把你的程式改成每借一本就儲存一次 也謝謝各位大大近日來提供的建議^^ 發表人 -
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-05-18 12:41:37 IP:218.16.xxx.xxx 未訂閱
沒看見你昨天的 post 所以沒覆,對不起 那個方法是每一次 Save 做 一句 SQL 一次過儲存所有記錄 這句SQL 分兩大部份,第一部份是說明 insert 的 Table 和 欄位,之後便是每筆的資料 第一部份只需一次第二部份每個記錄要一次 雖然你說 zSQL := 'insert into 借閱記錄(姓名,借書,日期,還書情形) values '; 只執行一次,但看你的結果好像是每次借一本書這句都被重覆執行了,這樣才會只記下最後一筆 你最好可以在最後的 save button 檢視一下 zSQL 是否包含所有資料,或在 zSQL := 'insert into 借閱記錄(姓名,借書,日期,還書情形) values '; 設 Break point 看是否被重覆執行了
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-05-18 14:58:02 IP:61.64.xxx.xxx 未訂閱
引言: 沒用過 ADO 果然差些,我就沒想起 ADOCommand 不過我想總是 一句 insert statement 插入所有記錄比較好罷 ? 因為 1. SQL 比較短,傳輸快 2. 數據庫只執行一句statement , 速度快 3. 若中間某筆資料有問題, 一句 SQL statement 能一貫處理不會執行了部份後才發現問題 ? 只是我的想法若不對歡迎指正 若有一堆不同的 SQL command, 使用 ADOCommand 真的會很好用。
1. 一個封包如果以 TCP/IP 來說,可以傳送 1K 的資料,一個 SQL 敘述要寫到 1K 實在是不容易。所以,一次一個 SQL 來傳送並不會比一批一起傳送來得快。 2. 一個或一批 SQL 敘述送到 DBMS 之後,會經過語法檢查、compile 等動作,如果每次送一個 SQL 敘述,這樣語法檢查和 compile 的動作會多出許多 3. 在這樣的場合,通常是配合著 Transaction 一起執行,所以有錯誤還是能即時發現。 加油喔,喵~
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-05-18 16:30:43 IP:218.16.xxx.xxx 未訂閱
我想你有點誤會我的對比了,我的對比是 1. 你說的用 ADOCommands 整合多個 insert Statement 作一次性的傳輸 Vs 2. 用一句 insert statement 整合多個記錄的更新作一次性的傳輸更新 而不是對用多句 Statement 作多次性的更新。 我同意你的說法,用 ADOCommands 絕對比分多次每次一個 insert Statement 好。但若可以做到一句 insert statement 就做到了一個 command 數十個 insert statment 的同樣功效,不是更好嗎?
系統時間:2024-06-29 16:52:38
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!