科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件DELPHI多层分布式开发(二)

DELPHI多层分布式开发(二)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文急袭讲解DELPHI多层分布式开发

作者:codesky.net  来源:codesky.net  2007年9月15日

关键字: 软件

  • 评论
  • 分享微博
  • 分享邮件
下面解决这个问题。

现在,在服务器上再做一个方法: GetTableNames ,准备向客户端送表名。

注意,要用Add加入一个传出参数。

刷新后产生一个新的方法:

function GetTableNames: OleVariant; safecall;

现在可以写方法程序了:

function TPcSQL.GetTableNames: OleVariant;

var

I: Integer;

DBTables: TStrings;

begin

//
建立一个字符串数组存放所有表名。

DBTables := TStringList.Create;

try

//
利用Database控件取得当前所有表名数据。

Database1.GetTableNames(DBTables , False);

/// 建立一个变量数组给函数返回变量Result

Result := VarArrayCreate([0, DBTables.Count - 1], varOleStr);

// 最后再把表名数据指定给该变量数组。

for I := 0 to DBTables.Count - 1 do

Result[I] := DBTables[I];

finally

DBTables.Free;

end;

end;

然后重新保存,注册,运行一下。

再看客户端:

现在给它再加一个ComboBox,以显示当前打开的数据库的表名。

; .FormCreate事件过程中,再声明一个变量:

DBTables: OleVariant;

.FormCreate程序的最后加上:

//显示表名

ComboBox2.Clear;

DBTables := DCOMConnection1.AppServer.GetTableNames;

if VarIsArray(DBTables) then

for I := 0 to VarArrayHighBound(DBTables, 1) do

ComboBox2.Items.Add(DBtables[I]);

为了在改变数据库后也能正确显示相应的表名,ComboBox1的双击事件也要加上相应的一段。

procedure TForm1.ComboBox1DblClick(Sender: TObject);

var

UserName, Password: string;

//下面两的变量声明是新加的

DBTables: OleVariant;

i:integer;

begin

//
当您在ComboBox中选取的数据不是空字符串时

if ComboBox1.Text <> '' then

begin

ClientDataSet1.Close;

try

//
先给应用程序服务器传一次空的UserNamePassword

//
如果后台数据库是ParadoxdBASE可能就没问题,


//
可是如果是SQL base的关系型数据库则会收到exception

//SetDatabaseNames
是服务端的COM 方法

DCOMConnection1.AppServer.SetDatabaseName(ComboBox1.Text,'','');

except

// 由于后台数据库是SQL base的关系型数据库,所以您必须

//
通过Form2输入UserNamePassword,并且把这些数据

//
通过应用程序服务器提供的SetDatabaseName传给后台数

//
据库验证。

on E: Exception do

if E.Message = 'Password Required' then

begin

if InputDialog(UserName, Password) then

DCOMConnection1.AppServer.SetDatabaseName(ComboBox1.Text,

UserName, Password);

end else raise;

end;

//显示表名,这段程序是新加的

ComboBox2.Clear;

DBTables := DCOMConnection1.AppServer.GetTableNames;

if VarIsArray(DBTables) then

for I := 0 to VarArrayHighBound(DBTables, 1) do

ComboBox2.Items.Add(DBtables[I]);

ComboBox2.Text:=ComboBox2.items[0];

end;

end;

ComboBpx2加一个双击事件,可以把表的名字加入SQL 语言:

procedure TForm1.ComboBox2DblClick(Sender: TObject);

begin

Memo1.text:=Memo1.text+combobox2.text;

end;

效果就完全不同了,你可以方便的选择数据库和表:

然后组合适当的SQL语言,最终打开一个合适的表。

进一步考虑,组合新的SQL语言的时候最好要有字段名的数据,这不需要从服务器得到,因为在多层情况下,ClientDataSet实际上起着Ttable或者Tquery相似的作用,对数据库的控制上,有几乎相同的语言,例如记录指针的移动,字段数据的取得和写入等等,这样一来,你也可以直接使用这些方法来操纵数据库。

再一次提醒大家,ClientDataSet是个功能强大非常重要的控件,在Delphi的很多高级场合,都要使用到它。

当然,利用ClientDataSet,被打开数据库的字段名表也很容易得到。

首先再加一个Combbox控件Combbox3

SQL 查询的Button事件作如下修改:

procedure TForm1.Button1Click(Sender: TObject);

//
首先要定义两个变量

var i,N:integer;

begin

ClientDataSet1.Close;

ClientDataSet1.CommandText := Memo1.Lines.Text;

ClientDataSet1.Open;

//这是后加入的显示子段名的程序

ComboBox3.Clear;

N:=ClientDataSet1.FieldCount;

for I := 0 to N - 1 do

ComboBox3.Items.Add(ClientDataSet1.Fields[i].FieldName);

ComboBox3.Text:=ComboBox3.items[0];

end;

事实上,FormCreate事件程序也要加入相应的程序,使一打开程序就有子段名表显示。

procedure TForm1.FormCreate(Sender: TObject);

var

//
增加两个定义

I,N: Integer;

DBNames: OleVariant;

DBTables: OleVariant;

begin

//
连上应用程序服务器

DCOMConnection1.Connected := True;

// 取得BDE所有设置的数据库别名数据

DBNames := DCOMConnection1.AppServer.GetDatabaseNames;

// 假如有数据库别名数据,则将其一个一个地加到ComboBox控件内

if VarIsArray(DBNames) then

for I := 0 to VarArrayHighBound(DBNames, 1) do

ComboBox1.Items.Add(DBNames[I]);

//把默认的数据库显示在第一个

ComboBox1.Text:='abc';

//显示表名

DBTables := DCOMConnection1.AppServer.GetTableNames;

if VarIsArray(DBTables) then

for I := 0 to VarArrayHighBound(DBTables, 1) do

ComboBox2.Items.Add(DBtables[I]);

ComboBox2.Text:=ComboBox2.items[0];

//显示字段名表,增加的程序

ComboBox3.Clear;

N:=ClientDataSet1.FieldCount;

for I := 0 to N - 1 do

ComboBox3.Items.Add(ClientDataSet1.Fields[i].FieldName);

ComboBox3.Text:=ComboBox3.items[0];

end;

需要时,也可以写入ComboBox3的双击事件:

procedure TForm1.ComboBox3DblClick(Sender: TObject);

begin

Memo1.text:=Memo1.text+combobox3.text;

end;

好了,现在可以看看效果:



这些数据取得以后,你就可以把这个客户程序做得更加方便通用,那就要看你的想象力和程序设计的水平了,这里的例子,主要是想提供客户端使用DCOM提供的方法的思想和规则,通过这样的研究,您是不是对DCOM 和分布式数据库的问题有了更深的理解了呢?



第七节一对多表的服务器端程序

一、Application Server

事先要有一个标准的
Form

file -> New -> Multitier -> Remote Data Module

CoClass Name : Master2

Instacting: Multiple Instacting

Threading Model: Apartment

放入 ADOTable1

ADOTable2

Datasouce1

DataSetProvider1(
Data Access)

DataSetProvider2

属性:

ADOTable1
(主表)


ADOTable2
(从表)

ConnectionStringTableName连上数据库

为了构建主从表,注意下面的图:

DataSouce1属性:DataSet=ADOTab1

ADOTable2属性:MasterSource=DataSource1

MasterField=
连结字段


TdataSetProvider1
属性:Dataset=ADOTable1

TdataSetProvider2
属性:
Dataset=ADOTable2

这就完成了主从表的服务器端构建。


保存,注册,运行一下。



二、客户端编程

首先建立一个普通的工程:

加入一个TDCOMConnection,两个TClientDataSet,和两个TdataSource

DCOMConnection1

属性:ComputerName=计算机名(本地可以不写)

ServerName=
服务器端程序名(COM

Connecter=true
(表示连上)


ClientDataSet1

属性:RemoteServer=DCOMConnection1

ProviderName=DataSetProvider1

Active-=true

ClientDataSet2

属性:
RemoteServer=DCOMConnection2

ProviderName=DataSetProvider2

Active-=true

两个TDataSource分别连上

ClientDataSet1


ClientDataSet2

加入两个TDBGrid,分别连上相应的DataSource

主从表似乎应该建立起来了,但运行一下就可以发现,主从关系并没有建立起来。

解决办法:

双击ClientDataSet1,出现一个Form1.ClientDataSet1窗口:

在窗口空白处右键,快捷菜单上选Add Field 这时,我们可以看到最后一行出现:ADOTable2 。这是很重要的,正是靠这个建立了主从联接关系

OK 让它进入Form1.ClientDataSet1窗口(也可以调整主表所显示的字段,但ADOTable2 不能少,它实际上是把从表作为主表的一个字段使用了)。

ClientDataSet2属性:

DataSetField=ClientDataSet1ADOTable2

Active=true


好啦,主从关系建立起来了。

通过这个研究可以发现,实际上在服务端程序中,DataSetProvider2是多余的,以后在设置的时候,可以不要。只需要一个DataSetProvider1就可以和客户端联系了。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章