About MTS UPdates, help !~!~(200分)

  • 主题发起人 主题发起人 3p
  • 开始时间 开始时间
3

3p

Unregistered / Unconfirmed
GUEST, unregistred user!
我尝试李维的新书《delphi5.x ADO/MTS/COM+》的例子,有关MTS+ADO+MIDAS更新的例子,
利用MTS环境下和MIDAS结合,当数据插入不会发生问题,但当修改数据Updates时发生错误
,出现MTX的信息窗口,第一次“update database1 set field1=? ”问题在“?”,按OK
按钮后出现第二次MTX的信息窗口“update database1 set field1=? where field2=? and
field3=? and field4=?”问题也在这个“?”,“?”代表什么?为什么会出现窗口,当
再按OK按钮后,发现更新有效,每更新一条记录,就会出现2个MTX窗口,很烦恼!
哪位高人可以提示提示,我的开发无法进行下去了!谢谢各位!
 
修改一下RESOLVETODATASET属性值试一试.
 
按李维书上所说,resolvetodataset应该设置为TRUE,但这样datasetprovider的更新就
得依靠它所连接的dataset,如何实现?我所指的是datasetprovider已经通过clientdataset
取得了查询的数据,但如何去连接另外一个clientdataset或如何利用这个clientdataset
更新数据? 书上有关这样设置的例子我没见过,我也很想知道,请举例。谢谢。
如果单纯把resolvetodataset设置为TRUE,那么我在客户端的更新根本不会发生作用,
只有把resolvetodataset设置为默认的fasle,才起作用,但更改却发生了困惑的消息
窗口,而插入却不会,这是否真的是resolvetodataset的问题?按李维书上所说,应该
把resolvetodataset设置为TRUE,这样能减少Bug的影响,但到底如何利用:
resolvetodataset:=TRUE;这个设置,也就是,其他需要什么连接?需要什么设置和动作,
各位请参与指点,谢谢,谢谢笑傲江湖。
 
你太客气啦:)
我并没有提供太多帮助,共同学习吧.
在这方面也只是走马观花看了一点李维的书而已,它的例子也没去试.
动手经验方面远远不如你啊.
你的那个问题怎么样啦.
急啊!ADO+MTS!
我看了你最近的问题问了好多ADO/MTS的问题
在搞李维的第三本书吧.
很多都没有得到答案,因为有很多人现在都还没搞(清)它啊.
等哪一天你把这些问题都搞清楚了我们都要问你啦.
 
继续帮我呀!
我说说我的怀疑,是否是NT4.0的Transaction server问题?或Nt4.0自己的问题?
或是delphi5.0本身的问题,我已安装了dephi5的补丁及ADO的补丁。
笑傲江湖:
你没回答我一般情况下,关于resolvetodataset:=true;是如何再进一步实现
更新的,Tell Me Please,谢谢!
 
听说MTS+ADO+“COM+”在Win2000下将更稳定,这是真的吗?有谁试过?
 
我没试验过,不过我这个人向来都是赶时髦
什么新用什么,一年机器FDISK/FORMAT正常来说一季度一次
我在很早以前就用了WIN2K SERVER,四个月前换成了VIN2K ADVANCED SERVER
我的机器配置并不高(P3 450 ,128m, IBM THINKPAD390X)
建议你升级到WIN2K(PROFESSIONAL都可以)
做你的MTS/COM+程序吧.
 

笑傲江湖:
你没回答我一般情况下,关于resolvetodataset:=true;是如何再进一步实现
更新的,Tell Me more,谢谢!
 
如果我说你看看源码吧,你肯定不满意.
如果我把VCL源码都贴出来,肯定有人要骂娘
我自己都还没搞清楚,我也记不清李维的书上是怎么写的了.
可是,李维的书是怎么写出来的,还不是看源码,调试源码摸出来的
(当然啦他也可能利用自己特使身份从INPRISE那搞点内幕也不无可能)
我也不是写书的,现在也没这么多时间把他搞得很清楚,
当然啦,可能给我时间我也搞不清楚.
你看看下面有关VCL源码,看完之后,有时间接着讨论.
/////////////////////////////////////////////////////////////////////////////
{TDataSetProvider }
/////////////////////////////////////////////////////////////////////////////
function TDataSetProvider.InternalApplyUpdates(const Delta: OleVariant;
MaxErrors: Integer;
out ErrorCount: Integer): OleVariant;
var
TransactionStarted: Boolean;
begin
CheckDataSet;
TransactionStarted := not IProviderSupport(DataSet).PSInTransaction;
if TransactionStarted then
IProviderSupport(DataSet).PSStartTransaction;
try
CheckResolver;
Resolver.FUpdateTree.InitData(DataSet);
try
Result := inherited InternalApplyUpdates(Delta, MaxErrors, ErrorCount);
finally
Resolver.FUpdateTree.InitData(nil);
end;
finally
if TransactionStarted then
IProviderSupport(DataSet).PSEndTransaction((ErrorCount <= MaxErrors) or (MaxErrors = -1));
end;
end;

procedure TDataSetProvider.SetResolveToDataSet(Value: Boolean);
begin
if (Value <> FResolveToDataSet) and Assigned(Resolver) then
FreeResolver;
FResolveToDataSet := Value;
end;

function TDataSetProvider.CreateResolver: TCustomResolver;
begin
if ResolveToDataSet then
Result := TDataSetResolver.Create(Self) else
Result := TSQLResolver.Create(Self);
end;

procedure TDataSetProvider.CheckDataSet;
begin
if not Assigned(DataSet) then
DatabaseError(SMissingDataSet);
end;

/////////////////////////////////////////////////////////////////////////////
{ TDataSetResolver }
/////////////////////////////////////////////////////////////////////////////
constructor TDataSetResolver.Create(AProvider: TDataSetProvider);
begin
inherited Create(AProvider);
FOpened := False;
end;

function TDataSetResolver.GetProvider: TDataSetProvider;
begin
Result := TDataSetProvider(inherited Provider);
end;

procedure TDataSetResolver.begin
Update;
begin
FOpened := not Provider.DataSet.Active;
if FOpened then
begin
Provider.DataSet.Open;
FBookmark := '';
end else
FBookmark := Provider.DataSet.Bookmark;
end;

procedure TDataSetResolver.EndUpdate;
begin
if FOpened then
begin
Provider.DataSet.Close;
FOpened := False;
end else
begin
if (Length(FBookmark) > 0) and
Provider.DataSet.BookmarkValid(@FBookmark[1]) then
Provider.DataSet.Bookmark := FBookmark;
end;
end;

procedure TDataSetResolver.InitializeConflictBuffer(Tree: TUpdateTree);
begin
{ Set the conflict buffer to the current values of the data }
if Provider.FindRecord(Tree.Source, Tree.Delta, upWhereKeyOnly) then
Tree.Delta.AssignCurValues(Tree.Source);
end;

procedure TDataSetResolver.InternalBeforeResolve(Tree: TUpdateTree);
begin
Provider.FindRecord(Tree.Source, Tree.Delta, Provider.UpdateMode);
end;

procedure TDataSetResolver.PutRecord(Tree: TUpdateTree);
procedure PutField(Src, Dest: TField);
forward;
procedure PutObjectField(Src, Dest: TObjectField);
var
i: Integer;
begin
if VarIsNull(Src.NewValue) then
Dest.Clear else
for i := 0 to Src.FieldCount - 1do
if (not VarIsEmpty(Src.Fields.NewValue)) and
(pfInUpdate in Src.Fields.ProviderFlags) then
PutField(Src.Fields, Dest.Fields);
end;

procedure PutField(Src, Dest: TField);
begin
if (Src.DataType in [ftArray, ftADT]) then
PutObjectField(TObjectField(Src), TObjectField(Dest)) else
if (Src.DataType in [ftDataSet, ftReference]) then
raise Exception.CreateRes(@SNoDataSets) else
if (not VarIsEmpty(Src.NewValue)) and
(pfInUpdate in Src.ProviderFlags) then
Dest.Assign(Src);
end;

var
i: Integer;
Field: TField;
begin
with Treedo
try
for i := 0 to Delta.FieldCount - 1do
begin
Field := Source.FindField(Delta.Fields.FieldName);
if (Field <> nil) then
PutField(Delta.Fields, Field);
end;
Source.Post;
except
Source.Cancel;
raise;
end;
end;

procedure TDataSetResolver.DoUpdate(Tree: TUpdateTree);
begin
with Treedo
begin
if not Provider.FindRecord(Source, Delta, Provider.UpdateMode) then
DatabaseError(SRecordChanged);
Source.Edit;
PutRecord(Tree);
end;
end;

procedure TDataSetResolver.DoDelete(Tree: TUpdateTree);
begin
with Treedo
begin
if Provider.FindRecord(Tree.Source, Tree.Delta, Provider.UpdateMode) then
Source.Delete else
DatabaseError(SRecordChanged);
end;
end;

procedure TDataSetResolver.DoInsert(Tree: TUpdateTree);
begin
Tree.Source.Append;
PutRecord(Tree);
end;

/////////////////////////////////////////////////////////////////////////////
{ TSQLResolver }
/////////////////////////////////////////////////////////////////////////////
type
PSQLInfo = ^TSQLInfo;
TSQLInfo = record
IsSQLBased: Boolean;
QuoteChar: string;
QuotedTable: string;
QuotedTableDot: string;
Opened: Boolean;
HasObjects: Boolean;
end;

constructor TSQLResolver.Create(AProvider: TDataSetProvider);
begin
inherited Create(AProvider);
FSQL := TStringList.Create;
FParams := TParams.Create(nil);
end;

destructor TSQLResolver.Destroy;
begin
FSQL.Free;
FParams.Free;
inherited Destroy;
end;

function TSQLResolver.GetProvider: TDataSetProvider;
begin
Result := TDataSetProvider(inherited Provider);
end;

procedure TSQLResolver.DoExecSQL(SQL: TStringList;
Params: TParams);
var
RowsAffected: Integer;
begin
RowsAffected := IProviderSupport(Provider.DataSet).PSExecuteStatement(SQL.Text, Params);
if not (poAllowMultiRecordUpdates in Provider.Options) and (RowsAffected > 1) then
DatabaseError(STooManyRecordsModified);
if RowsAffected < 1 then
DatabaseError(SRecordChanged);
end;

procedure TSQLResolver.DoGetValues(SQL: TStringList;
Params: TParams;
DataSet: TDataSet);
var
DS: TDataSet;
begin
DS := nil;
IProviderSupport(Provider.DataSet).PSExecuteStatement(SQL.Text, Params, @DS);
if Assigned(DS) then
try
TPacketDataSet(DataSet).AssignCurValues(DS)
finally
DS.Free;
end;
end;

procedure TSQLResolver.InternalDoUpdate(Tree: TUpdateTree;
UpdateKind: TUpdateKind);
var
Alias: string;
begin
if not IProviderSupport(Tree.Source).PSUpdateRecord(UpdateKind, Tree.Delta) then
begin
if (PSQLInfo(Tree.Data)^.QuotedTable = '') and not Tree.IsNested then
DatabaseError(SNoTableName);
if PSQLInfo(Tree.Data)^.HasObjects then
Alias := DefAlias else
Alias := '';
FSQL.Clear;
FParams.Clear;
case UpdateKind of
ukModify: GenUpdateSQL(Tree, FSQL, FParams, Alias);
ukInsert: GenInsertSQL(Tree, FSQL, FParams);
ukDelete: GenDeleteSQL(Tree, FSQL, FParams, Alias);
end;
do
ExecSQL(FSQL, FParams);
end;
end;

procedure TSQLResolver.DoUpdate(Tree: TUpdateTree);
begin
InternalDoUpdate(Tree, ukModify);
end;

procedure TSQLResolver.DoDelete(Tree: TUpdateTree);
begin
InternalDoUpdate(Tree, ukDelete);
end;

procedure TSQLResolver.DoInsert(Tree: TUpdateTree);
begin
InternalDoUpdate(Tree, ukInsert);
end;

 
一句话,主要是看看 TDataSetResolver/TSQLResolver的不同实现.
 
太长了,看不懂,能有简单的设置方法说明吗,如果要书写累长的代码,不象李维的作风!
tell me more or simple detail
 
升级到win2000后问题依然,如何办?
 
在升级到win2000甚至MSsql2000下,情况依然,这回是Dllhost.exe提示出同样的问题,为
什么?各位谁能成功地尝试在MTS下的修改?快快帮帮我呀!please..
 
今天很高兴,我的2个问题解决了,是偶然!
只要把adoquery.locktype:=ltOptimistic(默认),datasetprovider.resolveto
dataset:=true;问题解决了,李维的书上相当的肯定adoquery.locktype应设置为
ltBatchOptimistic,也推荐datasetprovider.resolvetodataset:=true,这样的组合是
错误的,我认为,因为这样修改是没效的,而datasetprovider.resolvetodataset:=false;
却会发生我的问题,这也是错误的,似乎李维忽略了这个重要的关节,很害人的。
各位谢谢了,我也歇歇了。
 
后退
顶部