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

一個DataModule如何應付多個不同業務的用戶端

缺席
huangbh57
一般會員


發表:28
回覆:21
積分:9
註冊:2004-10-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-04-20 10:27:07 IP:218.247.xxx.xxx 未訂閱
一個DataModule如何應付多個不同業務的用戶端, 有如下發表的文章,本人看不明白,希望哪位兄弟能幫我解釋一下,在此感激不盡(因本人用多個clientdataset連接同一個datasetprovider,並作資料更新) //当你在Com 的资料元件写 procedure TData.SaveData(Delta: OLEVariant); var EC:integer; begin try SQLQuery_Data.Close; SQLQuery_Data.SQL.Clear; DataSetProvider_Data.ApplyUpdates(Delta,0,EC); if EC>0 then Raise Exception.Create(UpdateErrorMsg) else SetComplete; except SetAbort; raise; end; end; procedure TData.DataSetProvider_DataUpdateError(Sender: TObject; DataSet: TCustomClientDataSet; E: EUpdateError; UpdateKind: TUpdateKind; var Response: TResolverResponse); begin UpdateErrorMsg:=E.Message; Response:=rrAbort; end; 来保存客户端TClientDataSet送来的异动资料时,你可能会发现资料保存不进去,会看到如下错误消息: unable to resole records.Table name not found. 意思是delta里没有TableName信息,Data里也没有,TDataSetProvider不知道如何产生更新的SQL语句。 需要让Client同时以参数形式把TableName传过来吗?SaveData变成 procedure SaveData(TableName:WideString;Delta:OLEVariant);virtual;safecall; 太麻烦了吧?有办法在返回TDataSetProvider.Data时就把TableName信息写入Data呢?而且Delta也能带回? 我们看看TDataSetProvider的OnGetDataSetProperties事件,好像可以夹杂点自己的东西到Data里,如何让它认识这是TableName信息呢?看看Provider.pas的TSQLResolver的: procedure TSQLResolver.InitTreeData(Tree: TUpdateTree); override; .... begin if Tree.Data <> nil then Dispose(PSQLInfo(Tree.Data)); New(Info); Tree.Data := Info; Info.IsSQLBased := IProviderSupport(Tree.Source).PSIsSQLBased; Info.QuoteChar := IProviderSupport(Tree.Source).PSGetQuoteChar; TableName := VarToStr(Tree.Delta.GetOptionalParam(szTABLE_NAME)); if TableName = '' then TableName := IProviderSupport(Tree.Source).PSGetTableName; Provider.DoGetTableName(Tree.Source, TableName); ...... 哦,要用szTABLE_NAME,如何夹入到Param里呢?格式如何? 再看看 procedure TDataSetProvider.DoGetProviderAttributes(DataSet: TDataSet; List: TList); var CustParams: OleVariant; Attr: PPacketAttribute; i, j: Integer; begin IProviderSupport(DataSet).PSGetAttributes(List); if Assigned(FGetDSProps) then begin FGetDSProps(Self, DataSet, CustParams); if VarIsArray(CustParams) then begin for i := VarArrayLowBound(CustParams, 1) to VarArrayHighBound(CustParams, 1) do begin if VarIsArray(CustParams[i]) and (VarArrayHighBound(CustParams[i], 1) - VarArrayLowBound(CustParams[i], 1) = 2) then begin j := VarArrayLowBound(CustParams[i], 1); New(Attr); List.Add(Attr); with Attr^ do begin Name := CustParams[i][j]; Value := CustParams[i][j 1]; IncludeInDelta := CustParams[i][j 2]; end; end; end; end; end; end; 哦,三个字段,第一Name,第二个Value,第三个是否包含在Delta里,ok,干吧 procedure TData.DataSetProvider_DataGetDataSetProperties(Sender: TObject; DataSet: TDataSet; out Properties: OleVariant); var V:OLEVariant; begin Properties:=VarArrayCreate([0,0],varVariant); V:=VarArrayCreate([0,2],varVariant); V[0]:=szTABLE_NAME; V[1]:=GetTableNameFromQuery(TSQLQuery(DataSet).SQL.Text); V[2]:=true; Properties[0]:=V; end; GetTableNameFromQuery函数在DBCommon.pas 我用的dbexpress,因此用TSQLQuery(DataSet
mustapha.wang
資深會員


發表:89
回覆:409
積分:274
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-04-22 21:45:54 IP:218.1.xxx.xxx 未訂閱
RemoteDataModule,使用预设的Apartment线程,Server端会为每个客户端建立不同的线程和RemoteDataModule元件,不用担心会有什么问题。如果想简单点,就是不要在RemoteDataModule一对一的放置很多的DataSet,而改成函数提供调用。     久病成良医--多试 千人之诺诺,不如一士之谔谔--兼听
------
江上何人初见月,江月何年初照人
jieshu
版主


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-04-23 15:26:10 IP:203.204.xxx.xxx 未訂閱
引言:
哦,三个字段,第一Name,第二个Value,第三个是否包含在Delta里,ok,干吧
procedure TData.DataSetProvider_DataGetDataSetProperties(Sender: TObject;
  DataSet: TDataSet; out Properties: OleVariant);
var
  V:OLEVariant;
begin
  Properties:=VarArrayCreate([0,0],varVariant);
  V:=VarArrayCreate([0,2],varVariant);
  V[0]:=szTABLE_NAME;
  V[1]:=GetTableNameFromQuery(TSQLQuery(DataSet).SQL.Text);
  V[2]:=true;
  Properties[0]:=V;
end;
GetTableNameFromQuery函数在DBCommon.pas 我用的dbexpress,因此用TSQLQuery(DataSet)
主要使用在上面這一段, 其餘只是mustapha.wang兄對他研究的講解, 但沒有講解要怎麼用到要Update的DataSet上, 應該請mustapha.wang可否提供一下使用的範例, 例如取得Properties後要給誰, 怎麼給. <iFrame src="http://www.coss.com.tw/jieshu/sign.htm" width=400 height=105 scolling="NO" border="0"></iFrame> 震江系統(股)公司: http://www.coss.com.tw/ 捷舒軟體設計坊: http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行
人若為善,福雖未至,禍已遠離
人若為惡,禍雖未至,福已遠離
http://www.taconet.com.tw/jieshu/
jieshu
版主


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-04-25 11:12:48 IP:203.204.xxx.xxx 未訂閱
引言:
引言:
哦,三个字段,第一Name,第二个Value,第三个是否包含在Delta里,ok,干吧
procedure TData.DataSetProvider_DataGetDataSetProperties(Sender: TObject;
  DataSet: TDataSet; out Properties: OleVariant);
var
  V:OLEVariant;
begin
  Properties:=VarArrayCreate([0,0],varVariant);
  V:=VarArrayCreate([0,2],varVariant);
  V[0]:=szTABLE_NAME;
  V[1]:=GetTableNameFromQuery(TSQLQuery(DataSet).SQL.Text);
  V[2]:=true;
  Properties[0]:=V;
end;
GetTableNameFromQuery函数在DBCommon.pas 我用的dbexpress,因此用TSQLQuery(DataSet)
主要使用在上面這一段, 其餘只是mustapha.wang兄對他研究的講解, 但沒有講解要怎麼用到要Update的DataSet上, 應該請mustapha.wang可否提供一下使用的範例, 例如取得Properties後要給誰, 怎麼給.
經詳看程式碼, 應該是只要在您的RemoteDataModule上的共用TDataSetProvider上的OnGetDataSetProperties事件, 給以上程式碼即可, 但仍要依使用的DataSet做稍微的修正. <iFrame src="http://www.coss.com.tw/jieshu/sign.htm" width=400 height=105 scolling="NO" border="0"></iFrame> 震江系統(股)公司: http://www.coss.com.tw/ 捷舒軟體設計坊: http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行
人若為善,福雖未至,禍已遠離
人若為惡,禍雖未至,福已遠離
http://www.taconet.com.tw/jieshu/
huangbh57
一般會員


發表:28
回覆:21
積分:9
註冊:2004-10-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-04-29 12:07:31 IP:218.247.xxx.xxx 未訂閱
經詳看程式碼, 應該是只要在您的RemoteDataModule上的共用TDataSetProvider上的OnGetDataSetProperties事件, 給以上程式碼即可, 但仍要依使用的DataSet做稍微的修正. 兄弟能否提供完整的程序碼,因本人也按你所說的做,但不知如何修正(但仍要依使用的DataSet做稍微的修正),在此很感激!!!
jieshu
版主


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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-29 13:24:43 IP:203.204.xxx.xxx 未訂閱
引言: V[1]:=GetTableNameFromQuery(TSQLQuery(DataSet).SQL.Text); GetTableNameFromQuery函数在DBCommon.pas 我用的dbexpress,因此用TSQLQuery(DataSet)
關鍵在上面幾行, 仔細看就知道了. 1.要Uses DBCommon. 2.DataSet如果用TSQLQuery就用TSQLQuery(DataSet).SQL.Text, 如果用TQuery就用TQuery(DataSet).SQL.Text, 以此類推. <iFrame src="http://www.coss.com.tw/jieshu/sign.htm" width=400 height=105 scolling="NO" border="0"></iFrame> 震江系統(股)公司: http://www.coss.com.tw/ 捷舒軟體設計坊: http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行
人若為善,福雖未至,禍已遠離
人若為惡,禍雖未至,福已遠離
http://www.taconet.com.tw/jieshu/
cancer
高階會員


發表:58
回覆:319
積分:190
註冊:2004-07-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-05-08 18:39:01 IP:210.201.xxx.xxx 未訂閱
huangbh57 大大, 應該是,一個Remote Data Module如何應付多個不同業務的用戶端吧? 例如以下的 Remote Data Module 元件安排: SQLConnection1 <-- SQLTable1 <-- DataSetProvider1 <-- SQLTable2 <-- DataSetProvider2 <-- SQLTable3 <-- DataSetProvider3 // 要幾個就加幾個 然後撰寫多個 Client 端應用程式,設定 DCOMConnection1 後, ClientDataSet的ProviderName 隨你選舉任何一個 DataSetProvider, 這樣,每個應用程式不就都連接同一個 Remote Data Module 但卻有不同的 業務功能嗎?
系統時間:2024-04-25 14:42:22
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!