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

Master/Detail 寫入資料

答題得分者是:jieshu
Andy Wu
一般會員


發表:17
回覆:25
積分:18
註冊:2004-02-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-02-25 17:12:57 IP:211.22.xxx.xxx 未訂閱
大家好~ 我是三層式架構的開發新手, 想請教各位二個問題。 如果我在Ap Server上拉了二個Query, 一個DataSource,建立好Master/Detail的關係,再搭配二個DataSetProvider,如此就完成Ap Server的設定。 另外,在Client端,我拉了二個ClientDataSet,分別指向上述的二個DataSetProvider,還拉了一個DataSource,建立起Client端的Master/Detail關係,如此也就完成Client端的設定。 問題一:上述的建置方式有無錯誤?或是怎麼樣可以改成簡化、又可以增進效能的建置方式? 問題二:Master & Detail的Primary Key值都是在寫入前,去查詢最大的ID才產生的,所以在還沒有ApplyUpdate之前,Client端在新增時,我都是先給初始值-1,每新增一筆就再減一,等到我要ApplyUpdate時,Ap Server端在BeforeApplyUpdate去做查詢最大ID的動作,把得到的值取代在Delta當中的ID,但是,問題當我下了Master的ApplyUpdate,剛剛新增M筆的資料全部寫回資料庫,其中ID欄位已經透過上述的查詢修改過才寫入,可是當我下Detail的ApplyUpdate,剛剛新增N筆的Detail資料,其中Master的ID欄位值還是我原先給的-1, -2, ...,這下子該怎麼辦?
jieshu
版主


發表:42
回覆:894
積分:745
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-02-25 18:03:58 IP:203.204.xxx.xxx 未訂閱
引言: 大家好~ 我是三層式架構的開發新手, 想請教各位二個問題。 如果我在Ap Server上拉了二個Query, 一個DataSource,建立好Master/Detail的關係,再搭配二個DataSetProvider,如此就完成Ap Server的設定。 另外,在Client端,我拉了二個ClientDataSet,分別指向上述的二個DataSetProvider,還拉了一個DataSource,建立起Client端的Master/Detail關係,如此也就完成Client端的設定。 問題一:上述的建置方式有無錯誤?或是怎麼樣可以改成簡化、又可以增進效能的建置方式? 問題二:Master & Detail的Primary Key值都是在寫入前,去查詢最大的ID才產生的,所以在還沒有ApplyUpdate之前,Client端在新增時,我都是先給初始值-1,每新增一筆就再減一,等到我要ApplyUpdate時,Ap Server端在BeforeApplyUpdate去做查詢最大ID的動作,把得到的值取代在Delta當中的ID,但是,問題當我下了Master的ApplyUpdate,剛剛新增M筆的資料全部寫回資料庫,其中ID欄位已經透過上述的查詢修改過才寫入,可是當我下Detail的ApplyUpdate,剛剛新增N筆的Detail資料,其中Master的ID欄位值還是我原先給的-1, -2, ...,這下子該怎麼辦?
1.如果你Master和Detal要分開Update就沒錯,但要注意交易(Transaction)問題,如果要一起Update,Client就不用設MasterSource,而是要設DataSetField(之前打錯了)(Master要加入所需欄位)。 2.應該宣告個全域陣列變數紀錄相對的值,在Detail處理時再填入。
人生有夢,逐夢而行。 人若為善,福雖未至,禍已遠離。 人若為惡,禍雖未至,福已遠離。 http://www.coss.com.tw/jieshu/
發表人 - jieshu 於 2004/02/25 18:06:09
------
人生有夢,逐夢而行
人若為善,福雖未至,禍已遠離
人若為惡,禍雖未至,福已遠離
http://www.taconet.com.tw/jieshu/
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-02-25 20:14:09 IP:218.17.xxx.xxx 未訂閱
如果你要在APP SERVER端设置MASTER/DETAIL,那么,就只要一个DataSetProvider。 在Client端,你的Master ClientDataSet从DataSetProvider取数据,生成固定Field,那堆Field里,有一个Field代表的是Server端的Detail表。 好了,再放一个ClientDtaSet上去,他的DataSetField拉下来,你能看到前面说的那个Field了。然后,这个ClientDataSet作为Detail表,可以取到数据了。 最后,当你在Client端要提交的时候,只需要提交Master ClientDataSet就好了。
Andy Wu
一般會員


發表:17
回覆:25
積分:18
註冊:2004-02-25

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-02-25 23:12:35 IP:61.229.xxx.xxx 未訂閱
引言: 如果你要在APP SERVER端设置MASTER/DETAIL,那么,就只要一个DataSetProvider。 在Client端,你的Master ClientDataSet从DataSetProvider取数据,生成固定Field,那堆Field里,有一个Field代表的是Server端的Detail表。 好了,再放一个ClientDtaSet上去,他的DataSetField拉下来,你能看到前面说的那个Field了。然后,这个ClientDataSet作为Detail表,可以取到数据了。 最后,当你在Client端要提交的时候,只需要提交Master ClientDataSet就好了。
謝謝樓上二位大哥的回應~~ 但是,現在我的資料結構,Master/Detail總共有六層,如果採用二位的作法,勢必Master的這一個DataSetProvider就得要負責這六個ClientDataSet的ApplyUpdate,在Ap Server設置五個全域變數,將每一個DataSet所得到的最大ID儲存下來,提供給下一層的DataSet使用,降子一來,這個DataSetProvider會不會太過忙碌?導致隱藏的問題發生?(例如Client端--A,ApplyUpdate之後得到某一資料表的Max ID = 1,Client端--B,ApplyUpdate之後得到此資料表的Max ID = 2,那麼下一層的DataSet去存取此全域變數,會不會錯亂掉?)
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-02-26 01:29:18 IP:61.226.xxx.xxx 未訂閱
DataSetProvider是否會處於忙碌的情況,要看ClientDataSet 的PackRecords有沒有設值,若有的話,將DataSetProvider改成無物件狀態會好一些 (Delphi 範例的Pooler);若無的話,DataSetProvider在收完資料後就不在使用了(除非你去修改資料),但資料量很大的話,速度會變得很慢
Andy Wu
一般會員


發表:17
回覆:25
積分:18
註冊:2004-02-25

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-02-26 01:53:25 IP:61.229.xxx.xxx 未訂閱
引言: DataSetProvider是否會處於忙碌的情況,要看ClientDataSet 的PackRecords有沒有設值,若有的話,將DataSetProvider改成無物件狀態會好一些 (Delphi 範例的Pooler);若無的話,DataSetProvider在收完資料後就不在使用了(除非你去修改資料),但資料量很大的話,速度會變得很慢
感謝您的答覆~~ 首先,PackRecords並沒有設值;此外,資料量大約最多是同時要寫入1500筆資料進到這六個資料表當中,所以才會擔心DataSetProvider是否會太過忙碌。 曾經發生的問題是,當同一時間,這組Master/Detail若少人使用,都正常無誤;若多人同時寫入資料,則有人的資料會寫不正確,所以才懷疑是不是DataSetProvider太過忙碌,導致降子的問題產生。
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-02-26 10:13:01 IP:61.224.xxx.xxx 未訂閱
引言: 謝謝樓上二位大哥的回應~~ 但是,現在我的資料結構,Master/Detail總共有六層,如果採用二位的作法,勢必Master的這一個DataSetProvider就得要負責這六個ClientDataSet的ApplyUpdate,在Ap Server設置五個全域變數,將每一個DataSet所得到的最大ID儲存下來,提供給下一層的DataSet使用,降子一來,這個DataSetProvider會不會太過忙碌?導致隱藏的問題發生?(例如Client端--A,ApplyUpdate之後得到某一資料表的Max ID = 1,Client端--B,ApplyUpdate之後得到此資料表的Max ID = 2,那麼下一層的DataSet去存取此全域變數,會不會錯亂掉?)
1.只能用一個DataSetProvider,這問題的原因並不是DataSetProvider會不會太過忙碌的問題,而是當你分成6個DataSetProvider,在Client異動資料時會分六次下Applyupdate,當其中一次(假設網路中斷)失敗,就會照成Master/Detail資料不一致(Master/Detail 異動必須包在一次交易之中) 2.多人同時對同一個Master/Detail 作異動時,會不會出問題,基本上是有可能的,假設你依照MIDAS的架構且寫成無狀態的狀態下 在下述狀況中可能照成非預期的結果 若兩人同時對Master/Detail作異動,若異動的方式為Master資料不變,只是對Detail資料作新增的動作,基本上兩人都會異動成功,系統不會舉發Changed By Another User的例外,基本上這個問題必須靠另外設計來解決 混心雜欲 棄修身~唉
------
唉~
Andy Wu
一般會員


發表:17
回覆:25
積分:18
註冊:2004-02-25

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-02-26 13:08:28 IP:61.229.xxx.xxx 未訂閱
引言: 1.只能用一個DataSetProvider,這問題的原因並不是DataSetProvider會不會太過忙碌的問題,而是當你分成6個DataSetProvider,在Client異動資料時會分六次下Applyupdate,當其中一次(假設網路中斷)失敗,就會照成Master/Detail資料不一致(Master/Detail 異動必須包在一次交易之中) 2.多人同時對同一個Master/Detail 作異動時,會不會出問題,基本上是有可能的,假設你依照MIDAS的架構且寫成無狀態的狀態下 在下述狀況中可能照成非預期的結果 若兩人同時對Master/Detail作異動,若異動的方式為Master資料不變,只是對Detail資料作新增的動作,基本上兩人都會異動成功,系統不會舉發Changed By Another User的例外,基本上這個問題必須靠另外設計來解決 混心雜欲 棄修身~唉
謝謝您的答覆!! 如果我改用一個DataSetProvider來處理這一組Master/Detail的異動,並且包在一個交易當中,因為要針對六個資料表寫入大量資料,並且我的作法是去查詢每個資料表目前最大的ID值帶入目前異動的Delta當中,有二個問題想請教各位大大。 問題一:這六個資料表是否會被鎖定?SQL Server2000的預設鎖定機制為何? 問題二:產生交易後,會紀錄所有的異動,當每一組Master/Detail異動的資料量都很大的時候,假設同時間Ap Server接收到N個Client端的ApplyUpdate,SQL Server都能夠把每個交易內的異動都紀錄下來嗎?有沒有上限? 此外,如果我採用的是ADO的元件,因為在SQL的處理機制上ADO有其最佳化的方式,因此書上建議將DataSetProvider的ResolveToDataSet設為True,由ADO的元件來處理異動的資料,不要用MIDAS的DataSetProvider來處理,不知道幾位大大有沒有用過ADO的元件,依照此種方式來處理?二者相比,孰優孰劣?
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-02-26 18:04:37 IP:61.224.xxx.xxx 未訂閱
引言: 謝謝您的答覆!! 如果我改用一個DataSetProvider來處理這一組Master/Detail的異動,並且包在一個交易當中,因為要針對六個資料表寫入大量資料,並且我的作法是去查詢每個資料表目前最大的ID值帶入目前異動的Delta當中,有二個問題想請教各位大大。 問題一:這六個資料表是否會被鎖定?SQL Server2000的預設鎖定機制為何? 問題二:產生交易後,會紀錄所有的異動,當每一組Master/Detail異動的資料量都很大的時候,假設同時間Ap Server接收到N個Client端的ApplyUpdate,SQL Server都能夠把每個交易內的異動都紀錄下來嗎?有沒有上限? 此外,如果我採用的是ADO的元件,因為在SQL的處理機制上ADO有其最佳化的方式,因此書上建議將DataSetProvider的ResolveToDataSet設為True,由ADO的元件來處理異動的資料,不要用MIDAS的DataSetProvider來處理,不知道幾位大大有沒有用過ADO的元件,依照此種方式來處理?二者相比,孰優孰劣?
1.你所謂鎖定是啥意思,基本上SQL Server本身會自己管理交易的相關問題,並不需要像傳統桌上型資料庫一樣必須自行下Lock指令 你唯一要注意的是這六個表格是否在同一個交易之內(在ap端這六個表都必須連相同的ADOConnection),另外要注意的是程式碼寫在哪邊,若是寫在DataSetProvider的相關事件中,一般而言是不需要加任何交易控制程式碼的(MIDAS元件已經幫你做掉);但如果你自己開Interface方法,那就必須自行控制交易 2.很不幸的是,兩種效率都很差,你可以自行用SQL Profiler對SQL Server監看AP Server所下SQL語法,一般而言將DataSetProvider的ResolveToDataSet設為True,問題會比較少,但在異動此一動作上,老實說真的非常沒效率,比方說再偷懶寫法下,Client只異動一筆,雖然傳回AP Server的Delta資料也只有兩筆(原始和目前異動的),但AP的ADODataSet卻會取回全部筆數的資料來比對,....., 我個人的做法為,異動時再動態解析Delta的資料,動態組成SQL語法去SQL Server取回異動要比對的資料,再由adoDataSet元件異動回去,有點類似混合做法,但代價就是要付出多餘的程式碼 其實就用SQL Profiler對SQL Server監控的結果來說,MIDAS的Master/Detail巢狀架構真的非常沒效率,你自行監控看看就曉的了 混心雜欲 棄修身~唉
------
唉~
Andy Wu
一般會員


發表:17
回覆:25
積分:18
註冊:2004-02-25

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-02-27 00:52:20 IP:61.229.xxx.xxx 未訂閱
引言: 1.你所謂鎖定是啥意思,基本上SQL Server本身會自己管理交易的相關問題,並不需要像傳統桌上型資料庫一樣必須自行下Lock指令 你唯一要注意的是這六個表格是否在同一個交易之內(在ap端這六個表都必須連相同的ADOConnection),另外要注意的是程式碼寫在哪邊,若是寫在DataSetProvider的相關事件中,一般而言是不需要加任何交易控制程式碼的(MIDAS元件已經幫你做掉);但如果你自己開Interface方法,那就必須自行控制交易 2.很不幸的是,兩種效率都很差,你可以自行用SQL Profiler對SQL Server監看AP Server所下SQL語法,一般而言將DataSetProvider的ResolveToDataSet設為True,問題會比較少,但在異動此一動作上,老實說真的非常沒效率,比方說再偷懶寫法下,Client只異動一筆,雖然傳回AP Server的Delta資料也只有兩筆(原始和目前異動的),但AP的ADODataSet卻會取回全部筆數的資料來比對,....., 我個人的做法為,異動時再動態解析Delta的資料,動態組成SQL語法去SQL Server取回異動要比對的資料,再由adoDataSet元件異動回去,有點類似混合做法,但代價就是要付出多餘的程式碼 其實就用SQL Profiler對SQL Server監控的結果來說,MIDAS的Master/Detail巢狀架構真的非常沒效率,你自行監控看看就曉的了 混心雜欲 棄修身~唉
感激不盡,speedup大大的講解讓小弟對三層式開發又有了更深的認識~~ 至於speedup大大所提到的「動態解析Delta的資料」,要怎麼個解析法呢?我把Delta轉存成XML文件,但是卻不是很瞭解裡面的內容,我要怎麼個解析法?
jieshu
版主


發表:42
回覆:894
積分:745
註冊:2002-04-15

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-02-27 09:18:10 IP:203.204.xxx.xxx 未訂閱
引言: 但是,現在我的資料結構,Master/Detail總共有六層,如果採用二位的作法,勢必Master的這一個DataSetProvider就得要負責這六個ClientDataSet的ApplyUpdate,在Ap Server設置五個全域變數,將每一個DataSet所得到的最大ID儲存下來,提供給下一層的DataSet使用,降子一來,這個DataSetProvider會不會太過忙碌?導致隱藏的問題發生?(例如Client端--A,ApplyUpdate之後得到某一資料表的Max ID = 1,Client端--B,ApplyUpdate之後得到此資料表的Max ID = 2,那麼下一層的DataSet去存取此全域變數,會不會錯亂掉?)
全域變數會不會錯亂,端看Create RemoteDataModule的參數,預設的
  TComponentFactory.Create(ComServer, TRemoteDataModule1,
    Class_RemoteDataModule1, ciMultiInstance, tmApartment);
如果是宣告在RemoteDataModule內就不會。因為每個連上的Client都會有獨自的執行個體。 建議一次不要存太多資料,以免導致交易時間變長,而增加資料庫Lock產生的機會。
人生有夢,逐夢而行。 人若為善,福雖未至,禍已遠離。 人若為惡,禍雖未至,福已遠離。 http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行
人若為善,福雖未至,禍已遠離
人若為惡,禍雖未至,福已遠離
http://www.taconet.com.tw/jieshu/
jieshu
版主


發表:42
回覆:894
積分:745
註冊:2002-04-15

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-02-27 09:47:48 IP:203.204.xxx.xxx 未訂閱
引言: 問題一:這六個資料表是否會被鎖定?SQL Server2000的預設鎖定機制為何? 問題二:產生交易後,會紀錄所有的異動,當每一組Master/Detail異動的資料量都很大的時候,假設同時間Ap Server接收到N個Client端的ApplyUpdate,SQL Server都能夠把每個交易內的異動都紀錄下來嗎?有沒有上限?
1.在下達交易指令後,當資料庫要更新該資料表時,就會自動鎖定該資料表,以確保資料的一致性,用鎖定到線上叢書找,應該可找到更多相關資料。 2.應該可以吧,記得在轉檔時好像可以達到幾萬筆吧,或是找看看有沒有相關參數可以設定,像是連線逾時...,但最好不要因為時間一久,會產生封鎖和被封鎖的產生,造成整個資料庫的死結,所以一次交易越快越好。
人生有夢,逐夢而行。 人若為善,福雖未至,禍已遠離。 人若為惡,禍雖未至,福已遠離。 http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行
人若為善,福雖未至,禍已遠離
人若為惡,禍雖未至,福已遠離
http://www.taconet.com.tw/jieshu/
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-02-27 10:10:09 IP:61.224.xxx.xxx 未訂閱
引言: 至於speedup大大所提到的「動態解析Delta的資料」,要怎麼個解析法呢?我把Delta轉存成XML文件,但是卻不是很瞭解裡面的內容,我要怎麼個解析法?
Delta的資料基本上你可以用ClientDataSet來解讀 TClientDataSet.Delta屬性可以把異動資料從目前操作的ClientDataSet讀出並轉成OleVariant資料 你可以用另外的ClientDataSet來解讀裡面的資料,如宣告一個myCDS,直接用 myCDS.Data := OrgCDS.Delta 就可讀出OrgCDS的異動資料 在TClientDataSet類別中提供一個UpdateStatus函數可以讀出目前所Locate該筆記錄的狀態分別為
1. usUnmodified 
   The current record has no unapplied updates.
2. usModified 
   The current record has unapplied modifications.
3. usInserted 
   The current record has been inserted but the insertion was not applied.
4. usDeleted        
   The current record represents a deleted record, where the deletion  has not yet been applied.
 
在異動時基本上有三種類型分別為 1.新增一筆資料,在Delta中會有一筆資料,標示為usInserted 2.修改資料,在Delta中會有兩筆資料分別為原始,和修改後標示為usUnmodified和usModified 3.刪除資料,在Delta中會一筆資料,標示為usDeleted 你可以先寫簡單的測試程式來解讀Delta資料(先不要接任何AP Server) 由此可見,在MIDAS架構中異動資料從前端到AP端只傳異動的的結構,這一段還蠻Perfect 了解Delta結構之後,接著便是在AP端如何運用,這有賴你對於IAppServer和ClientDataSet/DataSetProvider 三者之間的了解程度 像DataSetProvider的BeforeUpdateRecord基本上已經幫你把Delta的資料解出 混心雜欲 棄修身~唉
------
唉~
Andy Wu
一般會員


發表:17
回覆:25
積分:18
註冊:2004-02-25

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-02-27 12:53:31 IP:203.204.xxx.xxx 未訂閱
感謝幾位大大的熱心回應,小弟會根據幾位大大的說明,進行相關的測試與修改,真是感激不盡~~~~
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-03-06 12:07:08 IP:218.18.xxx.xxx 未訂閱
引言: 比方說再偷懶寫法下,Client只異動一筆,雖然傳回AP Server的Delta資料也只有兩筆(原始和目前異動的),但AP的ADODataSet卻會取回全部筆數的資料來比對,.....,
对啦,如果资料特别多的话,还是自己在DataSetProvider里把DELTA抓住,解析为自己的SQL语句,然后直接去执行这个SQL语句比较好。 根据我读DataSetProvider的SOURCE,它一定会把数据库里全部记录(可能有10万条,它就取10万条!)读进来,和你的DELTA那条记录的原记录对比的!这样的确效率很低。 ADODATASET会怎么做,我就不知道了。
系統時間:2024-04-25 9:03:33
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!