1 {*********************************************************}
3 { Zeos Database Objects }
4 { Abstract Database Connectivity Classes }
6 { Originally written by Sergey Seroukhov }
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 {********************************************************@}
59 Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,
60 ZDbcIntfs, ZTokenizer, ZCompatibility, ZVariant, ZDbcLogging, ZClasses,
64 TZSQLTypeArray = array of TZSQLType;
66 {** Implements Abstract Generic SQL Statement. }
68 { TZAbstractStatement }
70 TZAbstractStatement = class(TZCodePagedObject, IZStatement)
72 FMaxFieldSize: Integer;
74 FEscapeProcessing: Boolean;
75 FQueryTimeout: Integer;
76 FLastUpdateCount: Integer;
77 FLastResultSet: IZResultSet;
78 FFetchDirection: TZFetchDirection;
80 FResultSetConcurrency: TZResultSetConcurrency;
81 FResultSetType: TZResultSetType;
82 FPostUpdates: TZPostUpdatesMode;
83 FLocateUpdates: TZLocateUpdatesMode;
84 FCursorName: AnsiString;
85 FBatchQueries: TStrings;
86 FConnection: IZConnection;
88 FChunkSize: Integer; //size of buffer chunks for large lob's related to network settings
92 FIsAnsiDriver: Boolean;
93 procedure SetLastResultSet(ResultSet: IZResultSet); virtual;
95 procedure SetASQL(const Value: RawByteString); virtual;
96 procedure SetWSQL(const Value: ZWideString); virtual;
97 class function GetNextStatementId : integer;
98 procedure RaiseUnsupportedException;
100 property MaxFieldSize: Integer read FMaxFieldSize write FMaxFieldSize;
101 property MaxRows: Integer read FMaxRows write FMaxRows;
102 property EscapeProcessing: Boolean
103 read FEscapeProcessing write FEscapeProcessing;
104 property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout;
105 property LastUpdateCount: Integer
106 read FLastUpdateCount write FLastUpdateCount;
107 property LastResultSet: IZResultSet
108 read FLastResultSet write SetLastResultSet;
109 property FetchDirection: TZFetchDirection
110 read FFetchDirection write FFetchDirection;
111 property FetchSize: Integer read FFetchSize write FFetchSize;
112 property ResultSetConcurrency: TZResultSetConcurrency
113 read FResultSetConcurrency write FResultSetConcurrency;
114 property ResultSetType: TZResultSetType
115 read FResultSetType write FResultSetType;
116 property CursorName: AnsiString read FCursorName write FCursorName;
117 property BatchQueries: TStrings read FBatchQueries;
118 property Connection: IZConnection read FConnection;
119 property Info: TStrings read FInfo;
120 property Closed: Boolean read FClosed write FClosed;
122 {EgonHugeist SSQL only because of compatibility to the old code available}
123 property SSQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND} read {$IFDEF UNICODE}FWSQL{$ELSE}FaSQL{$ENDIF} write {$IFDEF UNICODE}SetWSQL{$ELSE}SetASQL{$ENDIF};
124 property WSQL: ZWideString read FWSQL write SetWSQL;
125 property ASQL: RawByteString read FaSQL write SetASQL;
126 property LogSQL: String read {$IFDEF UNICODE}FWSQL{$ELSE}FaSQL{$ENDIF};
127 property ChunkSize: Integer read FChunkSize;
128 property IsAnsiDriver: Boolean read FIsAnsiDriver;
130 constructor Create(Connection: IZConnection; Info: TStrings);
131 destructor Destroy; override;
133 function ExecuteQuery(const SQL: ZWideString): IZResultSet; overload; virtual;
134 function ExecuteUpdate(const SQL: ZWideString): Integer; overload; virtual;
135 function Execute(const SQL: ZWideString): Boolean; overload; virtual;
137 function ExecuteQuery(const SQL: RawByteString): IZResultSet; overload; virtual;
138 function ExecuteUpdate(const SQL: RawByteString): Integer; overload; virtual;
139 function Execute(const SQL: RawByteString): Boolean; overload; virtual;
141 procedure Close; virtual;
143 function GetMaxFieldSize: Integer; virtual;
144 procedure SetMaxFieldSize(Value: Integer); virtual;
145 function GetMaxRows: Integer; virtual;
146 procedure SetMaxRows(Value: Integer); virtual;
147 procedure SetEscapeProcessing(Value: Boolean); virtual;
148 function GetQueryTimeout: Integer; virtual;
149 procedure SetQueryTimeout(Value: Integer); virtual;
150 procedure Cancel; virtual;
151 procedure SetCursorName(const Value: AnsiString); virtual;
153 function GetResultSet: IZResultSet; virtual;
154 function GetUpdateCount: Integer; virtual;
155 function GetMoreResults: Boolean; virtual;
157 procedure SetFetchDirection(Value: TZFetchDirection); virtual;
158 function GetFetchDirection: TZFetchDirection; virtual;
159 procedure SetFetchSize(Value: Integer); virtual;
160 function GetFetchSize: Integer; virtual;
162 procedure SetResultSetConcurrency(Value: TZResultSetConcurrency); virtual;
163 function GetResultSetConcurrency: TZResultSetConcurrency; virtual;
164 procedure SetResultSetType(Value: TZResultSetType); virtual;
165 function GetResultSetType: TZResultSetType; virtual;
167 procedure SetPostUpdates(Value: TZPostUpdatesMode);
168 function GetPostUpdates: TZPostUpdatesMode;
169 procedure SetLocateUpdates(Value: TZLocateUpdatesMode);
170 function GetLocateUpdates: TZLocateUpdatesMode;
172 procedure AddBatch(const SQL: string); virtual;
173 procedure ClearBatch; virtual;
174 function ExecuteBatch: TIntegerDynArray; virtual;
176 function GetConnection: IZConnection;
177 function GetParameters: TStrings;
178 function GetChunkSize: Integer;
180 function GetWarnings: EZSQLWarning; virtual;
181 procedure ClearWarnings; virtual;
182 function GetEncodedSQL(const SQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND}): RawByteString; virtual;
185 {** Implements Abstract Prepared SQL Statement. }
187 { TZAbstractPreparedStatement }
189 TZAbstractPreparedStatement = class(TZAbstractStatement, IZPreparedStatement)
192 FInParamValues: TZVariantDynArray;
193 FInParamTypes: TZSQLTypeArray;
194 FInParamDefaultValues: TStringDynArray;
195 FInParamCount: Integer;
199 FStatementId : Integer;
200 procedure PrepareInParameters; virtual;
201 procedure BindInParameters; virtual;
202 procedure UnPrepareInParameters; virtual;
204 procedure SetInParamCount(NewParamCount: Integer); virtual;
205 procedure SetInParam(ParameterIndex: Integer; SQLType: TZSQLType;
206 const Value: TZVariant); virtual;
207 procedure LogPrepStmtMessage(Category: TZLoggingCategory; const Msg: string = '');
208 function GetInParamLogValue(Value: TZVariant): String;
210 property ExecCount: Integer read FExecCount;
211 property SQL: string read FSQL write FSQL;
212 property InParamValues: TZVariantDynArray
213 read FInParamValues write FInParamValues;
214 property InParamTypes: TZSQLTypeArray
215 read FInParamTypes write FInParamTypes;
216 property InParamDefaultValues: TStringDynArray
217 read FInParamDefaultValues write FInParamDefaultValues;
218 property InParamCount: Integer read FInParamCount write FInParamCount;
220 constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);
221 destructor Destroy; override;
223 function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;
224 function ExecuteUpdate(const SQL: ZWideString): Integer; override;
225 function Execute(const SQL: ZWideString): Boolean; override;
227 function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;
228 function ExecuteUpdate(const SQL: RawByteString): Integer; override;
229 function Execute(const SQL: RawByteString): Boolean; override;
231 function ExecuteQueryPrepared: IZResultSet; virtual;
232 function ExecuteUpdatePrepared: Integer; virtual;
233 function ExecutePrepared: Boolean; virtual;
235 function GetSQL : String;
236 procedure Prepare; virtual;
237 procedure Unprepare; virtual;
238 function IsPrepared: Boolean; virtual;
239 property Prepared: Boolean read IsPrepared;
241 procedure SetDefaultValue(ParameterIndex: Integer; const Value: string);
243 procedure SetNull(ParameterIndex: Integer; SQLType: TZSQLType); virtual;
244 procedure SetBoolean(ParameterIndex: Integer; Value: Boolean); virtual;
245 procedure SetByte(ParameterIndex: Integer; Value: Byte); virtual;
246 procedure SetShort(ParameterIndex: Integer; Value: SmallInt); virtual;
247 procedure SetInt(ParameterIndex: Integer; Value: Integer); virtual;
248 procedure SetLong(ParameterIndex: Integer; Value: Int64); virtual;
249 procedure SetFloat(ParameterIndex: Integer; Value: Single); virtual;
250 procedure SetDouble(ParameterIndex: Integer; Value: Double); virtual;
251 procedure SetBigDecimal(ParameterIndex: Integer; Value: Extended); virtual;
252 procedure SetPChar(ParameterIndex: Integer; Value: PChar); virtual;
253 procedure SetString(ParameterIndex: Integer; const Value: String); virtual;
254 procedure SetUnicodeString(ParameterIndex: Integer; const Value: ZWideString); virtual; //AVZ
255 procedure SetBytes(ParameterIndex: Integer; const Value: TByteDynArray); virtual;
256 procedure SetDate(ParameterIndex: Integer; Value: TDateTime); virtual;
257 procedure SetTime(ParameterIndex: Integer; Value: TDateTime); virtual;
258 procedure SetTimestamp(ParameterIndex: Integer; Value: TDateTime); virtual;
259 procedure SetAsciiStream(ParameterIndex: Integer; Value: TStream); virtual;
260 procedure SetUnicodeStream(ParameterIndex: Integer; Value: TStream); virtual;
261 procedure SetBinaryStream(ParameterIndex: Integer; Value: TStream); virtual;
262 procedure SetBlob(ParameterIndex: Integer; SQLType: TZSQLType; Value: IZBlob); virtual;
263 procedure SetValue(ParameterIndex: Integer; const Value: TZVariant); virtual;
265 procedure ClearParameters; virtual;
267 procedure AddBatchPrepared; virtual;
268 function GetMetaData: IZResultSetMetaData; virtual;
271 {** Implements Abstract Callable SQL statement. }
272 TZAbstractCallableStatement = class(TZAbstractPreparedStatement,
275 FOutParamValues: TZVariantDynArray;
276 FOutParamTypes: TZSQLTypeArray;
277 FOutParamCount: Integer;
278 FLastWasNull: Boolean;
281 FIsFunction: Boolean;
282 FHasOutParameter: Boolean;
284 FResultSets: IZCollection;
285 FActiveResultset: Integer;
286 FDBParamTypes: array of ShortInt;
287 procedure ClearResultSets; virtual;
288 procedure TrimInParameters; virtual;
289 procedure SetOutParamCount(NewParamCount: Integer); virtual;
290 function GetOutParam(ParameterIndex: Integer): TZVariant; virtual;
291 procedure SetProcSQL(const Value: String); virtual;
293 property OutParamValues: TZVariantDynArray
294 read FOutParamValues write FOutParamValues;
295 property OutParamTypes: TZSQLTypeArray
296 read FOutParamTypes write FOutParamTypes;
297 property OutParamCount: Integer read FOutParamCount write FOutParamCount;
298 property LastWasNull: Boolean read FLastWasNull write FLastWasNull;
299 property ProcSql: String read FProcSQL write SetProcSQL;
301 constructor Create(Connection: IZConnection; SQL: string; Info: TStrings);
302 procedure ClearParameters; override;
303 procedure Close; override;
305 function IsFunction: Boolean;
306 function HasOutParameter: Boolean;
307 function HasMoreResultSets: Boolean; virtual;
308 function GetFirstResultSet: IZResultSet; virtual;
309 function GetPreviousResultSet: IZResultSet; virtual;
310 function GetNextResultSet: IZResultSet; virtual;
311 function GetLastResultSet: IZResultSet; virtual;
312 function BOR: Boolean; virtual;
313 function EOR: Boolean; virtual;
314 function GetResultSetByIndex(const Index: Integer): IZResultSet; virtual;
315 function GetResultSetCount: Integer; virtual;
317 procedure RegisterOutParameter(ParameterIndex: Integer;
318 SQLType: Integer); virtual;
319 procedure RegisterParamType(ParameterIndex:integer;ParamType:Integer);virtual;
320 function WasNull: Boolean; virtual;
322 function IsNull(ParameterIndex: Integer): Boolean; virtual;
323 function GetPChar(ParameterIndex: Integer): PChar; virtual;
324 function GetString(ParameterIndex: Integer): String; virtual;
325 function GetUnicodeString(ParameterIndex: Integer): WideString; virtual;
326 function GetBoolean(ParameterIndex: Integer): Boolean; virtual;
327 function GetByte(ParameterIndex: Integer): Byte; virtual;
328 function GetShort(ParameterIndex: Integer): SmallInt; virtual;
329 function GetInt(ParameterIndex: Integer): Integer; virtual;
330 function GetLong(ParameterIndex: Integer): Int64; virtual;
331 function GetFloat(ParameterIndex: Integer): Single; virtual;
332 function GetDouble(ParameterIndex: Integer): Double; virtual;
333 function GetBigDecimal(ParameterIndex: Integer): Extended; virtual;
334 function GetBytes(ParameterIndex: Integer): TByteDynArray; virtual;
335 function GetDate(ParameterIndex: Integer): TDateTime; virtual;
336 function GetTime(ParameterIndex: Integer): TDateTime; virtual;
337 function GetTimestamp(ParameterIndex: Integer): TDateTime; virtual;
338 function GetValue(ParameterIndex: Integer): TZVariant; virtual;
341 {** Implements a real Prepared Callable SQL Statement. }
342 TZAbstractPreparedCallableStatement = CLass(TZAbstractCallableStatement)
344 procedure SetProcSQL(const Value: String); override;
346 function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;
347 function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;
348 function ExecuteUpdate(const SQL: ZWideString): Integer; override;
349 function ExecuteUpdate(const SQL: RawByteString): Integer; override;
350 function Execute(const SQL: ZWideString): Boolean; override;
351 function Execute(const SQL: RawByteString): Boolean; override;
354 {** Implements an Emulated Prepared SQL Statement. }
355 TZEmulatedPreparedStatement = class(TZAbstractPreparedStatement)
357 FExecStatement: IZStatement;
358 FCachedQuery: TStrings;
359 FLastStatement: IZStatement;
360 procedure SetLastStatement(LastStatement: IZStatement);
362 FNeedNCharDetection: Boolean;
363 property ExecStatement: IZStatement read FExecStatement write FExecStatement;
364 property CachedQuery: TStrings read FCachedQuery write FCachedQuery;
365 property LastStatement: IZStatement read FLastStatement write SetLastStatement;
367 function CreateExecStatement: IZStatement; virtual; abstract;
368 function PrepareWideSQLParam(ParamIndex: Integer): ZWideString; virtual;
369 function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString; virtual;
370 function GetExecStatement: IZStatement;
371 function TokenizeSQLQuery: TStrings;
372 function PrepareWideSQLQuery: ZWideString; virtual;
373 function PrepareAnsiSQLQuery: RawByteString; virtual;
375 destructor Destroy; override;
377 procedure Close; override;
379 function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;
380 function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;
381 function ExecuteUpdate(const SQL: ZWideString): Integer; override;
382 function ExecuteUpdate(const SQL: RawByteString): Integer; override;
383 function Execute(const SQL: ZWideString): Boolean; override;
384 function Execute(const SQL: RawByteString): Boolean; override;
386 function ExecuteQueryPrepared: IZResultSet; override;
387 function ExecuteUpdatePrepared: Integer; override;
388 function ExecutePrepared: Boolean; override;
393 uses ZSysUtils, ZMessages, ZDbcResultSet, ZCollections;
397 Holds the value of the last assigned statement ID.
398 Only Accessible using TZAbstractStatement.GetNextStatementId.
400 GlobalStatementIdCounter : integer;
402 { TZAbstractStatement }
405 Constructs this class and defines the main properties.
406 @param Connection a database connection object.
407 @param Info a statement parameters;
409 constructor TZAbstractStatement.Create(Connection: IZConnection; Info: TStrings);
411 { Sets the default properties. }
413 ConSettings := Connection.GetConSettings;
416 FEscapeProcessing := False;
418 FLastUpdateCount := -1;
419 FLastResultSet := nil;
420 FFetchDirection := fdForward;
422 FResultSetConcurrency := rcReadOnly;
423 FResultSetType := rtForwardOnly;
426 FConnection := Connection;
427 FBatchQueries := TStringList.Create;
429 FInfo := TStringList.Create;
431 FInfo.AddStrings(Info);
432 if FInfo.Values['chunk_size'] = '' then
433 FChunkSize := StrToIntDef(Connection.GetParameters.Values['chunk_size'], 4096)
435 FChunkSize := StrToIntDef(FInfo.Values['chunk_size'], 4096);
437 FIsAnsiDriver := Connection.GetIZPlainDriver.IsAnsiDriver;
441 Destroys this object and cleanups the memory.
443 destructor TZAbstractStatement.Destroy;
446 if Assigned(FBatchQueries) then
447 FreeAndNil(FBatchQueries);
450 FLastResultSet := nil;
455 Sets the preprepared SQL-Statement in an String and AnsiStringForm.
456 @param Value: the SQL-String which has to be optional preprepared
458 procedure TZAbstractStatement.SetWSQL(const Value: ZWideString);
460 if FWSQL <> Value then
463 FaSQL := GetEncodedSQL(Value);
465 FaSQL := ZPlainString(Value);
467 FWSQL := ZDbcUnicodeString(FASQL, ConSettings^.ClientCodePage^.CP);;
471 procedure TZAbstractStatement.SetASQL(const Value: RawByteString);
473 if FASQL <> Value then
476 FASQL := GetEncodedSQL(Value);
477 FWSQL := ZDbcUnicodeString(FASQL, ConSettings^.ClientCodePage^.CP);
480 FWSQL := ZDbcString(Value);
486 Raises unsupported operation exception.
488 procedure TZAbstractStatement.RaiseUnsupportedException;
490 raise EZSQLException.Create(SUnsupportedOperation);
494 Sets a last result set to avoid problems with reference counting.
495 @param ResultSet the lastest executed result set.
497 procedure TZAbstractStatement.SetLastResultSet(ResultSet: IZResultSet);
499 if (FLastResultSet <> nil) then
500 FLastResultSet.Close;
502 FLastResultSet := ResultSet;
505 class function TZAbstractStatement.GetNextStatementId: integer;
507 Inc(GlobalStatementIdCounter);
508 Result := GlobalStatementIdCounter;
512 Executes an SQL statement that returns a single <code>ResultSet</code> object.
513 @param sql typically this is a static SQL <code>SELECT</code> statement
514 @return a <code>ResultSet</code> object that contains the data produced by the
515 given query; never <code>null</code>
517 function TZAbstractStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;
520 Result := ExecuteQuery(ASQL);
523 function TZAbstractStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;
526 RaiseUnsupportedException;
530 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
531 <code>DELETE</code> statement. In addition,
532 SQL statements that return nothing, such as SQL DDL statements,
535 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
536 <code>DELETE</code> statement or an SQL statement that returns nothing
537 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
538 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
540 function TZAbstractStatement.ExecuteUpdate(const SQL: ZWideString): Integer;
543 Result := ExecuteUpdate(ASQL);
546 function TZAbstractStatement.ExecuteUpdate(const SQL: RawByteString): Integer;
549 RaiseUnsupportedException;
553 Releases this <code>Statement</code> object's database
554 and JDBC resources immediately instead of waiting for
555 this to happen when it is automatically closed.
556 It is generally good practice to release resources as soon as
557 you are finished with them to avoid tying up database
559 <P><B>Note:</B> A <code>Statement</code> object is automatically closed when it is
560 garbage collected. When a <code>Statement</code> object is closed, its current
561 <code>ResultSet</code> object, if one exists, is also closed.
563 procedure TZAbstractStatement.Close;
565 if LastResultSet <> nil then
568 LastResultSet := nil;
574 Returns the maximum number of bytes allowed
575 for any column value.
576 This limit is the maximum number of bytes that can be
577 returned for any column value.
578 The limit applies only to <code>BINARY</code>,
579 <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and <code>LONGVARCHAR</code>
580 columns. If the limit is exceeded, the excess data is silently
582 @return the current max column size limit; zero means unlimited
584 function TZAbstractStatement.GetMaxFieldSize: Integer;
586 Result := FMaxFieldSize;
590 Sets the limit for the maximum number of bytes in a column to
591 the given number of bytes. This is the maximum number of bytes
592 that can be returned for any column value. This limit applies
593 only to <code>BINARY</code>, <code>VARBINARY</code>,
594 <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and
595 <code>LONGVARCHAR</code> fields. If the limit is exceeded, the excess data
596 is silently discarded. For maximum portability, use values
599 @param max the new max column size limit; zero means unlimited
601 procedure TZAbstractStatement.SetMaxFieldSize(Value: Integer);
603 FMaxFieldSize := Value;
607 Retrieves the maximum number of rows that a
608 <code>ResultSet</code> object can contain. If the limit is exceeded, the excess
609 rows are silently dropped.
611 @return the current max row limit; zero means unlimited
613 function TZAbstractStatement.GetMaxRows: Integer;
619 Sets the limit for the maximum number of rows that any
620 <code>ResultSet</code> object can contain to the given number.
621 If the limit is exceeded, the excess rows are silently dropped.
623 @param max the new max rows limit; zero means unlimited
625 procedure TZAbstractStatement.SetMaxRows(Value: Integer);
631 Sets escape processing on or off.
632 If escape scanning is on (the default), the driver will do
633 escape substitution before sending the SQL to the database.
635 Note: Since prepared statements have usually been parsed prior
636 to making this call, disabling escape processing for prepared
637 statements will have no effect.
639 @param enable <code>true</code> to enable; <code>false</code> to disable
641 procedure TZAbstractStatement.SetEscapeProcessing(Value: Boolean);
643 FEscapeProcessing := Value;
647 Retrieves the number of seconds the driver will
648 wait for a <code>Statement</code> object to execute. If the limit is exceeded, a
649 <code>SQLException</code> is thrown.
651 @return the current query timeout limit in seconds; zero means unlimited
653 function TZAbstractStatement.GetQueryTimeout: Integer;
655 Result := FQueryTimeout;
659 Sets the number of seconds the driver will
660 wait for a <code>Statement</code> object to execute to the given number of seconds.
661 If the limit is exceeded, an <code>SQLException</code> is thrown.
663 @param seconds the new query timeout limit in seconds; zero means unlimited
665 procedure TZAbstractStatement.SetQueryTimeout(Value: Integer);
667 FQueryTimeout := Value;
671 Cancels this <code>Statement</code> object if both the DBMS and
672 driver support aborting an SQL statement.
673 This method can be used by one thread to cancel a statement that
674 is being executed by another thread.
676 procedure TZAbstractStatement.Cancel;
678 RaiseUnsupportedException;
682 Retrieves the first warning reported by calls on this <code>Statement</code> object.
683 Subsequent <code>Statement</code> object warnings will be chained to this
684 <code>SQLWarning</code> object.
686 <p>The warning chain is automatically cleared each time
687 a statement is (re)executed.
689 <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
690 warnings associated with reads on that <code>ResultSet</code> object
691 will be chained on it.
693 @return the first <code>SQLWarning</code> object or <code>null</code>
695 function TZAbstractStatement.GetWarnings: EZSQLWarning;
701 Clears all the warnings reported on this <code>Statement</code>
702 object. After a call to this method,
703 the method <code>getWarnings</code> will return
704 <code>null</code> until a new warning is reported for this
705 <code>Statement</code> object.
707 procedure TZAbstractStatement.ClearWarnings;
711 function TZAbstractStatement.GetEncodedSQL(const SQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND}): RawByteString;
713 SQLTokens: TZTokenDynArray;
716 if GetConnection.AutoEncodeStrings then
718 Result := ''; //init for FPC
719 SQLTokens := GetConnection.GetDriver.GetTokenizer.TokenizeBuffer(SQL, [toSkipEOF]); //Disassembles the Query
720 for i := Low(SQLTokens) to high(SQLTokens) do //Assembles the Query
722 case (SQLTokens[i].TokenType) of
724 Result := Result + {$IFDEF UNICODE}ZPlainString{$ENDIF}(SQLTokens[i].Value);
726 ttWord, ttQuotedIdentifier, ttKeyword:
727 Result := Result + ZPlainString(SQLTokens[i].Value);
729 Result := Result + RawByteString(SQLTokens[i].Value);
735 Result := ZPlainString(SQL);
742 Defines the SQL cursor name that will be used by
743 subsequent <code>Statement</code> object <code>execute</code> methods.
744 This name can then be
745 used in SQL positioned update/delete statements to identify the
746 current row in the <code>ResultSet</code> object generated by this statement. If
747 the database doesn't support positioned update/delete, this
748 method is a noop. To insure that a cursor has the proper isolation
749 level to support updates, the cursor's <code>SELECT</code> statement should be
750 of the form 'select for update ...'. If the 'for update' phrase is
751 omitted, positioned updates may fail.
753 <P><B>Note:</B> By definition, positioned update/delete
754 execution must be done by a different <code>Statement</code> object than the one
755 which generated the <code>ResultSet</code> object being used for positioning. Also,
756 cursor names must be unique within a connection.
758 @param name the new cursor name, which must be unique within a connection
760 procedure TZAbstractStatement.SetCursorName(const Value: AnsiString);
762 FCursorName := Value;
766 Executes an SQL statement that may return multiple results.
767 Under some (uncommon) situations a single SQL statement may return
768 multiple result sets and/or update counts. Normally you can ignore
769 this unless you are (1) executing a stored procedure that you know may
770 return multiple results or (2) you are dynamically executing an
771 unknown SQL string. The methods <code>execute</code>,
772 <code>getMoreResults</code>, <code>getResultSet</code>,
773 and <code>getUpdateCount</code> let you navigate through multiple results.
775 The <code>execute</code> method executes an SQL statement and indicates the
776 form of the first result. You can then use the methods
777 <code>getResultSet</code> or <code>getUpdateCount</code>
778 to retrieve the result, and <code>getMoreResults</code> to
779 move to any subsequent result(s).
781 @param sql any SQL statement
782 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
783 <code>false</code> if it is an update count or there are no more results
788 function TZAbstractStatement.Execute(const SQL: ZWideString): Boolean;
791 Result := Execute(ASQL);
794 function TZAbstractStatement.Execute(const SQL: RawByteString): Boolean;
797 LastResultSet := nil;
798 LastUpdateCount := -1;
802 Returns the current result as a <code>ResultSet</code> object.
803 This method should be called only once per result.
805 @return the current result as a <code>ResultSet</code> object;
806 <code>null</code> if the result is an update count or there are no more results
809 function TZAbstractStatement.GetResultSet: IZResultSet;
811 Result := LastResultSet;
815 Returns the current result as an update count;
816 if the result is a <code>ResultSet</code> object or there are no more results, -1
817 is returned. This method should be called only once per result.
819 @return the current result as an update count; -1 if the current result is a
820 <code>ResultSet</code> object or there are no more results
823 function TZAbstractStatement.GetUpdateCount: Integer;
825 Result := FLastUpdateCount;
829 Moves to a <code>Statement</code> object's next result. It returns
830 <code>true</code> if this result is a <code>ResultSet</code> object.
831 This method also implicitly closes any current <code>ResultSet</code>
832 object obtained with the method <code>getResultSet</code>.
834 <P>There are no more results when the following is true:
836 <code>(!getMoreResults() && (getUpdateCount() == -1)</code>
839 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
840 <code>false</code> if it is an update count or there are no more results
843 function TZAbstractStatement.GetMoreResults: Boolean;
849 Retrieves the direction for fetching rows from
850 database tables that is the default for result sets
851 generated from this <code>Statement</code> object.
852 If this <code>Statement</code> object has not set
853 a fetch direction by calling the method <code>setFetchDirection</code>,
854 the return value is implementation-specific.
856 @return the default fetch direction for result sets generated
857 from this <code>Statement</code> object
859 function TZAbstractStatement.GetFetchDirection: TZFetchDirection;
861 Result := FFetchDirection;
865 Gives the driver a hint as to the direction in which
866 the rows in a result set
867 will be processed. The hint applies only to result sets created
868 using this <code>Statement</code> object. The default value is
869 <code>ResultSet.FETCH_FORWARD</code>.
870 <p>Note that this method sets the default fetch direction for
871 result sets generated by this <code>Statement</code> object.
872 Each result set has its own methods for getting and setting
873 its own fetch direction.
874 @param direction the initial direction for processing rows
876 procedure TZAbstractStatement.SetFetchDirection(Value: TZFetchDirection);
878 FFetchDirection := Value;
882 Retrieves the number of result set rows that is the default
883 fetch size for result sets
884 generated from this <code>Statement</code> object.
885 If this <code>Statement</code> object has not set
886 a fetch size by calling the method <code>setFetchSize</code>,
887 the return value is implementation-specific.
888 @return the default fetch size for result sets generated
889 from this <code>Statement</code> object
891 function TZAbstractStatement.GetFetchSize: Integer;
893 Result := FFetchSize;
897 Gives the JDBC driver a hint as to the number of rows that should
898 be fetched from the database when more rows are needed. The number
899 of rows specified affects only result sets created using this
900 statement. If the value specified is zero, then the hint is ignored.
901 The default value is zero.
903 @param rows the number of rows to fetch
905 procedure TZAbstractStatement.SetFetchSize(Value: Integer);
911 Sets a result set concurrency for <code>ResultSet</code> objects
912 generated by this <code>Statement</code> object.
914 @param Concurrency either <code>ResultSet.CONCUR_READ_ONLY</code> or
915 <code>ResultSet.CONCUR_UPDATABLE</code>
917 procedure TZAbstractStatement.SetResultSetConcurrency(
918 Value: TZResultSetConcurrency);
920 FResultSetConcurrency := Value;
924 Retrieves the result set concurrency for <code>ResultSet</code> objects
925 generated by this <code>Statement</code> object.
927 @return either <code>ResultSet.CONCUR_READ_ONLY</code> or
928 <code>ResultSet.CONCUR_UPDATABLE</code>
930 function TZAbstractStatement.GetResultSetConcurrency: TZResultSetConcurrency;
932 Result := FResultSetConcurrency;
936 Sets a result set type for <code>ResultSet</code> objects
937 generated by this <code>Statement</code> object.
939 @param ResultSetType one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
940 <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
941 <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
943 procedure TZAbstractStatement.SetResultSetType(Value: TZResultSetType);
945 FResultSetType := Value;
949 Retrieves the result set type for <code>ResultSet</code> objects
950 generated by this <code>Statement</code> object.
952 @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
953 <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
954 <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
956 function TZAbstractStatement.GetResultSetType: TZResultSetType;
958 Result := FResultSetType;
962 Gets the current value for locate updates.
963 @returns the current value for locate updates.
965 function TZAbstractStatement.GetLocateUpdates: TZLocateUpdatesMode;
967 Result := FLocateUpdates;
971 Sets a new value for locate updates.
972 @param Value a new value for locate updates.
974 procedure TZAbstractStatement.SetLocateUpdates(Value: TZLocateUpdatesMode);
976 FLocateUpdates := Value;
980 Gets the current value for post updates.
981 @returns the current value for post updates.
983 function TZAbstractStatement.GetPostUpdates: TZPostUpdatesMode;
985 Result := FPostUpdates;
989 Sets a new value for post updates.
990 @param Value a new value for post updates.
992 procedure TZAbstractStatement.SetPostUpdates(Value: TZPostUpdatesMode);
994 FPostUpdates := Value;
998 Adds an SQL command to the current batch of commmands for this
999 <code>Statement</code> object. This method is optional.
1001 @param sql typically this is a static SQL <code>INSERT</code> or
1002 <code>UPDATE</code> statement
1004 procedure TZAbstractStatement.AddBatch(const SQL: string);
1006 FBatchQueries.Add(SQL);
1010 Makes the set of commands in the current batch empty.
1011 This method is optional.
1013 procedure TZAbstractStatement.ClearBatch;
1015 FBatchQueries.Clear;
1019 Submits a batch of commands to the database for execution and
1020 if all commands execute successfully, returns an array of update counts.
1021 The <code>int</code> elements of the array that is returned are ordered
1022 to correspond to the commands in the batch, which are ordered
1023 according to the order in which they were added to the batch.
1024 The elements in the array returned by the method <code>executeBatch</code>
1025 may be one of the following:
1027 <LI>A number greater than or equal to zero -- indicates that the
1028 command was processed successfully and is an update count giving the
1029 number of rows in the database that were affected by the command's
1031 <LI>A value of <code>-2</code> -- indicates that the command was
1032 processed successfully but that the number of rows affected is
1035 If one of the commands in a batch update fails to execute properly,
1036 this method throws a <code>BatchUpdateException</code>, and a JDBC
1037 driver may or may not continue to process the remaining commands in
1038 the batch. However, the driver's behavior must be consistent with a
1039 particular DBMS, either always continuing to process commands or never
1040 continuing to process commands. If the driver continues processing
1041 after a failure, the array returned by the method
1042 <code>BatchUpdateException.getUpdateCounts</code>
1043 will contain as many elements as there are commands in the batch, and
1044 at least one of the elements will be the following:
1046 <LI>A value of <code>-3</code> -- indicates that the command failed
1047 to execute successfully and occurs only if a driver continues to
1048 process commands after a command fails
1051 A driver is not required to implement this method.
1052 The possible implementations and return values have been modified in
1053 the Java 2 SDK, Standard Edition, version 1.3 to
1054 accommodate the option of continuing to proccess commands in a batch
1055 update after a <code>BatchUpdateException</code> obejct has been thrown.
1057 @return an array of update counts containing one element for each
1058 command in the batch. The elements of the array are ordered according
1059 to the order in which commands were added to the batch.
1061 function TZAbstractStatement.ExecuteBatch: TIntegerDynArray;
1065 SetLength(Result, FBatchQueries.Count);
1066 for I := 0 to FBatchQueries.Count -1 do
1067 Result[I] := ExecuteUpdate(FBatchQueries[I]);
1072 Returns the <code>Connection</code> object
1073 that produced this <code>Statement</code> object.
1074 @return the connection that produced this statement
1076 function TZAbstractStatement.GetConnection: IZConnection;
1078 Result := FConnection;
1082 Gets statement parameters.
1083 @returns a list with statement parameters.
1085 function TZAbstractStatement.GetParameters: TStrings;
1091 Returns the ChunkSize for reading/writing large lobs
1092 @returns the chunksize in bytes.
1094 function TZAbstractStatement.GetChunkSize: Integer;
1096 Result := FChunkSize;
1099 { TZAbstractPreparedStatement }
1102 Constructs this object and assigns main properties.
1103 @param Connection a database connection object.
1104 @param Sql a prepared Sql statement.
1105 @param Info a statement parameters.
1107 constructor TZAbstractPreparedStatement.Create(Connection: IZConnection;
1108 const SQL: string; Info: TStrings);
1110 inherited Create(Connection, Info);
1112 {$IFDEF UNICODE}WSQL{$ELSE}ASQL{$ENDIF} := SQL;
1117 FStatementId := Self.GetNextStatementId;
1121 Destroys this object and cleanups the memory.
1123 destructor TZAbstractPreparedStatement.Destroy;
1131 Executes an SQL statement that returns a single <code>ResultSet</code> object.
1132 @param sql typically this is a static SQL <code>SELECT</code> statement
1133 @return a <code>ResultSet</code> object that contains the data produced by the
1134 given query; never <code>null</code>
1136 function TZAbstractPreparedStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;
1139 Result := ExecuteQueryPrepared;
1143 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
1144 <code>DELETE</code> statement. In addition,
1145 SQL statements that return nothing, such as SQL DDL statements,
1148 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
1149 <code>DELETE</code> statement or an SQL statement that returns nothing
1150 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
1151 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
1153 function TZAbstractPreparedStatement.ExecuteUpdate(const SQL: ZWideString): Integer;
1156 Result := ExecuteUpdatePrepared;
1160 Executes an SQL statement that may return multiple results.
1161 Under some (uncommon) situations a single SQL statement may return
1162 multiple result sets and/or update counts. Normally you can ignore
1163 this unless you are (1) executing a stored procedure that you know may
1164 return multiple results or (2) you are dynamically executing an
1165 unknown SQL string. The methods <code>execute</code>,
1166 <code>getMoreResults</code>, <code>getResultSet</code>,
1167 and <code>getUpdateCount</code> let you navigate through multiple results.
1169 The <code>execute</code> method executes an SQL statement and indicates the
1170 form of the first result. You can then use the methods
1171 <code>getResultSet</code> or <code>getUpdateCount</code>
1172 to retrieve the result, and <code>getMoreResults</code> to
1173 move to any subsequent result(s).
1175 @param sql any SQL statement
1176 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
1177 <code>false</code> if it is an update count or there are no more results
1179 @see #getUpdateCount
1180 @see #getMoreResults
1182 function TZAbstractPreparedStatement.Execute(const SQL: ZWideString): Boolean;
1185 Result := ExecutePrepared;
1189 Executes an SQL statement that returns a single <code>ResultSet</code> object.
1190 @param sql typically this is a static SQL <code>SELECT</code> statement
1191 @return a <code>ResultSet</code> object that contains the data produced by the
1192 given query; never <code>null</code>
1194 function TZAbstractPreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;
1197 Result := ExecuteQueryPrepared;
1201 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
1202 <code>DELETE</code> statement. In addition,
1203 SQL statements that return nothing, such as SQL DDL statements,
1206 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
1207 <code>DELETE</code> statement or an SQL statement that returns nothing
1208 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
1209 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
1211 function TZAbstractPreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;
1214 Result := ExecuteUpdatePrepared;
1218 Executes an SQL statement that may return multiple results.
1219 Under some (uncommon) situations a single SQL statement may return
1220 multiple result sets and/or update counts. Normally you can ignore
1221 this unless you are (1) executing a stored procedure that you know may
1222 return multiple results or (2) you are dynamically executing an
1223 unknown SQL string. The methods <code>execute</code>,
1224 <code>getMoreResults</code>, <code>getResultSet</code>,
1225 and <code>getUpdateCount</code> let you navigate through multiple results.
1227 The <code>execute</code> method executes an SQL statement and indicates the
1228 form of the first result. You can then use the methods
1229 <code>getResultSet</code> or <code>getUpdateCount</code>
1230 to retrieve the result, and <code>getMoreResults</code> to
1231 move to any subsequent result(s).
1233 @param sql any SQL statement
1234 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
1235 <code>false</code> if it is an update count or there are no more results
1237 @see #getUpdateCount
1238 @see #getMoreResults
1240 function TZAbstractPreparedStatement.Execute(const SQL: RawByteString): Boolean;
1243 Result := ExecutePrepared;
1248 Prepares eventual structures for binding input parameters.
1250 procedure TZAbstractPreparedStatement.PrepareInParameters;
1255 Binds the input parameters
1257 procedure TZAbstractPreparedStatement.BindInParameters;
1262 LogString := ''; //init for FPC
1263 if InParamCount = 0 then
1265 { Prepare Log Output}
1266 For I := 0 to InParamCount - 1 do
1268 LogString := LogString + GetInParamLogValue(InParamValues[I])+',';
1270 LogPrepStmtMessage(lcBindPrepStmt, LogString);
1274 Removes eventual structures for binding input parameters.
1276 procedure TZAbstractPreparedStatement.UnPrepareInParameters;
1281 Sets a new parameter count and initializes the buffers.
1282 @param NewParamCount a new parameters count.
1284 procedure TZAbstractPreparedStatement.SetInParamCount(NewParamCount: Integer);
1288 SetLength(FInParamValues, NewParamCount);
1289 SetLength(FInParamTypes, NewParamCount);
1290 SetLength(FInParamDefaultValues, NewParamCount);
1291 for I := FInParamCount to NewParamCount - 1 do
1293 FInParamValues[I] := NullVariant;
1294 FInParamTypes[I] := stUnknown;
1296 FInParamDefaultValues[I] := '';
1298 FInParamCount := NewParamCount;
1302 Sets a variant value into specified parameter.
1303 @param ParameterIndex a index of the parameter.
1304 @param SqlType a parameter SQL type.
1305 @paran Value a new parameter value.
1307 procedure TZAbstractPreparedStatement.SetInParam(ParameterIndex: Integer;
1308 SQLType: TZSQLType; const Value: TZVariant);
1310 if ParameterIndex >= FInParamCount then
1311 SetInParamCount(ParameterIndex);
1313 FInParamTypes[ParameterIndex - 1] := SQLType;
1314 FInParamValues[ParameterIndex - 1] := Value;
1318 Logs a message about prepared statement event with normal result code.
1319 @param Category a category of the message.
1320 @param Protocol a name of the protocol.
1321 @param Msg a description message.
1323 procedure TZAbstractPreparedStatement.LogPrepStmtMessage(Category: TZLoggingCategory;
1324 const Msg: string = '');
1327 DriverManager.LogMessage(Category, Connection.GetIZPlainDriver.GetProtocol, Format('Statement %d : %s', [FStatementId, Msg]))
1329 DriverManager.LogMessage(Category, Connection.GetIZPlainDriver.GetProtocol, Format('Statement %d', [FStatementId]));
1333 function TZAbstractPreparedStatement.GetInParamLogValue(Value: TZVariant): String;
1337 vtNull : result := '(NULL)';
1338 vtBoolean : If VBoolean then result := '(TRUE)' else result := '(FALSE)';
1339 vtInteger : result := IntToStr(VInteger);
1340 vtFloat : result := FloatToStr(VFloat);
1341 vtString : result := '''' + VString + '''';
1342 vtUnicodeString : result := '''' + VUnicodeString + '''';
1343 vtDateTime : result := DateTimeToStr(VDateTime);
1344 vtPointer : result := '(POINTER)';
1345 vtInterface : result := '(INTERFACE)';
1347 result := '(UNKNOWN TYPE)'
1352 Executes the SQL query in this <code>PreparedStatement</code> object
1353 and returns the result set generated by the query.
1355 @return a <code>ResultSet</code> object that contains the data produced by the
1356 query; never <code>null</code>
1359 function TZAbstractPreparedStatement.ExecuteQueryPrepared: IZResultSet;
1361 { Logging Execution }
1362 LogPrepStmtMessage(lcExecPrepStmt);
1367 Executes the SQL INSERT, UPDATE or DELETE statement
1368 in this <code>PreparedStatement</code> object.
1370 SQL statements that return nothing, such as SQL DDL statements,
1373 @return either the row count for INSERT, UPDATE or DELETE statements;
1374 or 0 for SQL statements that return nothing
1377 function TZAbstractPreparedStatement.ExecuteUpdatePrepared: Integer;
1379 { Logging Execution }
1380 LogPrepStmtMessage(lcExecPrepStmt);
1385 Sets the designated parameter the default SQL value.
1386 <P><B>Note:</B> You must specify the default value.
1388 @param parameterIndex the first parameter is 1, the second is 2, ...
1389 @param Value the default value normally defined in the field's DML SQL statement
1391 procedure TZAbstractPreparedStatement.SetDefaultValue(
1392 ParameterIndex: Integer; const Value: string);
1394 if ParameterIndex >= FInParamCount then
1395 SetInParamCount(ParameterIndex);
1397 FInParamDefaultValues[ParameterIndex - 1] := Value;
1401 Sets the designated parameter to SQL <code>NULL</code>.
1402 <P><B>Note:</B> You must specify the parameter's SQL type.
1404 @param parameterIndex the first parameter is 1, the second is 2, ...
1405 @param sqlType the SQL type code defined in <code>java.sql.Types</code>
1407 procedure TZAbstractPreparedStatement.SetNull(ParameterIndex: Integer;
1408 SQLType: TZSQLType);
1410 SetInParam(ParameterIndex, SQLType, NullVariant);
1414 Sets the designated parameter to a Java <code>boolean</code> value.
1415 The driver converts this
1416 to an SQL <code>BIT</code> value when it sends it to the database.
1418 @param parameterIndex the first parameter is 1, the second is 2, ...
1419 @param x the parameter value
1421 procedure TZAbstractPreparedStatement.SetBoolean(ParameterIndex: Integer;
1426 DefVarManager.SetAsBoolean(Temp, Value);
1427 SetInParam(ParameterIndex, stBoolean, Temp);
1431 Sets the designated parameter to a Java <code>byte</code> value.
1432 The driver converts this
1433 to an SQL <code>TINYINT</code> value when it sends it to the database.
1435 @param parameterIndex the first parameter is 1, the second is 2, ...
1436 @param x the parameter value
1438 procedure TZAbstractPreparedStatement.SetByte(ParameterIndex: Integer;
1443 DefVarManager.SetAsInteger(Temp, Value);
1444 SetInParam(ParameterIndex, stByte, Temp);
1448 Sets the designated parameter to a Java <code>short</code> value.
1449 The driver converts this
1450 to an SQL <code>SMALLINT</code> value when it sends it to the database.
1452 @param parameterIndex the first parameter is 1, the second is 2, ...
1453 @param x the parameter value
1455 procedure TZAbstractPreparedStatement.SetShort(ParameterIndex: Integer;
1460 DefVarManager.SetAsInteger(Temp, Value);
1461 SetInParam(ParameterIndex, stShort, Temp);
1465 Sets the designated parameter to a Java <code>int</code> value.
1466 The driver converts this
1467 to an SQL <code>INTEGER</code> value when it sends it to the database.
1469 @param parameterIndex the first parameter is 1, the second is 2, ...
1470 @param x the parameter value
1472 procedure TZAbstractPreparedStatement.SetInt(ParameterIndex: Integer;
1477 DefVarManager.SetAsInteger(Temp, Value);
1478 SetInParam(ParameterIndex, stInteger, Temp);
1482 Sets the designated parameter to a Java <code>long</code> value.
1483 The driver converts this
1484 to an SQL <code>BIGINT</code> value when it sends it to the database.
1486 @param parameterIndex the first parameter is 1, the second is 2, ...
1487 @param x the parameter value
1489 procedure TZAbstractPreparedStatement.SetLong(ParameterIndex: Integer;
1494 DefVarManager.SetAsInteger(Temp, Value);
1495 SetInParam(ParameterIndex, stLong, Temp);
1499 Sets the designated parameter to a Java <code>float</code> value.
1500 The driver converts this
1501 to an SQL <code>FLOAT</code> value when it sends it to the database.
1503 @param parameterIndex the first parameter is 1, the second is 2, ...
1504 @param x the parameter value
1506 procedure TZAbstractPreparedStatement.SetFloat(ParameterIndex: Integer;
1511 DefVarManager.SetAsFloat(Temp, Value);
1512 SetInParam(ParameterIndex, stFloat, Temp);
1516 Sets the designated parameter to a Java <code>double</code> value.
1517 The driver converts this
1518 to an SQL <code>DOUBLE</code> value when it sends it to the database.
1520 @param parameterIndex the first parameter is 1, the second is 2, ...
1521 @param x the parameter value
1523 procedure TZAbstractPreparedStatement.SetDouble(ParameterIndex: Integer;
1528 DefVarManager.SetAsFloat(Temp, Value);
1529 SetInParam(ParameterIndex, stDouble, Temp);
1533 Sets the designated parameter to a <code>java.math.BigDecimal</code> value.
1534 The driver converts this to an SQL <code>NUMERIC</code> value when
1535 it sends it to the database.
1537 @param parameterIndex the first parameter is 1, the second is 2, ...
1538 @param x the parameter value
1540 procedure TZAbstractPreparedStatement.SetBigDecimal(
1541 ParameterIndex: Integer; Value: Extended);
1545 DefVarManager.SetAsFloat(Temp, Value);
1546 SetInParam(ParameterIndex, stBigDecimal, Temp);
1550 Sets the designated parameter to a Java <code>String</code> value.
1551 The driver converts this
1552 to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
1553 (depending on the argument's
1554 size relative to the driver's limits on <code>VARCHAR</code> values)
1555 when it sends it to the database.
1557 @param parameterIndex the first parameter is 1, the second is 2, ...
1558 @param x the parameter value
1560 procedure TZAbstractPreparedStatement.SetPChar(ParameterIndex: Integer;
1565 DefVarManager.SetAsString(Temp, Value);
1566 SetInParam(ParameterIndex, stString, Temp);
1570 Sets the designated parameter to a Java <code>String</code> value.
1571 The driver converts this
1572 to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
1573 (depending on the argument's
1574 size relative to the driver's limits on <code>VARCHAR</code> values)
1575 when it sends it to the database.
1577 @param parameterIndex the first parameter is 1, the second is 2, ...
1578 @param x the parameter value
1580 procedure TZAbstractPreparedStatement.SetString(ParameterIndex: Integer;
1581 const Value: String);
1585 DefVarManager.SetAsString(Temp, Value);
1586 SetInParam(ParameterIndex, stString, Temp);
1590 Sets the designated parameter to a Object Pascal <code>WideString</code>
1591 value. The driver converts this
1592 to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
1593 (depending on the argument's
1594 size relative to the driver's limits on <code>VARCHAR</code> values)
1595 when it sends it to the database.
1597 @param parameterIndex the first parameter is 1, the second is 2, ...
1598 @param x the parameter value
1601 procedure TZAbstractPreparedStatement.SetUnicodeString(ParameterIndex: Integer;
1602 const Value: ZWideString);
1606 DefVarManager.SetAsUnicodeString(Temp, Value);
1607 SetInParam(ParameterIndex, stUnicodeString, Temp);
1611 Sets the designated parameter to a Java array of bytes. The driver converts
1612 this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
1613 (depending on the argument's size relative to the driver's limits on
1614 <code>VARBINARY</code> values) when it sends it to the database.
1616 @param parameterIndex the first parameter is 1, the second is 2, ...
1617 @param x the parameter value
1619 procedure TZAbstractPreparedStatement.SetBytes(ParameterIndex: Integer;
1620 const Value: TByteDynArray);
1624 DefVarManager.SetAsBytes(Temp, Value);
1625 SetInParam(ParameterIndex, stBytes, Temp);
1629 Sets the designated parameter to a <code<java.sql.Date</code> value.
1630 The driver converts this to an SQL <code>DATE</code>
1631 value when it sends it to the database.
1633 @param parameterIndex the first parameter is 1, the second is 2, ...
1634 @param x the parameter value
1636 procedure TZAbstractPreparedStatement.SetDate(ParameterIndex: Integer;
1641 DefVarManager.SetAsDateTime(Temp, Value);
1642 SetInParam(ParameterIndex, stDate, Temp);
1646 Sets the designated parameter to a <code>java.sql.Time</code> value.
1647 The driver converts this to an SQL <code>TIME</code> value
1648 when it sends it to the database.
1650 @param parameterIndex the first parameter is 1, the second is 2, ...
1651 @param x the parameter value
1653 procedure TZAbstractPreparedStatement.SetTime(ParameterIndex: Integer;
1658 DefVarManager.SetAsDateTime(Temp, Value);
1659 SetInParam(ParameterIndex, stTime, Temp);
1663 Sets the designated parameter to a <code>java.sql.Timestamp</code> value.
1664 The driver converts this to an SQL <code>TIMESTAMP</code> value
1665 when it sends it to the database.
1667 @param parameterIndex the first parameter is 1, the second is 2, ...
1668 @param x the parameter value
1670 procedure TZAbstractPreparedStatement.SetTimestamp(ParameterIndex: Integer;
1675 DefVarManager.SetAsDateTime(Temp, Value);
1676 SetInParam(ParameterIndex, stTimestamp, Temp);
1680 Sets the designated parameter to the given input stream, which will have
1681 the specified number of bytes.
1682 When a very large ASCII value is input to a <code>LONGVARCHAR</code>
1683 parameter, it may be more practical to send it via a
1684 <code>java.io.InputStream</code>. Data will be read from the stream
1685 as needed until end-of-file is reached. The JDBC driver will
1686 do any necessary conversion from ASCII to the database char format.
1688 <P><B>Note:</B> This stream object can either be a standard
1689 Java stream object or your own subclass that implements the
1692 @param parameterIndex the first parameter is 1, the second is 2, ...
1693 @param x the Java input stream that contains the ASCII parameter value
1694 @param length the number of bytes in the stream
1696 procedure TZAbstractPreparedStatement.SetAsciiStream(
1697 ParameterIndex: Integer; Value: TStream);
1699 SetBlob(ParameterIndex, stAsciiStream, TZAbstractBlob.CreateWithStream(Value, GetConnection));
1703 Sets the designated parameter to the given input stream, which will have
1704 the specified number of bytes.
1705 When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
1706 parameter, it may be more practical to send it via a
1707 <code>java.io.InputStream</code> object. The data will be read from the stream
1708 as needed until end-of-file is reached. The JDBC driver will
1709 do any necessary conversion from UNICODE to the database char format.
1710 The byte format of the Unicode stream must be Java UTF-8, as
1711 defined in the Java Virtual Machine Specification.
1713 <P><B>Note:</B> This stream object can either be a standard
1714 Java stream object or your own subclass that implements the
1717 @param parameterIndex the first parameter is 1, the second is 2, ...
1718 @param x the java input stream which contains the UNICODE parameter value
1720 procedure TZAbstractPreparedStatement.SetUnicodeStream(
1721 ParameterIndex: Integer; Value: TStream);
1723 SetBlob(ParameterIndex, stUnicodeStream, TZAbstractBlob.CreateWithStream(Value, GetConnection));
1727 Sets the designated parameter to the given input stream, which will have
1728 the specified number of bytes.
1729 When a very large binary value is input to a <code>LONGVARBINARY</code>
1730 parameter, it may be more practical to send it via a
1731 <code>java.io.InputStream</code> object. The data will be read from the stream
1732 as needed until end-of-file is reached.
1734 <P><B>Note:</B> This stream object can either be a standard
1735 Java stream object or your own subclass that implements the
1738 @param parameterIndex the first parameter is 1, the second is 2, ...
1739 @param x the java input stream which contains the binary parameter value
1741 procedure TZAbstractPreparedStatement.SetBinaryStream(
1742 ParameterIndex: Integer; Value: TStream);
1744 SetBlob(ParameterIndex, stBinaryStream, TZAbstractBlob.CreateWithStream(Value, GetConnection));
1748 Sets a blob object for the specified parameter.
1749 @param ParameterIndex the first parameter is 1, the second is 2, ...
1750 @param Value the java blob object.
1752 procedure TZAbstractPreparedStatement.SetBlob(ParameterIndex: Integer;
1753 SQLType: TZSQLType; Value: IZBlob);
1757 if not (SQLType in [stAsciiStream, stUnicodeStream, stBinaryStream]) then
1758 raise EZSQLException.Create(SWrongTypeForBlobParameter);
1759 DefVarManager.SetAsInterface(Temp, Value);
1760 SetInParam(ParameterIndex, SQLType, Temp);
1764 Sets a variant value for the specified parameter.
1765 @param ParameterIndex the first parameter is 1, the second is 2, ...
1766 @param Value the variant value.
1768 procedure TZAbstractPreparedStatement.SetValue(ParameterIndex: Integer;
1769 const Value: TZVariant);
1774 vtBoolean: SQLType := stBoolean;
1775 vtInteger: SQLType := stLong;
1776 vtFloat: SQLType := stBigDecimal;
1777 vtUnicodeString: SQLType := stUnicodeString;
1778 vtDateTime: SQLType := stTimestamp;
1780 SQLType := stString;
1782 SetInParam(ParameterIndex, SQLType, Value);
1786 Clears the current parameter values immediately.
1787 <P>In general, parameter values remain in force for repeated use of a
1788 statement. Setting a parameter value automatically clears its
1789 previous value. However, in some cases it is useful to immediately
1790 release the resources used by the current parameter values; this can
1791 be done by calling the method <code>clearParameters</code>.
1793 procedure TZAbstractPreparedStatement.ClearParameters;
1797 for I := 1 to FInParamCount do
1799 SetInParam(I, stUnknown, NullVariant);
1800 SetDefaultValue(I, '');
1806 Executes any kind of SQL statement.
1807 Some prepared statements return multiple results; the <code>execute</code>
1808 method handles these complex statements as well as the simpler
1809 form of statements handled by the methods <code>executeQuery</code>
1810 and <code>executeUpdate</code>.
1811 @see Statement#execute
1814 function TZAbstractPreparedStatement.ExecutePrepared: Boolean;
1816 { Logging Execution }
1817 LogPrepStmtMessage(lcExecPrepStmt, '');
1822 function TZAbstractPreparedStatement.GetSQL: String;
1827 procedure TZAbstractPreparedStatement.Prepare;
1829 PrepareInParameters;
1833 procedure TZAbstractPreparedStatement.Unprepare;
1835 UnPrepareInParameters;
1839 function TZAbstractPreparedStatement.IsPrepared: Boolean;
1841 Result := FPrepared;
1845 Adds a set of parameters to this <code>PreparedStatement</code>
1846 object's batch of commands.
1847 @see Statement#addBatch
1849 procedure TZAbstractPreparedStatement.AddBatchPrepared;
1854 Gets the number, types and properties of a <code>ResultSet</code>
1856 @return the description of a <code>ResultSet</code> object's columns
1858 function TZAbstractPreparedStatement.GetMetaData: IZResultSetMetaData;
1861 RaiseUnsupportedException;
1864 { TZAbstractCallableStatement }
1867 Constructs this object and assigns main properties.
1868 @param Connection a database connection object.
1869 @param Sql a prepared Sql statement.
1870 @param Info a statement parameters.
1872 constructor TZAbstractCallableStatement.Create(Connection: IZConnection;
1873 SQL: string; Info: TStrings);
1875 inherited Create(Connection, SQL, Info);
1876 FOutParamCount := 0;
1877 SetOutParamCount(0);
1878 FProcSql := ''; //Init -> FPC
1879 FLastWasNull := True;
1880 FResultSets := TZCollection.Create;
1881 FIsFunction := False;
1885 Close and release a list of returned resultsets.
1887 procedure TZAbstractCallableStatement.ClearResultSets;
1892 for i := 0 to FResultSets.Count -1 do
1893 if Supports(FResultSets[i], IZResultSet, RS) then //possible IZUpdateCount e.g. DBLib, ASA
1896 LastResultSet := nil;
1900 Function remove stUnknown and ptResult, ptOutput paramters from
1901 InParamTypes and InParamValues because the out-params are added after
1904 procedure TZAbstractCallableStatement.TrimInParameters;
1907 ParamValues: TZVariantDynArray;
1908 ParamTypes: TZSQLTypeArray;
1909 ParamCount: Integer;
1912 SetLength(ParamValues, InParamCount);
1913 SetLength(ParamTypes, InParamCount);
1915 {Need for dbc access, where no metadata is used to register the ParamTypes}
1916 if Length(FDBParamTypes) < InParamCount then
1917 SetLength(FDBParamTypes, InParamCount);
1918 {end for dbc access}
1920 for I := 0 to High(InParamTypes) do
1922 if ( InParamTypes[I] = ZDbcIntfs.stUnknown ) then
1924 if (FDBParamTypes[i] in [2, 4]) then //[ptResult, ptOutput]
1925 continue; //EgonHugeist: Ignore known OutParams! else StatmentInparamCount <> expect ProcedureParamCount
1926 ParamTypes[ParamCount] := InParamTypes[I];
1927 ParamValues[ParamCount] := InParamValues[I];
1930 if ParamCount = InParamCount then
1932 InParamTypes := ParamTypes;
1933 InParamValues := ParamValues;
1934 SetInParamCount(ParamCount); //AVZ
1938 Sets a new parameter count and initializes the buffers.
1939 @param NewParamCount a new parameters count.
1941 procedure TZAbstractCallableStatement.SetOutParamCount(NewParamCount: Integer);
1945 SetLength(FOutParamValues, NewParamCount);
1946 SetLength(FOutParamTypes, NewParamCount);
1947 for I := FOutParamCount to NewParamCount - 1 do
1949 FOutParamValues[I] := NullVariant;
1950 FOutParamTypes[I] := stUnknown;
1952 FOutParamCount := NewParamCount;
1956 Clears the current parameter values immediately.
1957 <P>In general, parameter values remain in force for repeated use of a
1958 statement. Setting a parameter value automatically clears its
1959 previous value. However, in some cases it is useful to immediately
1960 release the resources used by the current parameter values; this can
1961 be done by calling the method <code>clearParameters</code>.
1963 procedure TZAbstractCallableStatement.ClearParameters;
1968 for I := 1 to FOutParamCount do
1970 OutParamValues[I - 1] := NullVariant;
1971 OutParamTypes[I - 1] := stUnknown;
1973 SetOutParamCount(0);
1977 Releases this <code>Statement</code> object's database
1978 and JDBC resources immediately instead of waiting for
1979 this to happen when it is automatically closed.
1980 It is generally good practice to release resources as soon as
1981 you are finished with them to avoid tying up database
1983 <P><B>Note:</B> A <code>Statement</code> object is automatically closed when it is
1984 garbage collected. When a <code>Statement</code> object is closed, its current
1985 <code>ResultSet</code> object, if one exists, is also closed.
1987 procedure TZAbstractCallableStatement.Close;
1995 Do we call a function or a procedure?
1996 @result Returns <code>True</code> if we call a function
1998 function TZAbstractCallableStatement.IsFunction: Boolean;
2000 Result := FIsFunction;
2004 Do we have ptInputOutput or ptOutput paramets in a function or procedure?
2005 @result Returns <code>True</code> if ptInputOutput or ptOutput is available
2007 function TZAbstractCallableStatement.HasOutParameter: Boolean;
2009 Result := FHasOutParameter;
2013 Are more resultsets retrieved?
2014 @result Returns <code>True</code> if more resultsets are retrieved
2016 function TZAbstractCallableStatement.HasMoreResultSets: Boolean;
2022 Get the first resultset..
2023 @result <code>IZResultSet</code> if supported
2025 function TZAbstractCallableStatement.GetFirstResultSet: IZResultSet;
2031 Get the previous resultset..
2032 @result <code>IZResultSet</code> if supported
2034 function TZAbstractCallableStatement.GetPreviousResultSet: IZResultSet;
2040 Get the next resultset..
2041 @result <code>IZResultSet</code> if supported
2043 function TZAbstractCallableStatement.GetNextResultSet: IZResultSet;
2049 Get the last resultset..
2050 @result <code>IZResultSet</code> if supported
2052 function TZAbstractCallableStatement.GetLastResultSet: IZResultSet;
2059 @result <code>True</code> if first ResultSet
2061 function TZAbstractCallableStatement.BOR: Boolean;
2068 @result <code>True</code> if Last ResultSet
2070 function TZAbstractCallableStatement.EOR: Boolean;
2076 Retrieves a ResultSet by his index.
2077 @param Index the index of the Resultset
2078 @result <code>IZResultSet</code> of the Index or nil.
2080 function TZAbstractCallableStatement.GetResultSetByIndex(const Index: Integer): IZResultSet;
2086 Returns the Count of retrived ResultSets.
2087 @result <code>Integer</code> Count
2089 function TZAbstractCallableStatement.GetResultSetCount: Integer;
2095 Registers the OUT parameter in ordinal position
2096 <code>parameterIndex</code> to the JDBC type
2097 <code>sqlType</code>. All OUT parameters must be registered
2098 before a stored procedure is executed.
2100 The JDBC type specified by <code>sqlType</code> for an OUT
2101 parameter determines the Java type that must be used
2102 in the <code>get</code> method to read the value of that parameter.
2104 If the JDBC type expected to be returned to this output parameter
2105 is specific to this particular database, <code>sqlType</code>
2106 should be <code>java.sql.Types.OTHER</code>. The method retrieves the value.
2107 @param parameterIndex the first parameter is 1, the second is 2,
2109 @param sqlType the JDBC type code defined by <code>java.sql.Types</code>.
2110 If the parameter is of JDBC type <code>NUMERIC</code>
2111 or <code>DECIMAL</code>, the version of
2112 <code>registerOutParameter</code> that accepts a scale value should be used.
2114 procedure TZAbstractCallableStatement.RegisterOutParameter(ParameterIndex,
2117 SetOutParamCount(ParameterIndex);
2118 OutParamTypes[ParameterIndex - 1] := TZSQLType(SQLType);
2121 procedure TZAbstractCallableStatement.RegisterParamType(ParameterIndex,
2122 ParamType: Integer);
2124 if (Length(FDBParamTypes) < ParameterIndex) then
2125 SetLength(FDBParamTypes, ParameterIndex);
2127 FDBParamTypes[ParameterIndex - 1] := ParamType;
2128 if not FIsFunction then FIsFunction := ParamType = 4; //ptResult
2129 if not FHasOutParameter then FHasOutParameter := ParamType in [2,3]; //ptOutput, ptInputOutput
2133 Gets a output parameter value by it's index.
2134 @param ParameterIndex a parameter index.
2135 @returns a parameter value.
2137 function TZAbstractCallableStatement.GetOutParam(
2138 ParameterIndex: Integer): TZVariant;
2140 if Assigned(OutParamValues) then
2142 Result := OutParamValues[ParameterIndex - 1];
2143 FLastWasNull := DefVarManager.IsNull(Result);
2147 Result:=NullVariant;
2152 procedure TZAbstractCallableStatement.SetProcSQL(const Value: String);
2158 Indicates whether or not the last OUT parameter read had the value of
2159 SQL <code>NULL</code>. Note that this method should be called only after
2160 calling a <code>getXXX</code> method; otherwise, there is no value to use in
2161 determining whether it is <code>null</code> or not.
2162 @return <code>true</code> if the last parameter read was SQL
2163 <code>NULL</code>; <code>false</code> otherwise
2165 function TZAbstractCallableStatement.WasNull: Boolean;
2167 Result := FLastWasNull;
2171 Indicates whether or not the specified OUT parameter read had the value of
2172 SQL <code>NULL</code>.
2173 @return <code>true</code> if the parameter read was SQL
2174 <code>NULL</code>; <code>false</code> otherwise
2176 function TZAbstractCallableStatement.IsNull(ParameterIndex: Integer): Boolean;
2178 GetOutParam(ParameterIndex);
2179 Result := FLastWasNull;
2183 Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
2184 or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
2185 the Java programming language.
2187 For the fixed-length type JDBC <code>CHAR</code>,
2188 the <code>String</code> object
2189 returned has exactly the same value the JDBC
2190 <code>CHAR</code> value had in the
2191 database, including any padding added by the database.
2192 @param parameterIndex the first parameter is 1, the second is 2,
2194 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2195 is <code>null</code>.
2196 @exception SQLException if a database access error occurs
2198 function TZAbstractCallableStatement.GetPChar(ParameterIndex: Integer): PChar;
2200 FTemp := GetString(ParameterIndex);
2201 Result := PChar(FTemp);
2205 Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
2206 or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
2207 the Java programming language.
2209 For the fixed-length type JDBC <code>CHAR</code>,
2210 the <code>String</code> object
2211 returned has exactly the same value the JDBC
2212 <code>CHAR</code> value had in the
2213 database, including any padding added by the database.
2214 @param parameterIndex the first parameter is 1, the second is 2,
2216 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2217 is <code>null</code>.
2218 @exception SQLException if a database access error occurs
2220 function TZAbstractCallableStatement.GetString(ParameterIndex: Integer): String;
2222 Result := SoftVarManager.GetAsString(GetOutParam(ParameterIndex));
2226 Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
2227 or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
2228 the Java programming language.
2230 For the fixed-length type JDBC <code>CHAR</code>,
2231 the <code>WideString</code> object
2232 returned has exactly the same value the JDBC
2233 <code>CHAR</code> value had in the
2234 database, including any padding added by the database.
2235 @param parameterIndex the first parameter is 1, the second is 2,
2237 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2238 is <code>null</code>.
2239 @exception SQLException if a database access error occurs
2241 function TZAbstractCallableStatement.GetUnicodeString(
2242 ParameterIndex: Integer): WideString;
2244 Result := SoftVarManager.GetAsUnicodeString(GetOutParam(ParameterIndex));
2248 Gets the value of a JDBC <code>BIT</code> parameter as a <code>boolean</code>
2249 in the Java programming language.
2250 @param parameterIndex the first parameter is 1, the second is 2,
2252 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2253 is <code>false</code>.
2255 function TZAbstractCallableStatement.GetBoolean(ParameterIndex: Integer): Boolean;
2257 Result := SoftvarManager.GetAsBoolean(GetOutParam(ParameterIndex));
2261 Gets the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
2262 in the Java programming language.
2263 @param parameterIndex the first parameter is 1, the second is 2,
2265 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2268 function TZAbstractCallableStatement.GetByte(ParameterIndex: Integer): Byte;
2270 Result := Byte(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));
2274 Gets the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
2275 in the Java programming language.
2276 @param parameterIndex the first parameter is 1, the second is 2,
2278 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2281 function TZAbstractCallableStatement.GetShort(ParameterIndex: Integer): SmallInt;
2283 Result := SmallInt(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));
2287 Gets the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
2288 in the Java programming language.
2289 @param parameterIndex the first parameter is 1, the second is 2,
2291 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2294 function TZAbstractCallableStatement.GetInt(ParameterIndex: Integer): Integer;
2296 Result := Integer(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));
2300 Gets the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
2301 in the Java programming language.
2302 @param parameterIndex the first parameter is 1, the second is 2,
2304 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2307 function TZAbstractCallableStatement.GetLong(ParameterIndex: Integer): Int64;
2309 Result := SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex));
2313 Gets the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
2314 in the Java programming language.
2315 @param parameterIndex the first parameter is 1, the second is 2,
2317 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2320 function TZAbstractCallableStatement.GetFloat(ParameterIndex: Integer): Single;
2322 Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));
2326 Gets the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
2327 in the Java programming language.
2328 @param parameterIndex the first parameter is 1, the second is 2,
2330 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2333 function TZAbstractCallableStatement.GetDouble(ParameterIndex: Integer): Double;
2335 Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));
2339 Gets the value of a JDBC <code>NUMERIC</code> parameter as a
2340 <code>java.math.BigDecimal</code> object with scale digits to
2341 the right of the decimal point.
2342 @param parameterIndex the first parameter is 1, the second is 2,
2344 @return the parameter value. If the value is SQL <code>NULL</code>, the result is
2347 function TZAbstractCallableStatement.GetBigDecimal(ParameterIndex: Integer):
2350 Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));
2354 Gets the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
2355 parameter as an array of <code>byte</code> values in the Java
2356 programming language.
2357 @param parameterIndex the first parameter is 1, the second is 2,
2359 @return the parameter value. If the value is SQL <code>NULL</code>, the result is
2362 function TZAbstractCallableStatement.GetBytes(ParameterIndex: Integer):
2365 Result := SoftVarManager.GetAsBytes(GetOutParam(ParameterIndex));
2369 Gets the value of a JDBC <code>DATE</code> parameter as a
2370 <code>java.sql.Date</code> object.
2371 @param parameterIndex the first parameter is 1, the second is 2,
2373 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2374 is <code>null</code>.
2376 function TZAbstractCallableStatement.GetDate(ParameterIndex: Integer):
2379 Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));
2383 Get the value of a JDBC <code>TIME</code> parameter as a
2384 <code>java.sql.Time</code> object.
2385 @param parameterIndex the first parameter is 1, the second is 2,
2387 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2388 is <code>null</code>.
2390 function TZAbstractCallableStatement.GetTime(ParameterIndex: Integer):
2393 Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));
2397 Gets the value of a JDBC <code>TIMESTAMP</code> parameter as a
2398 <code>java.sql.Timestamp</code> object.
2399 @param parameterIndex the first parameter is 1, the second is 2,
2401 @return the parameter value. If the value is SQL <code>NULL</code>, the result
2402 is <code>null</code>.
2404 function TZAbstractCallableStatement.GetTimestamp(ParameterIndex: Integer):
2407 Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));
2411 Gets the value of a JDBC <code>Variant</code> parameter value.
2412 @param parameterIndex the first parameter is 1, the second is 2,
2414 @return the parameter value. If the value is SQL <code>NULL</code>,
2415 the result is <code>null</code>.
2417 function TZAbstractCallableStatement.GetValue(ParameterIndex: Integer):
2420 Result := GetOutParam(ParameterIndex);
2423 { TZAbstractPreparedCallableStatement }
2425 procedure TZAbstractPreparedCallableStatement.SetProcSQL(const Value: String);
2427 if Value <> ProcSQL then Unprepare;
2428 inherited SetProcSQL(Value);
2429 if (Value <> '') and ( not Prepared ) then Prepare;
2433 Executes an SQL statement that returns a single <code>ResultSet</code> object.
2434 @param sql typically this is a static SQL <code>SELECT</code> statement
2435 @return a <code>ResultSet</code> object that contains the data produced by the
2436 given query; never <code>null</code>
2438 function TZAbstractPreparedCallableStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;
2440 if (SQL <> Self.WSQL) and (Prepared) then Unprepare;
2442 Result := ExecuteQueryPrepared;
2445 function TZAbstractPreparedCallableStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;
2447 if (SQL <> Self.ASQL) and (Prepared) then Unprepare;
2449 Result := ExecuteQueryPrepared;
2453 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
2454 <code>DELETE</code> statement. In addition,
2455 SQL statements that return nothing, such as SQL DDL statements,
2458 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
2459 <code>DELETE</code> statement or an SQL statement that returns nothing
2460 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
2461 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
2463 function TZAbstractPreparedCallableStatement.ExecuteUpdate(const SQL: ZWideString): Integer;
2465 if (SQL <> WSQL) and (Prepared) then Unprepare;
2467 Result := ExecuteUpdatePrepared;
2470 function TZAbstractPreparedCallableStatement.ExecuteUpdate(const SQL: RawByteString): Integer;
2472 if (SQL <> ASQL) and (Prepared) then Unprepare;
2474 Result := ExecuteUpdatePrepared;
2478 Executes an SQL statement that may return multiple results.
2479 Under some (uncommon) situations a single SQL statement may return
2480 multiple result sets and/or update counts. Normally you can ignore
2481 this unless you are (1) executing a stored procedure that you know may
2482 return multiple results or (2) you are dynamically executing an
2483 unknown SQL string. The methods <code>execute</code>,
2484 <code>getMoreResults</code>, <code>getResultSet</code>,
2485 and <code>getUpdateCount</code> let you navigate through multiple results.
2487 The <code>execute</code> method executes an SQL statement and indicates the
2488 form of the first result. You can then use the methods
2489 <code>getResultSet</code> or <code>getUpdateCount</code>
2490 to retrieve the result, and <code>getMoreResults</code> to
2491 move to any subsequent result(s).
2493 @param sql any SQL statement
2494 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
2495 <code>false</code> if it is an update count or there are no more results
2497 @see #getUpdateCount
2498 @see #getMoreResults
2501 function TZAbstractPreparedCallableStatement.Execute(const SQL: ZWideString): Boolean;
2503 if (SQL <> WSQL) and (Prepared) then Unprepare;
2505 Result := ExecutePrepared;
2508 function TZAbstractPreparedCallableStatement.Execute(const SQL: RawByteString): Boolean;
2510 if (SQL <> ASQL) and (Prepared) then Unprepare;
2512 Result := ExecutePrepared;
2515 { TZEmulatedPreparedStatement }
2518 Destroys this object and cleanups the memory.
2520 destructor TZEmulatedPreparedStatement.Destroy;
2522 if FCachedQuery <> nil then
2528 Sets a reference to the last statement.
2529 @param LastStatement the last statement interface.
2531 procedure TZEmulatedPreparedStatement.SetLastStatement(
2532 LastStatement: IZStatement);
2534 if FLastStatement <> nil then
2535 FLastStatement.Close;
2536 FLastStatement := LastStatement;
2539 function TZEmulatedPreparedStatement.PrepareWideSQLParam(ParamIndex: Integer): ZWideString;
2544 function TZEmulatedPreparedStatement.PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;
2550 Creates a temporary statement which executes queries.
2551 @param Info a statement parameters.
2552 @return a created statement object.
2554 function TZEmulatedPreparedStatement.GetExecStatement: IZStatement;
2556 if ExecStatement = nil then
2558 ExecStatement := CreateExecStatement;
2560 ExecStatement.SetMaxFieldSize(GetMaxFieldSize);
2561 ExecStatement.SetMaxRows(GetMaxRows);
2562 ExecStatement.SetEscapeProcessing(EscapeProcessing);
2563 ExecStatement.SetQueryTimeout(GetQueryTimeout);
2564 ExecStatement.SetCursorName(CursorName);
2566 ExecStatement.SetFetchDirection(GetFetchDirection);
2567 ExecStatement.SetFetchSize(GetFetchSize);
2568 ExecStatement.SetResultSetConcurrency(GetResultSetConcurrency);
2569 ExecStatement.SetResultSetType(GetResultSetType);
2571 Result := ExecStatement;
2575 Splits a SQL query into a list of sections.
2576 @returns a list of splitted sections.
2578 function TZEmulatedPreparedStatement.TokenizeSQLQuery: TStrings;
2584 if FCachedQuery = nil then
2586 FCachedQuery := TStringList.Create;
2587 if Pos('?', SSQL) > 0 then
2589 Tokens := Connection.GetDriver.GetTokenizer.TokenizeBufferToList(SSQL, [toUnifyWhitespaces]);
2592 for I := 0 to Tokens.Count - 1 do
2594 if Tokens[I] = '?' then
2596 if FNeedNCharDetection and not (Temp = '') then
2597 FCachedQuery.Add(Temp)
2599 FCachedQuery.Add(Temp);
2600 FCachedQuery.AddObject('?', Self);
2604 if FNeedNCharDetection and (Tokens[I] = 'N') and (Tokens.Count > i) and (Tokens[i+1] = '?') then
2606 FCachedQuery.Add(Temp);
2607 FCachedQuery.Add(Tokens[i]);
2611 Temp := Temp + Tokens[I];
2614 FCachedQuery.Add(Temp);
2620 FCachedQuery.Add(SSQL);
2622 Result := FCachedQuery;
2626 Prepares an SQL statement and inserts all data values.
2627 @return a prepared SQL statement.
2629 function TZEmulatedPreparedStatement.PrepareWideSQLQuery: ZWideString;
2632 ParamIndex: Integer;
2637 Tokens := TokenizeSQLQuery;
2639 for I := 0 to Tokens.Count - 1 do
2641 if Tokens[I] = '?' then
2643 Result := Result + PrepareWideSQLParam(ParamIndex);
2647 Result := Result + ZPlainUnicodeString(Tokens[I]);
2652 Prepares an SQL statement and inserts all data values.
2653 @return a prepared SQL statement.
2655 function TZEmulatedPreparedStatement.PrepareAnsiSQLQuery: RawByteString;
2658 ParamIndex: Integer;
2663 Tokens := TokenizeSQLQuery;
2665 for I := 0 to Tokens.Count - 1 do
2667 if Tokens[I] = '?' then
2669 Result := Result + PrepareAnsiSQLParam(ParamIndex);
2673 Result := Result + ZPlainString(Tokens[I]);
2676 if GetConnection.AutoEncodeStrings then
2677 Result := GetConnection.GetDriver.GetTokenizer.GetEscapeString(Result);
2682 Closes this statement and frees all resources.
2684 procedure TZEmulatedPreparedStatement.Close;
2687 if LastStatement <> nil then
2689 FLastStatement.Close;
2690 FLastStatement := nil;
2695 Executes an SQL statement that may return multiple results.
2696 Under some (uncommon) situations a single SQL statement may return
2697 multiple result sets and/or update counts. Normally you can ignore
2698 this unless you are (1) executing a stored procedure that you know may
2699 return multiple results or (2) you are dynamically executing an
2700 unknown SQL string. The methods <code>execute</code>,
2701 <code>getMoreResults</code>, <code>getResultSet</code>,
2702 and <code>getUpdateCount</code> let you navigate through multiple results.
2704 The <code>execute</code> method executes an SQL statement and indicates the
2705 form of the first result. You can then use the methods
2706 <code>getResultSet</code> or <code>getUpdateCount</code>
2707 to retrieve the result, and <code>getMoreResults</code> to
2708 move to any subsequent result(s).
2710 @param sql any SQL statement
2711 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
2712 <code>false</code> if it is an update count or there are no more results
2714 function TZEmulatedPreparedStatement.Execute(const SQL: ZWideString): Boolean;
2716 LastStatement := GetExecStatement;
2717 Result := LastStatement.Execute(SQL);
2719 LastResultSet := LastStatement.GetResultSet
2721 LastUpdateCount := LastStatement.GetUpdateCount;
2725 Executes an SQL statement that may return multiple results.
2726 Under some (uncommon) situations a single SQL statement may return
2727 multiple result sets and/or update counts. Normally you can ignore
2728 this unless you are (1) executing a stored procedure that you know may
2729 return multiple results or (2) you are dynamically executing an
2730 unknown SQL string. The methods <code>execute</code>,
2731 <code>getMoreResults</code>, <code>getResultSet</code>,
2732 and <code>getUpdateCount</code> let you navigate through multiple results.
2734 The <code>execute</code> method executes an SQL statement and indicates the
2735 form of the first result. You can then use the methods
2736 <code>getResultSet</code> or <code>getUpdateCount</code>
2737 to retrieve the result, and <code>getMoreResults</code> to
2738 move to any subsequent result(s).
2740 @param sql any SQL statement
2741 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
2742 <code>false</code> if it is an update count or there are no more results
2744 function TZEmulatedPreparedStatement.Execute(const SQL: RawByteString): Boolean;
2746 LastStatement := GetExecStatement;
2747 Result := LastStatement.Execute(SQL);
2749 LastResultSet := LastStatement.GetResultSet
2751 LastUpdateCount := LastStatement.GetUpdateCount;
2755 Executes an SQL statement that returns a single <code>ResultSet</code> object.
2756 @param sql typically this is a static SQL <code>SELECT</code> statement
2757 @return a <code>ResultSet</code> object that contains the data produced by the
2758 given query; never <code>null</code>
2760 function TZEmulatedPreparedStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;
2762 Result := GetExecStatement.ExecuteQuery(SQL);
2766 Executes an SQL statement that returns a single <code>ResultSet</code> object.
2767 @param sql typically this is a static SQL <code>SELECT</code> statement
2768 @return a <code>ResultSet</code> object that contains the data produced by the
2769 given query; never <code>null</code>
2771 function TZEmulatedPreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;
2773 Result := GetExecStatement.ExecuteQuery(SQL);
2777 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
2778 <code>DELETE</code> statement. In addition,
2779 SQL statements that return nothing, such as SQL DDL statements,
2782 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
2783 <code>DELETE</code> statement or an SQL statement that returns nothing
2784 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
2785 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
2787 function TZEmulatedPreparedStatement.ExecuteUpdate(const SQL: ZWideString): Integer;
2789 Result := GetExecStatement.ExecuteUpdate(SQL);
2790 LastUpdateCount := Result;
2794 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
2795 <code>DELETE</code> statement. In addition,
2796 SQL statements that return nothing, such as SQL DDL statements,
2799 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
2800 <code>DELETE</code> statement or an SQL statement that returns nothing
2801 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
2802 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
2804 function TZEmulatedPreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;
2806 Result := GetExecStatement.ExecuteUpdate(SQL);
2807 LastUpdateCount := Result;
2811 Executes the SQL query in this <code>PreparedStatement</code> object
2812 and returns the result set generated by the query.
2814 @return a <code>ResultSet</code> object that contains the data produced by the
2815 query; never <code>null</code>
2817 function TZEmulatedPreparedStatement.ExecutePrepared: Boolean;
2819 if IsAnsiDriver then
2820 Result := Execute(PrepareAnsiSQLQuery)
2822 Result := Execute(PrepareWideSQLQuery);
2826 Executes the SQL query in this <code>PreparedStatement</code> object
2827 and returns the result set generated by the query.
2829 @return a <code>ResultSet</code> object that contains the data produced by the
2830 query; never <code>null</code>
2832 function TZEmulatedPreparedStatement.ExecuteQueryPrepared: IZResultSet;
2834 if IsAnsiDriver then
2835 Result := ExecuteQuery(PrepareAnsiSQLQuery)
2837 Result := ExecuteQuery(PrepareWideSQLQuery);
2841 Executes the SQL INSERT, UPDATE or DELETE statement
2842 in this <code>PreparedStatement</code> object.
2844 SQL statements that return nothing, such as SQL DDL statements,
2847 @return either the row count for INSERT, UPDATE or DELETE statements;
2848 or 0 for SQL statements that return nothing
2850 function TZEmulatedPreparedStatement.ExecuteUpdatePrepared: Integer;
2852 if IsAnsiDriver then
2853 Result := ExecuteUpdate(PrepareAnsiSQLQuery)
2855 Result := ExecuteUpdate(PrepareWideSQLQuery);