利用DCOM建立了3层,远程数据模块(名字为DCOMServer)中放置了TDATABASE、TQuery、TDataSetProvider;客户端放置了DCOMConnection、TClientDataSet、TDataSource,到这里连接都成功了,数据也从设定好的一个表中成功取出并在DBGrid中显示了。然后照书上所说在远程数据模块中利用Type Library在IDCOMServer下添加新的方法叫nwQuery,设置了两个参数,并编写了代码用于重新设置远程数据模块中的TQuery的SQL属性。然后书上说要在客户端调用该服务只需将Provider的Exported属性设为True(已设置),客户端添加以下代码即可:ClientDataSet1.AppServer.nwQuery(参数)。我是将该代码放于客户端的一个按钮点击事件下的,但是奇怪的是输入到AppServer. 后面没有出现nwQuery这个方法可供选择,强行写上后也没有用,有高手能帮忙下吗?万分感谢!
这个不对。应该是DCOMConnection.
procedure TForm2.Button1Click(Sender: TObject);
var
aa:Iasasasas;//这是你的_TLB文中定义的接口。你查一下这个自动生成的文件会看到。
strSql:WideString;begin
aa:=Coasasasas.Create;//要创建一个对象。
aa.wy(strSql);
showmessage(strSql);end;先说明:APPSERVER接口是取不到自定义方法的。
首先在USE中加入你项目的_TLB单元。
_TLB自动生成的接口如下。一般在此文件最后部分。class function Coasasasas.Create: Iasasasas;//接口
begin
Result := CreateComObject(CLASS_asasasas) as Iasasasas;
end;//DCOM兼容接口
class function Coasasasas.CreateRemote(const MachineName: string): Iasasasas;
begin
Result := CreateRemoteComObject(MachineName, CLASS_asasasas) as Iasasasas;
end;
procedure TDCOMServer.nwQuery(ID, Name: OleVariant);
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select * from 博士后基本信息表 where BSHH=:BSH and XM=:NXM' );
Query1.ParamByName('BSH').Value:=ID;
Query1.ParamByName('NXM').Value:=Name;
Query1.Open;
end;
客户端的按纽点击后应该执行该过程,并取得新记录在DBGrid上反映出来,但事实上没有,我的点击事件的代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
Inter:IDCOMServer;
UID:OLEVariant;
UName:OLEVariant;begin
UID:=id.Text;
UName:=name.Text;
inter:=CoDCOMServer.Create;
Inter.nwQuery(UID,UName);
ClientDataSet1.Refresh;
DBGrid1.DataSource:=DataSource1;
DBGrid1.Visible:=True;
end;
奇怪就是无法在客户端反映出来,555555
TO:楼主。你这样取数据的方法我觉得并不好。clientdataset本身就可以到得数据,你在中间层更新的数据,但clientdataset的commandtext值估计你没改,所以refresh后,客户端还是根据clientdataset的commandtext来通过中间层取得数据。看上去数据是没有变化。取数据的话可以用APPSERVER的集成方法。都是AS_开头的。直接返回数据封包,不用DCOM。这是MIDAS3.0无状态对象的核心技术啊。方法说明你可以看看_TLB文件。
PS:建议人这样的系统做成COM+对象,更好一些。
让clientdataset.data:=这个变量就行了。function AS_GetRecords(const ProviderName: WideString; Count: Integer; outRecsOut: Integer;Options: Integer; const CommandText: WideString; var Params: OleVariant;var OwnerData: OleVariant): OleVariant;CommandText值不同,就可以取不同的表了。
var
ServerProject:Iappserver; //
Option: TGetRecordOption;
iRecOut: Integer;
OwnerData: OleVariant;
Params,vDatas: OleVariant;
strSql:WideString;
begin
strSql:='select * from tblname';
vDatas:=MyConnect.AS_GetRecords('dspQuery',-1,iRecOut,Byte(Option),strSql,Params,OwnerData);
cdsXX:=vDatas;
end;
var
ServerProject:Iappserver; //
Option: TGetRecordOption;
iRecOut: Integer;
OwnerData: OleVariant;
Params,vDatas: OleVariant;
strSql:WideString;
begin
strSql:='select * from tblname';
ServerProject:=DComConnection1.GetAppServer;
vDatas:=ServerProject.AS_GetRecords('dspQuery',-1,iRecOut,Byte(Option),strSql,Params,OwnerData);
cdsXX:=vDatas;
end;
传不过去的,再不行的话检查你的SQL语句,例如要这样写:select * from 表名 where
name='''+参数+''' ,如果有整型要这样写select * from 表名 where name='+inttostr(参数)+’;如果再不行的话把database拿开,不要放在远程数据模块,会有影响的,我建议你用ADO控件,连数据源都省了