Hi
If you have a look the error trace again:
2008-08-29-10:10:38 2008-08-29-10:10:38 ExceptHandler(EZSQLException: Cannot update a complex query with more then one table, 00521CAD) [00521CAD] ZDbcGenericResolver.TZGenericCachedResolver.DefineTableName (Line 289, "ZDbcGenericResolver.pas")
2008-08-29-10:10:38 2008-08-29-10:10:38 ExceptStackList-----------------------------------------------------------------
ZDbcGenericResolver.TZGenericCachedResolver.DefineTableName (Line 288, "ZDbcGenericResolver.pas")
ZDbcGenericResolver.TZGenericCachedResolver.FormInsertStatement (Line 630, "ZDbcGenericResolver.pas")
ZDbcGenericResolver.TZGenericCachedResolver.PostUpdates (Line 757, "ZDbcGenericResolver.pas")
ZDbcCachedResultSet.TZAbstractCachedResultSet.PostRowUpdates (Line 434, "ZDbcCachedResultSet.pas")
ZDbcCachedResultSet.TZAbstractCachedResultSet.PostUpdates (Line 540, "ZDbcCachedResultSet.pas")
ZDbcCachedResultSet.TZAbstractCachedResultSet.InsertRow (Line 1514, "ZDbcCachedResultSet.pas")
ZAbstractDataset.TZAbstractDataset.InternalAddRecord (Line 414, "ZAbstractDataset.pas")
ZAbstractDataset.TZAbstractDataset.InternalPost (Line 464, "ZAbstractDataset.pas")
DB.TDataSet.CheckOperation (Line 10371, "db.pas")
DB.TDataSet.Post (Line 10228, "db.pas")
ZAbstractDataset.TZAbstractDataset.PSUpdateRecord (Line 788, "ZAbstractDataset.pas")
Provider.TSQLResolver.InternalDoUpdate (Line 3648, "Provider.pas")
Provider.TSQLResolver.DoInsert (Line 3676, "Provider.pas")
Provider.TCustomResolver.InternalUpdateRecord (Line 3241, "Provider.pas")
Provider.TUpdateTree.DoUpdates (Line 3071, "Provider.pas")
Provider.TCustomResolver.ApplyUpdates (Line 3299, "Provider.pas")
Provider.TBaseProvider.InternalApplyUpdates (Line 2250, "Provider.pas")
Provider.TDataSetProvider.InternalApplyUpdates (Line 2656, "Provider.pas")
Provider.TCustomProvider.ApplyUpdates (Line 2092, "Provider.pas")
The except occur when PSUpdateRecord been called in side Provider.TSQLResolver.InternalDoUpdate function:
Code: Select all
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;
DoExecSQL(FSQL, FParams);
end;
end;
In ZeosLib, TZAbstractDataset.PSUpdateRecord try to solve the tablename and form the insert Statement for the ZQuery - as I said, this is a good thing. In IBX, it just do nothing if there has no FOnUpdateReord event and FUpdateObject:
Code: Select all
function TIBCustomDataSet.PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet): Boolean;
...
begin
Result := False;
if Assigned(OnUpdateRecord) then
begin
UpdateAction := uaFail;
if Assigned(FOnUpdateRecord) then
begin
FOnUpdateRecord(Delta, UpdateKind, UpdateAction);
Result := UpdateAction = uaApplied;
end;
end
else if Assigned(FUpdateObject) then
begin
SQL := FUpdateObject.GetSQL(UpdateKind).Text;
if SQL <> '' then
begin
Params := TParams.Create;
try
Params.ParseSQL(SQL, True);
AssignParams(Delta, Params);
if PSExecuteStatement(SQL, Params) = 0 then
IBError(ibxeNoRecordsAffected, [nil]);
Result := True;
finally
Params.Free;
end;
end;
end;
end;
Then let procedure TSQLResolver.GenInsertSQL generate the Sql statement.
I don't regard this as a ZeosLib's bug. As you suggest, adding a TZUpdateSQL can solve this problem. I just wondering how to make ZQuery working with TProvider better.
Cheers,
Tao