关于MTS的构建和数据处理问题[400分](300分)

  • 主题发起人 主题发起人 hjandy
  • 开始时间 开始时间
H

hjandy

Unregistered / Unconfirmed
GUEST, unregistred user!
(1) 120分 在MTS中建一客户端通用查询,比如从ClientDataSet中提取自订栏位并输入
相关资料查询相关资料
(2) 280分 建三层架构(MTS),请提供例子可EMail -> hjandy@21cn.com
注: A 我的客户端和服务器都是Windows 2000,数据库用MsSQL 2000
B.若认为分数太小请提出
-------------------- 以下资料仅供参考 ----------------------------
1.可参考李维 关于<<Delphi 5.x Ado/Mts/Com+>> 一书第九章
方法一、建MTS步紧
A.建Active Library 加 MTS/Com+数据模块并加入相关控件
B.建查询对象
C.建更新对象
---------------------------- 待处理问题 ----------------------
步骤如下:
1.在上述A中若使用AdoQuery向MsSQL 2000连接的表存在主键并自动加一
比如 表名为 User 栏位如下
Fields Date Type Length identity identity Seed identity inc
=========== ========== ======= ======== ============= ============
Auto_id Int 4 Yes 1 1
Employee_id Char 8
....
2.在 Fields Editor .. 中加入所有Fields并将DisplayLabel改成相应中文名称
3.设置TDataSetPrivider
4.在客户端用上述B调入相关资料(Select Auto_id, Employee_id, ... From user)
出现问题
问题(1):在客户端栏位 Auto_id 资料为仅读(Read Only)<-- 请问有什么办法可解决?
因若加入多笔记录会出错
己用方法:关闭 Auto_id 的 identity 为No, 在BeforeUpdateRecord中加入修改
处理没问题但总感觉不方便!
原因:1. 客户端 Auto_id 要入数值
2. 因在上述A中 Auto_id 的ProviderFlags设置pfinKey
问题(2):在上述A中若用AdoQuery并设置
Select top 900 Auto_id, Employee_id ... From User
Where Auto_id > :id Order By Auto_id
那必须在存贮前先取回资料参数值 Auto_id 否则无法存贮,
请问有没有更好的办法
比如 (注: 下述 SetKey 相应 :id 值)
procedure TMtsCustomer.UpdateDatas(vDatas: OleVariant;
iMaxErrors: Integer;
var iErrorCount: Integer;
SetKey: OleVariant);
begin
if not ((VarIsEmpty(SetKey)) or (VarIsNull(SetKey))) then
begin
AdoQuery.Parameters.ParamByName('id').Value := SetKey;
try
DataSetProvider.ApplyUpdates(vDatas, iMaxErrors, iErrorCount);
if (iErrorCount <= iMaxError) or (iErrorCount = -1) then
SetAbort
else
SetComplete;
except
SetAbort;
end;
end;
// else
...
end;

问题(3): 在上述C中若出现更新错误,怎样把出错记录结果传回并在客户端显示呢?

注:因本人需将Midas转为MTS,上述为主要关键部份! 烦请多多指教!!
 
唔会吧! 难道很难吗?
 
为什么要将midas转为mts
 
第3点
将DataSetProvider.ApplyUpdates的返回值传回客户端
 
关注。有例子请发到我得信箱中
ricezj@163.com
 
本人也在作同样的事情,希望交流
 
1.根本不用管auto_id,就当它不存在。Sql Server会为我们做好每一件事。直接从select中去也或在显示给用户前把audo_id干掉就行了。
2.既然如此,在AdoQuery的Fields Editor中将Auto_id的Visiable设为False好了。
3.这个问题其实很有一点难度。想知道怎样实现吗?我也没有十分好的办法,给你一个将就一点吧(其实这个“将就”的办法也不知杀死了我多少个脑细胞):
设:协调对象Coor(mtsCoor),MTS数据模块MTSDB,这个方法在Coor中实现。
为了便于说明问题,我在这个按你的意思应该是更新对象的Coor中也实现了查询数据的能力。
唉,花了近两个小时才搞定这个自以为easy的片断,道行不到家呀,咱还都得练。
给源代码吧:
MTS数据模块,用ADO、TDataSetProvider(Name:dspEmployee)连接到Sql Server的Pubs数据库中的一个表,这个表有以下字段:Auto_id,Name,Sex,Birthday,Memo,其类型应该一看便知。myCoor实现了一个方法:GetDatas。
protected
procedure GetDatas(var vDatas: OleVariant);
safecall;
public
{ Public declarations }
end;

var
mtsDB: TmtsDB;
implementation
{$R *.DFM}
class procedure TmtsDB.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
begin
...
end;

procedure TmtsDB.GetDatas(var vDatas: OleVariant);
begin
vDatas:=dspEmployee.Data;
end;

initialization
TComponentFactory.Create(ComServer, TmtsDB,
Class_mtsDB, ciMultiInstance, tmApartment);
end.

MTS中介对象:
实现两个方法:GetDatas和UpdateDatas,具体参数自己看吧。
uses ... Midas ,Provider;
...
type
TmtsCoor = class(TMtsAutoObject, ImtsCoor)
protected
procedure UpdateDatas(vDatas: OleVariant;
iMaxErrors, iErrorCount: Integer;
var vOwnerData: OleVariant);
safecall;
procedure GetDatas(var vDatas: OleVariant);
safecall;
{ Protected declarations }
end;

implementation
uses ComServ;
procedure TmtsCoor.UpdateDatas(vDatas: OleVariant;
iMaxErrors,
iErrorCount: Integer;
var vOwnerData: OleVariant);
var
myDB:ImtsDB;
myAPS:IAppServer;
begin
try
OleCheck(ObjectContext.CreateInstance(CLASS_MTSDB,IID_IMTSDB,myDB));
myAPS:=myDB as IAppServer;
myAPS.AS_ApplyUpdates('dspEmployee',vDatas,iMaxErrors,
iErrorCount,vOwnerData);
SetComplete;
except
SetAbort;
end;
end;

procedure TmtsCoor.GetDatas(var vDatas: OleVariant);
var
myDB:ImtsDB;
begin
try
OleCheck(ObjectContext.CreateInstance(CLASS_MTSDB,IID_IMTSDB,myDB));
myDb.GetDatas(vDatas);
SetComplete;
except
SetAbort;
end;
end;

initialization
TAutoObjectFactory.Create(ComServer, TmtsCoor, Class_mtsCoor,
ciMultiInstance, tmApartment);
end.

客户端:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, DBGrids, DB, DBClient, StdCtrls, pmtsCoor_TLB;
type
TForm1 = class(TForm)
ClientDataSet1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
ClientDataSet2: TClientDataSet;
DataSource2: TDataSource;
DBGrid2: TDBGrid;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ClientDataSet1AfterOpen(DataSet: TDataSet);
procedure ClientDataSet1AfterPost(DataSet: TDataSet);
private
myCoor:ImtsCoor;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
//更新数据
procedure TForm1.Button2Click(Sender: TObject);
var
iErrorCount:integer;
vDatas,vOwnerData:olevariant;
begin
iErrorCount:=-1;
if myCoor<>nil then
if ClientDataSet1.ChangeCount >0 then
try
vDatas:=ClientDataSet1.Delta;
myCoor.UpdateDatas(vDatas,0,iErrorCount,vOwnerData);
if not (varIsEmpty(vOwnerData) or varIsNull(vOwnerdata)) then
ClientDataSet2.Data:=vOwnerData;
//这里就是你想要的错误信息。如果有的话
ClientDataSet2.Close;
ShowMessage('Complete;');
except
raise;
end;
end;

//获取数据
procedure TForm1.Button1Click(Sender: TObject);
var
vDatas:oleVariant;
begin
if myCoor<>nil then
try
myCoor.GetDatas(vDatas);
if not (varIsEmpty(vDatas) or varIsNull(vDatas)) then
ClientDataSet1.Data :=vDatas
else
showmessage('Packet is empty.');
except
raise;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
myCoor:=comtsCoor.CreateRemote('win2k');
//建立中介对象
end;

//格式化DBGrid的显示
procedure TForm1.ClientDataSet1AfterOpen(DataSet: TDataSet);
var
i:integer;
begin
with ClientDataSet1do
begin
//这一段代码我为省时间就这样写了。
Fields[1].DisplayLabel :='姓名';
Fields[2].DisplayLabel :='性别';
Fields[3].DisplayLabel :='出生日期';
Fields[4].DisplayLabel :='备注';
end;
DBGrid1.Columns[0].Visible :=false;
for i:=1 to DBGrid1.Columns.Count -1do
DBGrid1.Columns.Title.Alignment :=taCenter;
end;

//将用户的操作(更新但未投递的数据)在DBGrid2中显示出来
procedure TForm1.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
ClientDataSet2.Data :=ClientDataSet1.Delta;
end;

end.

花了两个小时,希望你能够满意。如果再给这个小程序加入分段获取数据的能力的话,也就可以了。
其实还有其实方法可以达到你的要求。MTS/COM+中如何获取用户更新数据的错误,我也很想了解,但功力有限。


 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
816
SUNSTONE的Delphi笔记
S
后退
顶部