直接上步骤效果,理论的我也不懂呢
一、服务器端:新建立 application 工程。之后建立数据单元文件New->other->Multitier->Remote Data Module(窗体命名 为Tserverdm)。
做数据链接。添加数据库控件: adosql: TADOQuery;
proversql: TDataSetProvider; 对外提供服务。
consql: TADOConnection; 连接数据库
proversql: TDataSetProvider; 对外提供服务。
consql: TADOConnection; 连接数据库
注意:设置TDataSetProvider 的allowcommandtext 为true. 非则不能 通过sql语句获取数据。
服务端代码如下:
unit udm; {$WARN SYMBOL_PLATFORM OFF} interface uses Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr, DBClient, server_TLB, Forms,StdVcl, DB, ADODB,OleDB,ActiveX, Controls,Provider; type Tserverdm = class(TRemoteDataModule, Iserverdm) adosql: TADOQuery; proversql: TDataSetProvider; consql: TADOConnection; procedure RemoteDataModuleCreate(Sender: TObject); private { Private declarations } Function ConnDB(UdlFileName:string):String; procedure Init_ConnectionString(FileName : String; Var Cons :string); protected class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override; public { Public declarations } end; var myserverdm :Tserverdm; implementation {$R *.DFM} class procedure Tserverdm.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); begin if Register then begin inherited UpdateRegistry(Register, ClassID, ProgID); EnableSocketTransport(ClassID); EnableWebTransport(ClassID); end else begin DisableSocketTransport(ClassID); DisableWebTransport(ClassID); inherited UpdateRegistry(Register, ClassID, ProgID); end; end; procedure Tserverdm.Init_ConnectionString(FileName: String; var Cons: string); Var DataInit : IDataInitialize; FName : POleStr; s : POleStr; Tmp : WideString; begin //直接读udl文件,从中获取数据链接字符串 ok! Tmp:= FileName; FName:=POleStr(Tmp); DataInit:=CreateComObject(CLSID_DataLinks) as IDataInitialize; DataInit.LoadStringFromStorage(FName,s); Cons:=s; DataInit:=nil; end; function Tserverdm.ConnDB(UdlFileName: string): String; Var FileNames, SerName : String; begin FileNames :=ExtractFilepath(Application.ExeName)+UdlFileName; Init_ConnectionString(FileNames,SerName); consql.Close; consql.ConnectionString:=SerName; Application.ProcessMessages; Try consql.Open; Result:='0'; except On E:Exception Do Begin consql.Close; consql.Free; Result:='-1'+E.Message; End; end; end; procedure Tserverdm.RemoteDataModuleCreate(Sender: TObject); begin ConnDB('dbsql.udl'); end; initialization TComponentFactory.Create(ComServer, Tserverdm, Class_serverdm, ciMultiInstance, tmApartment); end.
客户端建立:
新建 applicatinon 工程。 添加组件: consql: TDCOMConnection; 连接服务端,设置属性:computerName 为本机名,servername 为添加服务端TDataSetProvider控件名称。
cds1: TClientDataSet; // TClientDataSet 属性servername 为添加服务端TDataSetProvider控件名称。
ds2: TDataSource;
dbgrd1: TDBGrid; 显示数据
客户端主要代码如下:
unit uMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, DBGrids, DB, StdCtrls, Buttons, DBClient, MConnect; type TForm2 = class(TForm) consql: TDCOMConnection; cds1: TClientDataSet; btnser: TBitBtn; ds2: TDataSource; dbgrd1: TDBGrid; Button1: TButton; procedure btnserClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.btnserClick(Sender: TObject); begin with cds1 do begin Close; CommandText :='select top 10 bahao,xming,xbie, xxing from dbo.pub_bren '; Open; end; end; end.
procedure TForm2.Button1Click(Sender: TObject);
begin
cds1.Edit;
cds1.FieldByName('xxing').AsString :='a';
cds1.Post;
cds1.ApplyUpdates(0);
//提交入数据库,看到生成的 修改语句是这样的 ,把四个字段都做为条件了,这样可不好啊。
//exec sp_executesql N'update dbo.pub_bren set
// xxing = @P1
//where
// bahao = @P2 and
// xming = @P3 and
// xbie = @P4 and
// xxing is null
//',N'@P1 varchar(50),@P2 varchar(50),@P3 varchar(50),@P4 int','a','BR00000001','杨贵生',1
另外这样的 循环修改是不对的。
with not cds1.Eof do
begin
edit;
fieldbyname('').asstring :='a';
post ;
end;