一個DataModule如何應付多個不同業務的用戶端 |
缺席
|
huangbh57
一般會員 發表:28 回覆:21 積分:9 註冊:2004-10-11 發送簡訊給我 |
一個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 發送簡訊給我 |
|
jieshu
版主 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言:主要使用在上面這一段, 其餘只是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/哦,三个字段,第一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)
------
人生有夢,逐夢而行 人若為善,福雖未至,禍已遠離 人若為惡,禍雖未至,福已遠離 http://www.taconet.com.tw/jieshu/ |
jieshu
版主 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言:經詳看程式碼, 應該是只要在您的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/引言:主要使用在上面這一段, 其餘只是mustapha.wang兄對他研究的講解, 但沒有講解要怎麼用到要Update的DataSet上, 應該請mustapha.wang可否提供一下使用的範例, 例如取得Properties後要給誰, 怎麼給.哦,三个字段,第一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)
------
人生有夢,逐夢而行 人若為善,福雖未至,禍已遠離 人若為惡,禍雖未至,福已遠離 http://www.taconet.com.tw/jieshu/ |
huangbh57
一般會員 發表:28 回覆:21 積分:9 註冊:2004-10-11 發送簡訊給我 |
|
jieshu
版主 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言: 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 發送簡訊給我 |
huangbh57 大大, 應該是,一個Remote Data Module如何應付多個不同業務的用戶端吧? 例如以下的 Remote Data Module 元件安排: SQLConnection1 <-- SQLTable1 <-- DataSetProvider1
<-- SQLTable2 <-- DataSetProvider2
<-- SQLTable3 <-- DataSetProvider3
// 要幾個就加幾個 然後撰寫多個 Client 端應用程式,設定 DCOMConnection1 後,
ClientDataSet的ProviderName 隨你選舉任何一個 DataSetProvider,
這樣,每個應用程式不就都連接同一個 Remote Data Module 但卻有不同的
業務功能嗎?
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |