1 {*********************************************************}
3 { Zeos Database Objects }
4 { Ado Resultset common functionality }
6 { Originally written by Janos Fegyverneki }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
52 unit ZDbcAdoResultSet;
62 {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},
64 ZClasses, ZSysUtils, ZCollections, ZDbcIntfs,
65 ZDbcGenericResolver, ZDbcCachedResultSet, ZDbcCache, ZDbcResultSet,
66 ZDbcResultsetMetadata, ZCompatibility, ZDbcAdo, ZPlainAdoDriver, ZPlainAdo;
69 {** Implements Ado ResultSet. }
70 TZAdoResultSet = class(TZAbstractResultSet)
72 AdoColTypeCache: TIntegerDynArray;
73 AdoColumnCount: Integer;
75 FAdoRecordSet: ZPlainAdo.RecordSet;
77 procedure Open; override;
79 constructor Create(Statement: IZStatement; SQL: string;
80 AdoRecordSet: ZPlainAdo.RecordSet);
81 destructor Destroy; override;
83 procedure Close; override;
84 function Next: Boolean; override;
85 function MoveAbsolute(Row: Integer): Boolean; override;
86 function GetRow: Integer; override;
87 function IsNull(ColumnIndex: Integer): Boolean; override;
88 function GetString(ColumnIndex: Integer): String; override;
89 function GetUnicodeString(ColumnIndex: Integer): WideString; override;
90 function GetBoolean(ColumnIndex: Integer): Boolean; override;
91 function GetByte(ColumnIndex: Integer): Byte; override;
92 function GetShort(ColumnIndex: Integer): SmallInt; override;
93 function GetInt(ColumnIndex: Integer): Integer; override;
94 function GetLong(ColumnIndex: Integer): Int64; override;
95 function GetFloat(ColumnIndex: Integer): Single; override;
96 function GetDouble(ColumnIndex: Integer): Double; override;
97 function GetBigDecimal(ColumnIndex: Integer): Extended; override;
98 function GetBytes(ColumnIndex: Integer): TByteDynArray; override;
99 function GetDate(ColumnIndex: Integer): TDateTime; override;
100 function GetTime(ColumnIndex: Integer): TDateTime; override;
101 function GetTimestamp(ColumnIndex: Integer): TDateTime; override;
102 function GetBlob(ColumnIndex: Integer): IZBlob; override;
105 {** Implements a cached resolver with Ado specific functionality. }
106 TZAdoCachedResolver = class (TZGenericCachedResolver, IZCachedResolver)
108 FHandle: ZPlainAdo.Command;
109 FAutoColumnIndex: Integer;
111 constructor Create(Handle: ZPlainAdo.Connection;
112 Statement: IZStatement; Metadata: IZResultSetMetadata);
114 procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;
115 OldRowAccessor, NewRowAccessor: TZRowAccessor); override;
121 Variants, Math, OleDB,
122 ZMessages, ZDbcUtils, ZDbcAdoUtils, ZEncoding;
125 Creates this object and assignes the main properties.
126 @param Statement an SQL statement object.
127 @param SQL an SQL query string.
128 @param AdoRecordSet a ADO recordset object, the source of the ResultSet.
130 constructor TZAdoResultSet.Create(Statement: IZStatement; SQL: string; AdoRecordSet: ZPlainAdo.RecordSet);
132 inherited Create(Statement, SQL, nil, Statement.GetConnection.GetConSettings);
133 FAdoRecordSet := AdoRecordSet;
138 Destroys this object and cleanups the memory.
140 destructor TZAdoResultSet.Destroy;
147 Opens this recordset and initializes the Column information.
149 procedure TZAdoResultSet.Open;
151 OleDBRowset: IUnknown;
152 OleDBColumnsInfo: IColumnsInfo;
153 pcColumns: NativeUInt;
154 prgInfo, OriginalprgInfo: PDBColumnInfo;
155 ppStringsBuffer: PWideChar;
158 ColumnInfo: TZColumnInfo;
161 HasAutoIncProp: Boolean;
162 F: ZPlainAdo.Field20;
166 //Check if the current statement can return rows
167 if not Assigned(FAdoRecordSet) or (FAdoRecordSet.State = adStateClosed) then
168 raise EZSQLException.Create(SCanNotRetrieveResultSetData);
170 (FAdoRecordSet as ADORecordsetConstruction).Get_Rowset(OleDBRowset);
171 OleDBRowset.QueryInterface(IColumnsInfo, OleDBColumnsInfo);
173 OleDBColumnsInfo.GetColumnInfo(pcColumns, prgInfo, ppStringsBuffer);
174 OriginalprgInfo := prgInfo;
176 { Fills the column info }
178 AdoColumnCount := FAdoRecordSet.Fields.Count;
179 SetLength(AdoColTypeCache, AdoColumnCount);
181 HasAutoIncProp := False;
182 if AdoColumnCount > 0 then
183 for I := 0 to FAdoRecordSet.Fields.Item[0].Properties.Count - 1 do
184 if FAdoRecordSet.Fields.Item[0].Properties.Item[I].Name = 'ISAUTOINCREMENT' then
186 HasAutoIncProp := True;
190 if Assigned(prgInfo) then
191 if prgInfo.iOrdinal = 0 then
192 Inc(NativeInt(prgInfo), SizeOf(TDBColumnInfo));
194 for I := 0 to AdoColumnCount - 1 do
196 ColumnInfo := TZColumnInfo.Create;
198 F := FAdoRecordSet.Fields.Item[I];
201 ColumnInfo.ColumnLabel := ColName;
202 ColumnInfo.ColumnName := ColName;
203 ColumnInfo.ColumnType := ConvertAdoToSqlType(ColType, ConSettings.CPType);
204 FieldSize := F.DefinedSize;
205 if FieldSize < 0 then
207 if F.Type_ = adGuid then
208 ColumnInfo.ColumnDisplaySize := 38
210 ColumnInfo.ColumnDisplaySize := FieldSize;
211 ColumnInfo.Precision := FieldSize;
212 ColumnInfo.Currency := ColType = adCurrency;
213 ColumnInfo.Signed := False;
215 for J := 0 to F.Properties.Count - 1 do
216 S := S+F.Properties.Item[J].Name + '=' + VarToStr(F.Properties.Item[J].Value) + ', ';
217 if HasAutoIncProp then
218 ColumnInfo.AutoIncrement := F.Properties.Item['ISAUTOINCREMENT'].Value;
219 if ColType in [adTinyInt, adSmallInt, adInteger, adBigInt, adCurrency, adDecimal, adDouble, adNumeric, adSingle] then
220 ColumnInfo.Signed := True;
222 ColumnInfo.Writable := (prgInfo.dwFlags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) <> 0) and (F.Properties.Item['BASECOLUMNNAME'].Value <> null) and not ColumnInfo.AutoIncrement;
223 ColumnInfo.ReadOnly := (prgInfo.dwFlags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) = 0) or ColumnInfo.AutoIncrement;
224 ColumnInfo.Searchable := (prgInfo.dwFlags and DBCOLUMNFLAGS_ISLONG) = 0;
225 if (prgInfo.dwFlags and DBCOLUMNFLAGS_ISLONG) <> 0 then
226 case ColumnInfo.ColumnType of
227 stString: ColumnInfo.ColumnType := stAsciiStream;
228 stUnicodeString: ColumnInfo.ColumnType := stUnicodeStream;
231 ColumnsInfo.Add(ColumnInfo);
233 AdoColTypeCache[I] := ColType;
234 Inc(NativeInt(prgInfo), SizeOf(TDBColumnInfo)); //M.A. Inc(Integer(prgInfo), SizeOf(TDBColumnInfo));
236 if Assigned(ppStringsBuffer) then ZAdoMalloc.Free(ppStringsBuffer);
237 if Assigned(OriginalprgInfo) then ZAdoMalloc.Free(OriginalprgInfo);
243 Releases this <code>ResultSet</code> object's database and
244 ADO resources immediately instead of waiting for
245 this to happen when it is automatically closed.
247 <P><B>Note:</B> A <code>ResultSet</code> object
248 is automatically closed by the
249 <code>Statement</code> object that generated it when
250 that <code>Statement</code> object is closed,
251 re-executed, or is used to retrieve the next result from a
252 sequence of multiple results. A <code>ResultSet</code> object
253 is also automatically closed when it is garbage collected.
255 procedure TZAdoResultSet.Close;
257 FAdoRecordSet := nil;
262 Moves the cursor down one row from its current position.
263 A <code>ResultSet</code> cursor is initially positioned
264 before the first row; the first call to the method
265 <code>next</code> makes the first row the current row; the
266 second call makes the second row the current row, and so on.
268 <P>If an input stream is open for the current row, a call
269 to the method <code>next</code> will
270 implicitly close it. A <code>ResultSet</code> object's
271 warning chain is cleared when a new row is read.
273 @return <code>true</code> if the new current row is valid;
274 <code>false</code> if there are no more rows
276 function TZAdoResultSet.Next: Boolean;
279 if FAdoRecordSet.BOF and FAdoRecordSet.EOF then
281 if FAdoRecordSet.BOF then
282 FAdoRecordSet.MoveFirst
284 if not FAdoRecordSet.EOF and not FFirstFetch then
285 FAdoRecordSet.MoveNext;
286 FFirstFetch := False;
287 Result := not FAdoRecordSet.EOF;
291 Moves the cursor to the given row number in
292 this <code>ResultSet</code> object.
294 <p>If the row number is positive, the cursor moves to
295 the given row number with respect to the
296 beginning of the result set. The first row is row 1, the second
299 <p>If the given row number is negative, the cursor moves to
300 an absolute row position with respect to
301 the end of the result set. For example, calling the method
302 <code>absolute(-1)</code> positions the
303 cursor on the last row; calling the method <code>absolute(-2)</code>
304 moves the cursor to the next-to-last row, and so on.
306 <p>An attempt to position the cursor beyond the first/last row in
307 the result set leaves the cursor before the first row or after
310 <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
311 as calling <code>first()</code>. Calling <code>absolute(-1)</code>
312 is the same as calling <code>last()</code>.
314 @return <code>true</code> if the cursor is on the result set;
315 <code>false</code> otherwise
317 function TZAdoResultSet.MoveAbsolute(Row: Integer): Boolean;
319 if FAdoRecordSet.EOF or FAdoRecordSet.BOF then
320 FAdoRecordSet.MoveFirst;
322 FAdoRecordSet.Move(Row - 1, adBookmarkFirst)
324 FAdoRecordSet.Move(Abs(Row) - 1, adBookmarkLast);
325 Result := not (FAdoRecordSet.EOF or FAdoRecordSet.BOF);
329 Retrieves the current row number. The first row is number 1, the
330 second number 2, and so on.
331 @return the current row number; <code>0</code> if there is no current row
333 function TZAdoResultSet.GetRow: Integer;
335 if FAdoRecordSet.EOF or FAdoRecordSet.BOF then
338 Result := FAdoRecordSet.AbsolutePosition;
342 Indicates if the value of the designated column in the current row
343 of this <code>ResultSet</code> object is Null.
345 @param columnIndex the first column is 1, the second is 2, ...
346 @return if the value is SQL <code>NULL</code>, the
347 value returned is <code>true</code>. <code>false</code> otherwise.
349 function TZAdoResultSet.IsNull(ColumnIndex: Integer): Boolean;
351 Result := VarIsNull(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value) or
352 VarIsEmpty(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value);
356 Gets the value of the designated column in the current row
357 of this <code>ResultSet</code> object as
358 a <code>String</code> in the Java programming language.
360 @param columnIndex the first column is 1, the second is 2, ...
361 @return the column value; if the value is SQL <code>NULL</code>, the
362 value returned is <code>null</code>
364 function TZAdoResultSet.GetString(ColumnIndex: Integer): String;
369 LastWasNull := IsNull(ColumnIndex);
372 if (VarType(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value) = varOleStr)
373 {$IFDEF UNICODE} or ( VarType(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value) = varUString){$ENDIF} then
374 Result := ZDbcString(ZWideString(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value))
376 Result := ZDbcString(AnsiString(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value))
377 {Why this? It cuts wanted trailing spaces!
378 NL := Length(Result);
379 while (NL > 0) and (Result[NL] = ' ') do Dec(NL);
380 SetLength(Result, NL);}
384 Gets the value of the designated column in the current row
385 of this <code>ResultSet</code> object as
386 a <code>WideString</code> in the Delphi programming language.
388 @param columnIndex the first column is 1, the second is 2, ...
389 @return the column value; if the value is SQL <code>NULL</code>, the
390 value returned is <code>null</code>
392 function TZAdoResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;
397 LastWasNull := IsNull(ColumnIndex);
400 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
401 {Why this? It cuts wanted trailing spaces!
402 NL := Length(Result);
403 while (NL > 0) and (Result[NL] = ' ') do
405 SetLength(Result, NL);}
409 Gets the value of the designated column in the current row
410 of this <code>ResultSet</code> object as
411 a <code>boolean</code> in the Java programming language.
413 @param columnIndex the first column is 1, the second is 2, ...
414 @return the column value; if the value is SQL <code>NULL</code>, the
415 value returned is <code>false</code>
417 function TZAdoResultSet.GetBoolean(ColumnIndex: Integer): Boolean;
420 LastWasNull := IsNull(ColumnIndex);
424 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
431 Gets the value of the designated column in the current row
432 of this <code>ResultSet</code> object as
433 a <code>byte</code> in the Java programming language.
435 @param columnIndex the first column is 1, the second is 2, ...
436 @return the column value; if the value is SQL <code>NULL</code>, the
437 value returned is <code>0</code>
439 function TZAdoResultSet.GetByte(ColumnIndex: Integer): Byte;
442 LastWasNull := IsNull(ColumnIndex);
446 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
453 Gets the value of the designated column in the current row
454 of this <code>ResultSet</code> object as
455 a <code>short</code> in the Java programming language.
457 @param columnIndex the first column is 1, the second is 2, ...
458 @return the column value; if the value is SQL <code>NULL</code>, the
459 value returned is <code>0</code>
461 function TZAdoResultSet.GetShort(ColumnIndex: Integer): SmallInt;
464 LastWasNull := IsNull(ColumnIndex);
468 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
475 Gets the value of the designated column in the current row
476 of this <code>ResultSet</code> object as
477 an <code>int</code> in the Java programming language.
479 @param columnIndex the first column is 1, the second is 2, ...
480 @return the column value; if the value is SQL <code>NULL</code>, the
481 value returned is <code>0</code>
483 function TZAdoResultSet.GetInt(ColumnIndex: Integer): Integer;
486 LastWasNull := IsNull(ColumnIndex);
490 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
497 Gets the value of the designated column in the current row
498 of this <code>ResultSet</code> object as
499 a <code>long</code> in the Java programming language.
501 @param columnIndex the first column is 1, the second is 2, ...
502 @return the column value; if the value is SQL <code>NULL</code>, the
503 value returned is <code>0</code>
505 function TZAdoResultSet.GetLong(ColumnIndex: Integer): Int64;
508 LastWasNull := IsNull(ColumnIndex);
512 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
519 Gets the value of the designated column in the current row
520 of this <code>ResultSet</code> object as
521 a <code>float</code> in the Java programming language.
523 @param columnIndex the first column is 1, the second is 2, ...
524 @return the column value; if the value is SQL <code>NULL</code>, the
525 value returned is <code>0</code>
527 function TZAdoResultSet.GetFloat(ColumnIndex: Integer): Single;
530 LastWasNull := IsNull(ColumnIndex);
534 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
541 Gets the value of the designated column in the current row
542 of this <code>ResultSet</code> object as
543 a <code>double</code> in the Java programming language.
545 @param columnIndex the first column is 1, the second is 2, ...
546 @return the column value; if the value is SQL <code>NULL</code>, the
547 value returned is <code>0</code>
549 function TZAdoResultSet.GetDouble(ColumnIndex: Integer): Double;
552 LastWasNull := IsNull(ColumnIndex);
556 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
563 Gets the value of the designated column in the current row
564 of this <code>ResultSet</code> object as
565 a <code>java.sql.BigDecimal</code> in the Java programming language.
567 @param columnIndex the first column is 1, the second is 2, ...
568 @param scale the number of digits to the right of the decimal point
569 @return the column value; if the value is SQL <code>NULL</code>, the
570 value returned is <code>null</code>
572 function TZAdoResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;
575 LastWasNull := IsNull(ColumnIndex);
579 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
586 Gets the value of the designated column in the current row
587 of this <code>ResultSet</code> object as
588 a <code>byte</code> array in the Java programming language.
589 The bytes represent the raw values returned by the driver.
591 @param columnIndex the first column is 1, the second is 2, ...
592 @return the column value; if the value is SQL <code>NULL</code>, the
593 value returned is <code>null</code>
595 function TZAdoResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;
600 SetLength(Result, 0);
601 LastWasNull := IsNull(ColumnIndex);
604 V := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
605 if VarType(V) = varByte then
608 if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType = stGUID then
610 SetLength(Result, 16);
611 GUID := StringToGUID(V);
612 System.Move(Pointer(@GUID)^, Pointer(Result)^, 16);
619 Gets the value of the designated column in the current row
620 of this <code>ResultSet</code> object as
621 a <code>java.sql.Date</code> object in the Java programming language.
623 @param columnIndex the first column is 1, the second is 2, ...
624 @return the column value; if the value is SQL <code>NULL</code>, the
625 value returned is <code>null</code>
627 function TZAdoResultSet.GetDate(ColumnIndex: Integer): TDateTime;
630 LastWasNull := IsNull(ColumnIndex);
634 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
641 Gets the value of the designated column in the current row
642 of this <code>ResultSet</code> object as
643 a <code>java.sql.Time</code> object in the Java programming language.
645 @param columnIndex the first column is 1, the second is 2, ...
646 @return the column value; if the value is SQL <code>NULL</code>, the
647 value returned is <code>null</code>
649 function TZAdoResultSet.GetTime(ColumnIndex: Integer): TDateTime;
652 LastWasNull := IsNull(ColumnIndex);
656 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
663 Gets the value of the designated column in the current row
664 of this <code>ResultSet</code> object as
665 a <code>java.sql.Timestamp</code> object in the Java programming language.
667 @param columnIndex the first column is 1, the second is 2, ...
668 @return the column value; if the value is SQL <code>NULL</code>, the
669 value returned is <code>null</code>
670 @exception SQLException if a database access error occurs
672 function TZAdoResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;
675 LastWasNull := IsNull(ColumnIndex);
679 Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
686 Returns the value of the designated column in the current row
687 of this <code>ResultSet</code> object as a <code>Blob</code> object
688 in the Java programming language.
690 @param ColumnIndex the first column is 1, the second is 2, ...
691 @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in
694 function TZAdoResultSet.GetBlob(ColumnIndex: Integer): IZBlob;
700 LastWasNull := IsNull(ColumnIndex);
704 V := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;
705 if VarIsStr(V) {$IFDEF UNICODE} or ( VarType(V) = varUString){$ENDIF} then
707 Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);
708 case GetMetadata.GetColumnType(ColumnIndex) of
710 if (VarType(V) = varOleStr) {$IFDEF UNICODE} or ( VarType(V) = varUString){$ENDIF} then
711 if ConSettings^.AutoEncode then
712 if ConSettings^.CPType = cCP_UTF8 then
713 Result.SetString(UTF8Encode(V))
715 Result.SetString(AnsiString(V))
717 Result.SetString(AnsiString(V))
719 Result.SetString(GetValidatedAnsiString(V, ConSettings, True));
721 Result.SetUnicodeString(WideString(V));
723 Result.SetString(RawByteString(V));
726 if VarIsArray(V) then
728 P := VarArrayLock(V);
730 Result := TZAbstractBlob.CreateWithData(P, VarArrayHighBound(V, 1)+1, GetStatement.GetConnection);
738 { TZAdoCachedResolver }
741 Creates a Ado specific cached resolver object.
742 @param PlainDriver a native Ado plain driver.
743 @param Handle a Ado specific query handle.
744 @param Statement a related SQL statement object.
745 @param Metadata a resultset metadata reference.
747 constructor TZAdoCachedResolver.Create(Handle: ZPlainAdo.Connection;
748 Statement: IZStatement; Metadata: IZResultSetMetadata);
752 inherited Create(Statement, Metadata);
753 FHandle := ZPlainAdo.CoCommand.Create;
754 FHandle._Set_ActiveConnection(Handle);
755 FHandle.CommandText := 'SELECT @@IDENTITY';
756 FHandle.CommandType := adCmdText;
758 { Defines an index of autoincrement field. }
759 FAutoColumnIndex := 0;
760 for I := 1 to Metadata.GetColumnCount do
762 if Metadata.IsAutoIncrement(I) and
763 (Metadata.GetColumnType(I) in [stByte, stShort, stInteger, stLong]) then
765 FAutoColumnIndex := I;
772 Posts updates to database.
773 @param Sender a cached result set object.
774 @param UpdateType a type of updates.
775 @param OldRowAccessor an accessor object to old column values.
776 @param NewRowAccessor an accessor object to new column values.
778 procedure TZAdoCachedResolver.PostUpdates(Sender: IZCachedResultSet;
779 UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);
781 Recordset: ZPlainAdo.Recordset;
784 inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor);
786 if (UpdateType = utInserted) and (FAutoColumnIndex > 0)
787 and OldRowAccessor.IsNull(FAutoColumnIndex) then
789 Recordset := FHandle.Execute(RA, null, 0);
790 if Recordset.RecordCount > 0 then
791 NewRowAccessor.SetLong(FAutoColumnIndex, Recordset.Fields.Item[0].Value);