00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { Abstract Database Connectivity Classes }
00005 { }
00006 { Originally written by Sergey Seroukhov }
00007 { }
00008 {*********************************************************}
00009
00010 {@********************************************************}
00011 { Copyright (c) 1999-2006 Zeos Development Group }
00012 { }
00013 { License Agreement: }
00014 { }
00015 { This library is distributed in the hope that it will be }
00016 { useful, but WITHOUT ANY WARRANTY; without even the }
00017 { implied warranty of MERCHANTABILITY or FITNESS FOR }
00018 { A PARTICULAR PURPOSE. See the GNU Lesser General }
00019 { Public License for more details. }
00020 { }
00021 { The source code of the ZEOS Libraries and packages are }
00022 { distributed under the Library GNU General Public }
00023 { License (see the file COPYING / COPYING.ZEOS) }
00024 { with the following modification: }
00025 { As a special exception, the copyright holders of this }
00026 { library give you permission to link this library with }
00027 { independent modules to produce an executable, }
00028 { regardless of the license terms of these independent }
00029 { modules, and to copy and distribute the resulting }
00030 { executable under terms of your choice, provided that }
00031 { you also meet, for each linked independent module, }
00032 { the terms and conditions of the license of that module. }
00033 { An independent module is a module which is not derived }
00034 { from or based on this library. If you modify this }
00035 { library, you may extend this exception to your version }
00036 { of the library, but you are not obligated to do so. }
00037 { If you do not wish to do so, delete this exception }
00038 { statement from your version. }
00039 { }
00040 { }
00041 { The project web site is located on: }
00042 { http:
00043 { http:
00044 { svn:
00045 { }
00046 { http:
00047 { http:
00048 { }
00049 { }
00050 { }
00051 { Zeos Development Group. }
00052 {********************************************************@}
00053
00054 unit ZDbcStatement;
00055
00056 interface
00057
00058 {$I ZDbc.inc}
00059
00060 uses
00061 {$IFNDEF VER130BELOW}
00062 Types,
00063 {$ENDIF}
00064 Classes, SysUtils, ZDbcIntfs, ZTokenizer, ZCompatibility, ZVariant;
00065
00066 type
00067 TZSQLTypeArray = array of TZSQLType;
00068
00069 {** Implements Abstract Generic SQL Statement. }
00070 TZAbstractStatement = class(TInterfacedObject, IZStatement)
00071 private
00072 FMaxFieldSize: Integer;
00073 FMaxRows: Integer;
00074 FEscapeProcessing: Boolean;
00075 FQueryTimeout: Integer;
00076 FLastUpdateCount: Integer;
00077 FLastResultSet: IZResultSet;
00078 FFetchDirection: TZFetchDirection;
00079 FFetchSize: Integer;
00080 FResultSetConcurrency: TZResultSetConcurrency;
00081 FResultSetType: TZResultSetType;
00082 FPostUpdates: TZPostUpdatesMode;
00083 FLocateUpdates: TZLocateUpdatesMode;
00084 FCursorName: string;
00085 FBatchQueries: TStrings;
00086 FConnection: IZConnection;
00087 FInfo: TStrings;
00088 FClosed: Boolean;
00089
00090 procedure SetLastResultSet(ResultSet: IZResultSet); virtual;
00091
00092 protected
00093 procedure RaiseUnsupportedException;
00094
00095 property MaxFieldSize: Integer read FMaxFieldSize write FMaxFieldSize;
00096 property MaxRows: Integer read FMaxRows write FMaxRows;
00097 property EscapeProcessing: Boolean
00098 read FEscapeProcessing write FEscapeProcessing;
00099 property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout;
00100 property LastUpdateCount: Integer
00101 read FLastUpdateCount write FLastUpdateCount;
00102 property LastResultSet: IZResultSet
00103 read FLastResultSet write SetLastResultSet;
00104 property FetchDirection: TZFetchDirection
00105 read FFetchDirection write FFetchDirection;
00106 property FetchSize: Integer read FFetchSize write FFetchSize;
00107 property ResultSetConcurrency: TZResultSetConcurrency
00108 read FResultSetConcurrency write FResultSetConcurrency;
00109 property ResultSetType: TZResultSetType
00110 read FResultSetType write FResultSetType;
00111 property CursorName: string read FCursorName write FCursorName;
00112 property BatchQueries: TStrings read FBatchQueries;
00113 property Connection: IZConnection read FConnection;
00114 property Info: TStrings read FInfo;
00115 property Closed: Boolean read FClosed write FClosed;
00116
00117 public
00118 constructor Create(Connection: IZConnection; Info: TStrings);
00119 destructor Destroy; override;
00120
00121 function ExecuteQuery(const SQL: string): IZResultSet; virtual;
00122 function ExecuteUpdate(const SQL: string): Integer; virtual;
00123 procedure Close; virtual;
00124
00125 function GetMaxFieldSize: Integer; virtual;
00126 procedure SetMaxFieldSize(Value: Integer); virtual;
00127 function GetMaxRows: Integer; virtual;
00128 procedure SetMaxRows(Value: Integer); virtual;
00129 procedure SetEscapeProcessing(Value: Boolean); virtual;
00130 function GetQueryTimeout: Integer; virtual;
00131 procedure SetQueryTimeout(Value: Integer); virtual;
00132 procedure Cancel; virtual;
00133 procedure SetCursorName(const Value: string); virtual;
00134
00135 function Execute(const SQL: string): Boolean; virtual;
00136 function GetResultSet: IZResultSet; virtual;
00137 function GetUpdateCount: Integer; virtual;
00138 function GetMoreResults: Boolean; virtual;
00139
00140 procedure SetFetchDirection(Value: TZFetchDirection); virtual;
00141 function GetFetchDirection: TZFetchDirection; virtual;
00142 procedure SetFetchSize(Value: Integer); virtual;
00143 function GetFetchSize: Integer; virtual;
00144
00145 procedure SetResultSetConcurrency(Value: TZResultSetConcurrency); virtual;
00146 function GetResultSetConcurrency: TZResultSetConcurrency; virtual;
00147 procedure SetResultSetType(Value: TZResultSetType); virtual;
00148 function GetResultSetType: TZResultSetType; virtual;
00149
00150 procedure SetPostUpdates(Value: TZPostUpdatesMode);
00151 function GetPostUpdates: TZPostUpdatesMode;
00152 procedure SetLocateUpdates(Value: TZLocateUpdatesMode);
00153 function GetLocateUpdates: TZLocateUpdatesMode;
00154
00155 procedure AddBatch(const SQL: string); virtual;
00156 procedure ClearBatch; virtual;
00157 function ExecuteBatch: TIntegerDynArray; virtual;
00158
00159 function GetConnection: IZConnection;
00160 function GetParameters: TStrings;
00161
00162 function GetWarnings: EZSQLWarning; virtual;
00163 procedure ClearWarnings; virtual;
00164 end;
00165
00166 {** Implements Abstract Prepared SQL Statement. }
00167 TZAbstractPreparedStatement = class(TZAbstractStatement, IZPreparedStatement)
00168 private
00169 FSQL: string;
00170 FInParamValues: TZVariantDynArray;
00171 FInParamTypes: TZSQLTypeArray;
00172 FInParamDefaultValues: TStringDynArray;
00173 FInParamCount: Integer;
00174 protected
00175 procedure SetInParamCount(NewParamCount: Integer); virtual;
00176 procedure SetInParam(ParameterIndex: Integer; SQLType: TZSQLType;
00177 const Value: TZVariant); virtual;
00178
00179 property SQL: string read FSQL write FSQL;
00180 property InParamValues: TZVariantDynArray
00181 read FInParamValues write FInParamValues;
00182 property InParamTypes: TZSQLTypeArray
00183 read FInParamTypes write FInParamTypes;
00184 property InParamDefaultValues: TStringDynArray
00185 read FInParamDefaultValues write FInParamDefaultValues;
00186 property InParamCount: Integer read FInParamCount write FInParamCount;
00187 public
00188 constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);
00189 destructor Destroy; override;
00190
00191 function ExecuteQueryPrepared: IZResultSet; virtual;
00192 function ExecuteUpdatePrepared: Integer; virtual;
00193 function ExecutePrepared: Boolean; virtual;
00194
00195 procedure SetDefaultValue(ParameterIndex: Integer; const Value: string);
00196
00197 procedure SetNull(ParameterIndex: Integer; SQLType: TZSQLType); virtual;
00198 procedure SetBoolean(ParameterIndex: Integer; Value: Boolean); virtual;
00199 procedure SetByte(ParameterIndex: Integer; Value: ShortInt); virtual;
00200 procedure SetShort(ParameterIndex: Integer; Value: SmallInt); virtual;
00201 procedure SetInt(ParameterIndex: Integer; Value: Integer); virtual;
00202 procedure SetLong(ParameterIndex: Integer; Value: Int64); virtual;
00203 procedure SetFloat(ParameterIndex: Integer; Value: Single); virtual;
00204 procedure SetDouble(ParameterIndex: Integer; Value: Double); virtual;
00205 procedure SetBigDecimal(ParameterIndex: Integer; Value: Extended); virtual;
00206 procedure SetPChar(ParameterIndex: Integer; Value: PChar); virtual;
00207 procedure SetString(ParameterIndex: Integer; const Value: string); virtual;
00208 procedure SetUnicodeString(ParameterIndex: Integer;
00209 const Value: WideString); virtual;
00210 procedure SetBytes(ParameterIndex: Integer; const Value: TByteDynArray); virtual;
00211 procedure SetDate(ParameterIndex: Integer; Value: TDateTime); virtual;
00212 procedure SetTime(ParameterIndex: Integer; Value: TDateTime); virtual;
00213 procedure SetTimestamp(ParameterIndex: Integer; Value: TDateTime); virtual;
00214 procedure SetAsciiStream(ParameterIndex: Integer; Value: TStream); virtual;
00215 procedure SetUnicodeStream(ParameterIndex: Integer; Value: TStream); virtual;
00216 procedure SetBinaryStream(ParameterIndex: Integer; Value: TStream); virtual;
00217 procedure SetBlob(ParameterIndex: Integer; SQLType: TZSQLType;
00218 Value: IZBlob); virtual;
00219 procedure SetValue(ParameterIndex: Integer; const Value: TZVariant); virtual;
00220
00221 procedure ClearParameters; virtual;
00222
00223 procedure AddBatchPrepared; virtual;
00224 function GetMetaData: IZResultSetMetaData; virtual;
00225 end;
00226
00227 {** Implements Abstract Callable SQL statement. }
00228 TZAbstractCallableStatement = class(TZAbstractPreparedStatement,
00229 IZCallableStatement)
00230 private
00231 FOutParamValues: TZVariantDynArray;
00232 FOutParamTypes: TZSQLTypeArray;
00233 FOutParamCount: Integer;
00234 FLastWasNull: Boolean;
00235 FTemp: string;
00236 protected
00237 procedure SetOutParamCount(NewParamCount: Integer); virtual;
00238 function GetOutParam(ParameterIndex: Integer): TZVariant; virtual;
00239
00240 property OutParamValues: TZVariantDynArray
00241 read FOutParamValues write FOutParamValues;
00242 property OutParamTypes: TZSQLTypeArray
00243 read FOutParamTypes write FOutParamTypes;
00244 property OutParamCount: Integer read FOutParamCount write FOutParamCount;
00245 property LastWasNull: Boolean read FLastWasNull write FLastWasNull;
00246 public
00247 constructor Create(Connection: IZConnection; SQL: string; Info: TStrings);
00248 procedure ClearParameters; override;
00249 procedure RegisterOutParameter(ParameterIndex: Integer;
00250 SQLType: Integer); virtual;
00251 function WasNull: Boolean; virtual;
00252
00253 function IsNull(ParameterIndex: Integer): Boolean; virtual;
00254 function GetPChar(ParameterIndex: Integer): PChar; virtual;
00255 function GetString(ParameterIndex: Integer): string; virtual;
00256 function GetUnicodeString(ParameterIndex: Integer): WideString; virtual;
00257 function GetBoolean(ParameterIndex: Integer): Boolean; virtual;
00258 function GetByte(ParameterIndex: Integer): ShortInt; virtual;
00259 function GetShort(ParameterIndex: Integer): SmallInt; virtual;
00260 function GetInt(ParameterIndex: Integer): Integer; virtual;
00261 function GetLong(ParameterIndex: Integer): Int64; virtual;
00262 function GetFloat(ParameterIndex: Integer): Single; virtual;
00263 function GetDouble(ParameterIndex: Integer): Double; virtual;
00264 function GetBigDecimal(ParameterIndex: Integer): Extended; virtual;
00265 function GetBytes(ParameterIndex: Integer): TByteDynArray; virtual;
00266 function GetDate(ParameterIndex: Integer): TDateTime; virtual;
00267 function GetTime(ParameterIndex: Integer): TDateTime; virtual;
00268 function GetTimestamp(ParameterIndex: Integer): TDateTime; virtual;
00269 function GetValue(ParameterIndex: Integer): TZVariant; virtual;
00270 end;
00271
00272 {** Implements an Emulated Prepared SQL Statement. }
00273 TZEmulatedPreparedStatement = class(TZAbstractPreparedStatement)
00274 private
00275 FExecStatement: IZStatement;
00276 FCachedQuery: TStrings;
00277 FLastStatement: IZStatement;
00278
00279 procedure SetLastStatement(LastStatement: IZStatement);
00280
00281 protected
00282 property ExecStatement: IZStatement read FExecStatement write FExecStatement;
00283 property CachedQuery: TStrings read FCachedQuery write FCachedQuery;
00284 property LastStatement: IZStatement read FLastStatement write SetLastStatement;
00285
00286 function CreateExecStatement: IZStatement; virtual; abstract;
00287 function PrepareSQLParam(ParamIndex: Integer): string; virtual; abstract;
00288 function GetExecStatement: IZStatement;
00289 function TokenizeSQLQuery: TStrings;
00290 function PrepareSQLQuery: string; virtual;
00291
00292 public
00293 destructor Destroy; override;
00294
00295 procedure Close; override;
00296
00297 function ExecuteQuery(const SQL: string): IZResultSet; override;
00298 function ExecuteUpdate(const SQL: string): Integer; override;
00299 function Execute(const SQL: string): Boolean; override;
00300
00301 function ExecuteQueryPrepared: IZResultSet; override;
00302 function ExecuteUpdatePrepared: Integer; override;
00303 function ExecutePrepared: Boolean; override;
00304 end;
00305
00306 implementation
00307
00308 uses ZSysUtils, ZMessages, ZDbcResultSet;
00309
00310 { TZAbstractStatement }
00311
00312 {**
00313 Constructs this class and defines the main properties.
00314 @param Connection a database connection object.
00315 @param Info a statement parameters;
00316 }
00317 constructor TZAbstractStatement.Create(Connection: IZConnection; Info: TStrings);
00318 begin
00319 { Sets the default properties. }
00320 FMaxFieldSize := 0;
00321 FMaxRows := 0;
00322 FEscapeProcessing := False;
00323 FQueryTimeout := 0;
00324 FLastUpdateCount := -1;
00325 FLastResultSet := nil;
00326 FFetchDirection := fdForward;
00327 FFetchSize := 0;
00328 FResultSetConcurrency := rcReadOnly;
00329 FResultSetType := rtForwardOnly;
00330 FCursorName := '';
00331
00332 FConnection := Connection;
00333 FBatchQueries := TStringList.Create;
00334
00335 FInfo := TStringList.Create;
00336 if Info <> nil then
00337 FInfo.AddStrings(Info);
00338 end;
00339
00340 {**
00341 Destroys this object and cleanups the memory.
00342 }
00343 destructor TZAbstractStatement.Destroy;
00344 begin
00345 Close;
00346 if Assigned(FBatchQueries) then
00347 FBatchQueries.Free;
00348 FBatchQueries := nil;
00349 FConnection := nil;
00350 FInfo.Free;
00351 FLastResultSet := nil;
00352 inherited Destroy;
00353 end;
00354
00355 {**
00356 Raises unsupported operation exception.
00357 }
00358 procedure TZAbstractStatement.RaiseUnsupportedException;
00359 begin
00360 raise EZSQLException.Create(SUnsupportedOperation);
00361 end;
00362
00363 {**
00364 Sets a last result set to avoid problems with reference counting.
00365 @param ResultSet the lastest executed result set.
00366 }
00367 procedure TZAbstractStatement.SetLastResultSet(ResultSet: IZResultSet);
00368 begin
00369 if (FLastResultSet <> nil) then
00370 FLastResultSet.Close;
00371
00372 FLastResultSet := ResultSet;
00373 end;
00374
00375 {**
00376 Executes an SQL statement that returns a single <code>ResultSet</code> object.
00377 @param sql typically this is a static SQL <code>SELECT</code> statement
00378 @return a <code>ResultSet</code> object that contains the data produced by the
00379 given query; never <code>null</code>
00380 }
00381 function TZAbstractStatement.ExecuteQuery(const SQL: string): IZResultSet;
00382 begin
00383 Result := nil;
00384 RaiseUnsupportedException;
00385 end;
00386
00387 {**
00388 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
00389 <code>DELETE</code> statement. In addition,
00390 SQL statements that return nothing, such as SQL DDL statements,
00391 can be executed.
00392
00393 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
00394 <code>DELETE</code> statement or an SQL statement that returns nothing
00395 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
00396 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
00397 }
00398 function TZAbstractStatement.ExecuteUpdate(const SQL: string): Integer;
00399 begin
00400 Result := 0;
00401 RaiseUnsupportedException;
00402 end;
00403
00404 {**
00405 Releases this <code>Statement</code> object's database
00406 and JDBC resources immediately instead of waiting for
00407 this to happen when it is automatically closed.
00408 It is generally good practice to release resources as soon as
00409 you are finished with them to avoid tying up database
00410 resources.
00411 <P><B>Note:</B> A <code>Statement</code> object is automatically closed when it is
00412 garbage collected. When a <code>Statement</code> object is closed, its current
00413 <code>ResultSet</code> object, if one exists, is also closed.
00414 }
00415 procedure TZAbstractStatement.Close;
00416 begin
00417 if LastResultSet <> nil then
00418 begin
00419 LastResultSet.Close;
00420 LastResultSet := nil;
00421 end;
00422 FClosed := True;
00423 end;
00424
00425 {**
00426 Returns the maximum number of bytes allowed
00427 for any column value.
00428 This limit is the maximum number of bytes that can be
00429 returned for any column value.
00430 The limit applies only to <code>BINARY</code>,
00431 <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and <code>LONGVARCHAR</code>
00432 columns. If the limit is exceeded, the excess data is silently
00433 discarded.
00434 @return the current max column size limit; zero means unlimited
00435 }
00436 function TZAbstractStatement.GetMaxFieldSize: Integer;
00437 begin
00438 Result := FMaxFieldSize;
00439 end;
00440
00441 {**
00442 Sets the limit for the maximum number of bytes in a column to
00443 the given number of bytes. This is the maximum number of bytes
00444 that can be returned for any column value. This limit applies
00445 only to <code>BINARY</code>, <code>VARBINARY</code>,
00446 <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and
00447 <code>LONGVARCHAR</code> fields. If the limit is exceeded, the excess data
00448 is silently discarded. For maximum portability, use values
00449 greater than 256.
00450
00451 @param max the new max column size limit; zero means unlimited
00452 }
00453 procedure TZAbstractStatement.SetMaxFieldSize(Value: Integer);
00454 begin
00455 FMaxFieldSize := Value;
00456 end;
00457
00458 {**
00459 Retrieves the maximum number of rows that a
00460 <code>ResultSet</code> object can contain. If the limit is exceeded, the excess
00461 rows are silently dropped.
00462
00463 @return the current max row limit; zero means unlimited
00464 }
00465 function TZAbstractStatement.GetMaxRows: Integer;
00466 begin
00467 Result := FMaxRows;
00468 end;
00469
00470 {**
00471 Sets the limit for the maximum number of rows that any
00472 <code>ResultSet</code> object can contain to the given number.
00473 If the limit is exceeded, the excess rows are silently dropped.
00474
00475 @param max the new max rows limit; zero means unlimited
00476 }
00477 procedure TZAbstractStatement.SetMaxRows(Value: Integer);
00478 begin
00479 FMaxRows := Value;
00480 end;
00481
00482 {**
00483 Sets escape processing on or off.
00484 If escape scanning is on (the default), the driver will do
00485 escape substitution before sending the SQL to the database.
00486
00487 Note: Since prepared statements have usually been parsed prior
00488 to making this call, disabling escape processing for prepared
00489 statements will have no effect.
00490
00491 @param enable <code>true</code> to enable; <code>false</code> to disable
00492 }
00493 procedure TZAbstractStatement.SetEscapeProcessing(Value: Boolean);
00494 begin
00495 FEscapeProcessing := Value;
00496 end;
00497
00498 {**
00499 Retrieves the number of seconds the driver will
00500 wait for a <code>Statement</code> object to execute. If the limit is exceeded, a
00501 <code>SQLException</code> is thrown.
00502
00503 @return the current query timeout limit in seconds; zero means unlimited
00504 }
00505 function TZAbstractStatement.GetQueryTimeout: Integer;
00506 begin
00507 Result := FQueryTimeout;
00508 end;
00509
00510 {**
00511 Sets the number of seconds the driver will
00512 wait for a <code>Statement</code> object to execute to the given number of seconds.
00513 If the limit is exceeded, an <code>SQLException</code> is thrown.
00514
00515 @param seconds the new query timeout limit in seconds; zero means unlimited
00516 }
00517 procedure TZAbstractStatement.SetQueryTimeout(Value: Integer);
00518 begin
00519 FQueryTimeout := Value;
00520 end;
00521
00522 {**
00523 Cancels this <code>Statement</code> object if both the DBMS and
00524 driver support aborting an SQL statement.
00525 This method can be used by one thread to cancel a statement that
00526 is being executed by another thread.
00527 }
00528 procedure TZAbstractStatement.Cancel;
00529 begin
00530 RaiseUnsupportedException;
00531 end;
00532
00533 {**
00534 Retrieves the first warning reported by calls on this <code>Statement</code> object.
00535 Subsequent <code>Statement</code> object warnings will be chained to this
00536 <code>SQLWarning</code> object.
00537
00538 <p>The warning chain is automatically cleared each time
00539 a statement is (re)executed.
00540
00541 <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any
00542 warnings associated with reads on that <code>ResultSet</code> object
00543 will be chained on it.
00544
00545 @return the first <code>SQLWarning</code> object or <code>null</code>
00546 }
00547 function TZAbstractStatement.GetWarnings: EZSQLWarning;
00548 begin
00549 Result := nil;
00550 end;
00551
00552 {**
00553 Clears all the warnings reported on this <code>Statement</code>
00554 object. After a call to this method,
00555 the method <code>getWarnings</code> will return
00556 <code>null</code> until a new warning is reported for this
00557 <code>Statement</code> object.
00558 }
00559 procedure TZAbstractStatement.ClearWarnings;
00560 begin
00561 end;
00562
00563 {**
00564 Defines the SQL cursor name that will be used by
00565 subsequent <code>Statement</code> object <code>execute</code> methods.
00566 This name can then be
00567 used in SQL positioned update/delete statements to identify the
00568 current row in the <code>ResultSet</code> object generated by this statement. If
00569 the database doesn't support positioned update/delete, this
00570 method is a noop. To insure that a cursor has the proper isolation
00571 level to support updates, the cursor's <code>SELECT</code> statement should be
00572 of the form 'select for update ...'. If the 'for update' phrase is
00573 omitted, positioned updates may fail.
00574
00575 <P><B>Note:</B> By definition, positioned update/delete
00576 execution must be done by a different <code>Statement</code> object than the one
00577 which generated the <code>ResultSet</code> object being used for positioning. Also,
00578 cursor names must be unique within a connection.
00579
00580 @param name the new cursor name, which must be unique within a connection
00581 }
00582 procedure TZAbstractStatement.SetCursorName(const Value: string);
00583 begin
00584 FCursorName := Value;
00585 end;
00586
00587 {**
00588 Executes an SQL statement that may return multiple results.
00589 Under some (uncommon) situations a single SQL statement may return
00590 multiple result sets and/or update counts. Normally you can ignore
00591 this unless you are (1) executing a stored procedure that you know may
00592 return multiple results or (2) you are dynamically executing an
00593 unknown SQL string. The methods <code>execute</code>,
00594 <code>getMoreResults</code>, <code>getResultSet</code>,
00595 and <code>getUpdateCount</code> let you navigate through multiple results.
00596
00597 The <code>execute</code> method executes an SQL statement and indicates the
00598 form of the first result. You can then use the methods
00599 <code>getResultSet</code> or <code>getUpdateCount</code>
00600 to retrieve the result, and <code>getMoreResults</code> to
00601 move to any subsequent result(s).
00602
00603 @param sql any SQL statement
00604 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
00605 <code>false</code> if it is an update count or there are no more results
00606 @see #getResultSet
00607 @see #getUpdateCount
00608 @see #getMoreResults
00609 }
00610 function TZAbstractStatement.Execute(const SQL: string): Boolean;
00611 begin
00612 Result := False;
00613 LastResultSet := nil;
00614 LastUpdateCount := -1;
00615 end;
00616
00617 {**
00618 Returns the current result as a <code>ResultSet</code> object.
00619 This method should be called only once per result.
00620
00621 @return the current result as a <code>ResultSet</code> object;
00622 <code>null</code> if the result is an update count or there are no more results
00623 @see #execute
00624 }
00625 function TZAbstractStatement.GetResultSet: IZResultSet;
00626 begin
00627 Result := LastResultSet;
00628 end;
00629
00630 {**
00631 Returns the current result as an update count;
00632 if the result is a <code>ResultSet</code> object or there are no more results, -1
00633 is returned. This method should be called only once per result.
00634
00635 @return the current result as an update count; -1 if the current result is a
00636 <code>ResultSet</code> object or there are no more results
00637 @see #execute
00638 }
00639 function TZAbstractStatement.GetUpdateCount: Integer;
00640 begin
00641 Result := FLastUpdateCount;
00642 end;
00643
00644 {**
00645 Moves to a <code>Statement</code> object's next result. It returns
00646 <code>true</code> if this result is a <code>ResultSet</code> object.
00647 This method also implicitly closes any current <code>ResultSet</code>
00648 object obtained with the method <code>getResultSet</code>.
00649
00650 <P>There are no more results when the following is true:
00651 <PRE>
00652 <code>(!getMoreResults() && (getUpdateCount() == -1)</code>
00653 </PRE>
00654
00655 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
00656 <code>false</code> if it is an update count or there are no more results
00657 @see #execute
00658 }
00659 function TZAbstractStatement.GetMoreResults: Boolean;
00660 begin
00661 Result := False;
00662 end;
00663
00664 {**
00665 Retrieves the direction for fetching rows from
00666 database tables that is the default for result sets
00667 generated from this <code>Statement</code> object.
00668 If this <code>Statement</code> object has not set
00669 a fetch direction by calling the method <code>setFetchDirection</code>,
00670 the return value is implementation-specific.
00671
00672 @return the default fetch direction for result sets generated
00673 from this <code>Statement</code> object
00674 }
00675 function TZAbstractStatement.GetFetchDirection: TZFetchDirection;
00676 begin
00677 Result := FFetchDirection;
00678 end;
00679
00680 {**
00681 Gives the driver a hint as to the direction in which
00682 the rows in a result set
00683 will be processed. The hint applies only to result sets created
00684 using this <code>Statement</code> object. The default value is
00685 <code>ResultSet.FETCH_FORWARD</code>.
00686 <p>Note that this method sets the default fetch direction for
00687 result sets generated by this <code>Statement</code> object.
00688 Each result set has its own methods for getting and setting
00689 its own fetch direction.
00690 @param direction the initial direction for processing rows
00691 }
00692 procedure TZAbstractStatement.SetFetchDirection(Value: TZFetchDirection);
00693 begin
00694 FFetchDirection := Value;
00695 end;
00696
00697 {**
00698 Retrieves the number of result set rows that is the default
00699 fetch size for result sets
00700 generated from this <code>Statement</code> object.
00701 If this <code>Statement</code> object has not set
00702 a fetch size by calling the method <code>setFetchSize</code>,
00703 the return value is implementation-specific.
00704 @return the default fetch size for result sets generated
00705 from this <code>Statement</code> object
00706 }
00707 function TZAbstractStatement.GetFetchSize: Integer;
00708 begin
00709 Result := FFetchSize;
00710 end;
00711
00712 {**
00713 Gives the JDBC driver a hint as to the number of rows that should
00714 be fetched from the database when more rows are needed. The number
00715 of rows specified affects only result sets created using this
00716 statement. If the value specified is zero, then the hint is ignored.
00717 The default value is zero.
00718
00719 @param rows the number of rows to fetch
00720 }
00721 procedure TZAbstractStatement.SetFetchSize(Value: Integer);
00722 begin
00723 FFetchSize := Value;
00724 end;
00725
00726 {**
00727 Sets a result set concurrency for <code>ResultSet</code> objects
00728 generated by this <code>Statement</code> object.
00729
00730 @param Concurrency either <code>ResultSet.CONCUR_READ_ONLY</code> or
00731 <code>ResultSet.CONCUR_UPDATABLE</code>
00732 }
00733 procedure TZAbstractStatement.SetResultSetConcurrency(
00734 Value: TZResultSetConcurrency);
00735 begin
00736 FResultSetConcurrency := Value;
00737 end;
00738
00739 {**
00740 Retrieves the result set concurrency for <code>ResultSet</code> objects
00741 generated by this <code>Statement</code> object.
00742
00743 @return either <code>ResultSet.CONCUR_READ_ONLY</code> or
00744 <code>ResultSet.CONCUR_UPDATABLE</code>
00745 }
00746 function TZAbstractStatement.GetResultSetConcurrency: TZResultSetConcurrency;
00747 begin
00748 Result := FResultSetConcurrency;
00749 end;
00750
00751 {**
00752 Sets a result set type for <code>ResultSet</code> objects
00753 generated by this <code>Statement</code> object.
00754
00755 @param ResultSetType one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
00756 <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
00757 <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
00758 }
00759 procedure TZAbstractStatement.SetResultSetType(Value: TZResultSetType);
00760 begin
00761 FResultSetType := Value;
00762 end;
00763
00764 {**
00765 Retrieves the result set type for <code>ResultSet</code> objects
00766 generated by this <code>Statement</code> object.
00767
00768 @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
00769 <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
00770 <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
00771 }
00772 function TZAbstractStatement.GetResultSetType: TZResultSetType;
00773 begin
00774 Result := FResultSetType;
00775 end;
00776
00777 {**
00778 Gets the current value for locate updates.
00779 @returns the current value for locate updates.
00780 }
00781 function TZAbstractStatement.GetLocateUpdates: TZLocateUpdatesMode;
00782 begin
00783 Result := FLocateUpdates;
00784 end;
00785
00786 {**
00787 Sets a new value for locate updates.
00788 @param Value a new value for locate updates.
00789 }
00790 procedure TZAbstractStatement.SetLocateUpdates(Value: TZLocateUpdatesMode);
00791 begin
00792 FLocateUpdates := Value;
00793 end;
00794
00795 {**
00796 Gets the current value for post updates.
00797 @returns the current value for post updates.
00798 }
00799 function TZAbstractStatement.GetPostUpdates: TZPostUpdatesMode;
00800 begin
00801 Result := FPostUpdates;
00802 end;
00803
00804 {**
00805 Sets a new value for post updates.
00806 @param Value a new value for post updates.
00807 }
00808 procedure TZAbstractStatement.SetPostUpdates(Value: TZPostUpdatesMode);
00809 begin
00810 FPostUpdates := Value;
00811 end;
00812
00813 {**
00814 Adds an SQL command to the current batch of commmands for this
00815 <code>Statement</code> object. This method is optional.
00816
00817 @param sql typically this is a static SQL <code>INSERT</code> or
00818 <code>UPDATE</code> statement
00819 }
00820 procedure TZAbstractStatement.AddBatch(const SQL: string);
00821 begin
00822 FBatchQueries.Add(SQL);
00823 end;
00824
00825 {**
00826 Makes the set of commands in the current batch empty.
00827 This method is optional.
00828 }
00829 procedure TZAbstractStatement.ClearBatch;
00830 begin
00831 FBatchQueries.Clear;
00832 end;
00833
00834 {**
00835 Submits a batch of commands to the database for execution and
00836 if all commands execute successfully, returns an array of update counts.
00837 The <code>int</code> elements of the array that is returned are ordered
00838 to correspond to the commands in the batch, which are ordered
00839 according to the order in which they were added to the batch.
00840 The elements in the array returned by the method <code>executeBatch</code>
00841 may be one of the following:
00842 <OL>
00843 <LI>A number greater than or equal to zero -- indicates that the
00844 command was processed successfully and is an update count giving the
00845 number of rows in the database that were affected by the command's
00846 execution
00847 <LI>A value of <code>-2</code> -- indicates that the command was
00848 processed successfully but that the number of rows affected is
00849 unknown
00850 <P>
00851 If one of the commands in a batch update fails to execute properly,
00852 this method throws a <code>BatchUpdateException</code>, and a JDBC
00853 driver may or may not continue to process the remaining commands in
00854 the batch. However, the driver's behavior must be consistent with a
00855 particular DBMS, either always continuing to process commands or never
00856 continuing to process commands. If the driver continues processing
00857 after a failure, the array returned by the method
00858 <code>BatchUpdateException.getUpdateCounts</code>
00859 will contain as many elements as there are commands in the batch, and
00860 at least one of the elements will be the following:
00861 <P>
00862 <LI>A value of <code>-3</code> -- indicates that the command failed
00863 to execute successfully and occurs only if a driver continues to
00864 process commands after a command fails
00865 </OL>
00866 <P>
00867 A driver is not required to implement this method.
00868 The possible implementations and return values have been modified in
00869 the Java 2 SDK, Standard Edition, version 1.3 to
00870 accommodate the option of continuing to proccess commands in a batch
00871 update after a <code>BatchUpdateException</code> obejct has been thrown.
00872
00873 @return an array of update counts containing one element for each
00874 command in the batch. The elements of the array are ordered according
00875 to the order in which commands were added to the batch.
00876 }
00877 function TZAbstractStatement.ExecuteBatch: TIntegerDynArray;
00878 var
00879 I: Integer;
00880 begin
00881 SetLength(Result, FBatchQueries.Count);
00882 for I := 0 to FBatchQueries.Count -1 do
00883 Result[I] := ExecuteUpdate(FBatchQueries[I]);
00884 ClearBatch;
00885 end;
00886
00887 {**
00888 Returns the <code>Connection</code> object
00889 that produced this <code>Statement</code> object.
00890 @return the connection that produced this statement
00891 }
00892 function TZAbstractStatement.GetConnection: IZConnection;
00893 begin
00894 Result := FConnection;
00895 end;
00896
00897 {**
00898 Gets statement parameters.
00899 @returns a list with statement parameters.
00900 }
00901 function TZAbstractStatement.GetParameters: TStrings;
00902 begin
00903 Result := FInfo;
00904 end;
00905
00906 { TZAbstractPreparedStatement }
00907
00908 {**
00909 Constructs this object and assigns main properties.
00910 @param Connection a database connection object.
00911 @param Sql a prepared Sql statement.
00912 @param Info a statement parameters.
00913 }
00914 constructor TZAbstractPreparedStatement.Create(Connection: IZConnection;
00915 const SQL: string; Info: TStrings);
00916 begin
00917 inherited Create(Connection, Info);
00918 FSQL := SQL;
00919 FInParamCount := 0;
00920 SetInParamCount(0);
00921 end;
00922
00923 {**
00924 Destroys this object and cleanups the memory.
00925 }
00926 destructor TZAbstractPreparedStatement.Destroy;
00927 begin
00928 inherited Destroy;
00929 ClearParameters;
00930 end;
00931
00932 {**
00933 Sets a new parameter count and initializes the buffers.
00934 @param NewParamCount a new parameters count.
00935 }
00936 procedure TZAbstractPreparedStatement.SetInParamCount(NewParamCount: Integer);
00937 var
00938 I: Integer;
00939 begin
00940 SetLength(FInParamValues, NewParamCount);
00941 SetLength(FInParamTypes, NewParamCount);
00942 SetLength(FInParamDefaultValues, NewParamCount);
00943 for I := FInParamCount to NewParamCount - 1 do
00944 begin
00945 FInParamValues[I] := NullVariant;
00946 FInParamTypes[I] := stUnknown;
00947
00948 FInParamDefaultValues[I] := '';
00949 end;
00950 FInParamCount := NewParamCount;
00951 end;
00952
00953 {**
00954 Sets a variant value into specified parameter.
00955 @param ParameterIndex a index of the parameter.
00956 @param SqlType a parameter SQL type.
00957 @paran Value a new parameter value.
00958 }
00959 procedure TZAbstractPreparedStatement.SetInParam(ParameterIndex: Integer;
00960 SQLType: TZSQLType; const Value: TZVariant);
00961 begin
00962 if ParameterIndex >= FInParamCount then
00963 SetInParamCount(ParameterIndex);
00964
00965 FInParamTypes[ParameterIndex - 1] := SQLType;
00966 FInParamValues[ParameterIndex - 1] := Value;
00967 end;
00968
00969 {**
00970 Executes the SQL query in this <code>PreparedStatement</code> object
00971 and returns the result set generated by the query.
00972
00973 @return a <code>ResultSet</code> object that contains the data produced by the
00974 query; never <code>null</code>
00975 }
00976 function TZAbstractPreparedStatement.ExecuteQueryPrepared: IZResultSet;
00977 begin
00978 Result := nil;
00979 RaiseUnsupportedException;
00980 end;
00981
00982 {**
00983 Executes the SQL INSERT, UPDATE or DELETE statement
00984 in this <code>PreparedStatement</code> object.
00985 In addition,
00986 SQL statements that return nothing, such as SQL DDL statements,
00987 can be executed.
00988
00989 @return either the row count for INSERT, UPDATE or DELETE statements;
00990 or 0 for SQL statements that return nothing
00991 }
00992 function TZAbstractPreparedStatement.ExecuteUpdatePrepared: Integer;
00993 begin
00994 Result := -1;
00995 RaiseUnsupportedException;
00996 end;
00997
00998 {**
00999 Sets the designated parameter the default SQL value.
01000 <P><B>Note:</B> You must specify the default value.
01001
01002 @param parameterIndex the first parameter is 1, the second is 2, ...
01003 @param Value the default value normally defined in the field's DML SQL statement
01004 }
01005 procedure TZAbstractPreparedStatement.SetDefaultValue(
01006 ParameterIndex: Integer; const Value: string);
01007 begin
01008 if ParameterIndex >= FInParamCount then
01009 SetInParamCount(ParameterIndex);
01010
01011 FInParamDefaultValues[ParameterIndex - 1] := Value;
01012 end;
01013
01014 {**
01015 Sets the designated parameter to SQL <code>NULL</code>.
01016 <P><B>Note:</B> You must specify the parameter's SQL type.
01017
01018 @param parameterIndex the first parameter is 1, the second is 2, ...
01019 @param sqlType the SQL type code defined in <code>java.sql.Types</code>
01020 }
01021 procedure TZAbstractPreparedStatement.SetNull(ParameterIndex: Integer;
01022 SQLType: TZSQLType);
01023 begin
01024 SetInParam(ParameterIndex, SQLType, NullVariant);
01025 end;
01026
01027 {**
01028 Sets the designated parameter to a Java <code>boolean</code> value.
01029 The driver converts this
01030 to an SQL <code>BIT</code> value when it sends it to the database.
01031
01032 @param parameterIndex the first parameter is 1, the second is 2, ...
01033 @param x the parameter value
01034 }
01035 procedure TZAbstractPreparedStatement.SetBoolean(ParameterIndex: Integer;
01036 Value: Boolean);
01037 var
01038 Temp: TZVariant;
01039 begin
01040 DefVarManager.SetAsBoolean(Temp, Value);
01041 SetInParam(ParameterIndex, stBoolean, Temp);
01042 end;
01043
01044 {**
01045 Sets the designated parameter to a Java <code>byte</code> value.
01046 The driver converts this
01047 to an SQL <code>TINYINT</code> value when it sends it to the database.
01048
01049 @param parameterIndex the first parameter is 1, the second is 2, ...
01050 @param x the parameter value
01051 }
01052 procedure TZAbstractPreparedStatement.SetByte(ParameterIndex: Integer;
01053 Value: ShortInt);
01054 var
01055 Temp: TZVariant;
01056 begin
01057 DefVarManager.SetAsInteger(Temp, Value);
01058 SetInParam(ParameterIndex, stByte, Temp);
01059 end;
01060
01061 {**
01062 Sets the designated parameter to a Java <code>short</code> value.
01063 The driver converts this
01064 to an SQL <code>SMALLINT</code> value when it sends it to the database.
01065
01066 @param parameterIndex the first parameter is 1, the second is 2, ...
01067 @param x the parameter value
01068 }
01069 procedure TZAbstractPreparedStatement.SetShort(ParameterIndex: Integer;
01070 Value: SmallInt);
01071 var
01072 Temp: TZVariant;
01073 begin
01074 DefVarManager.SetAsInteger(Temp, Value);
01075 SetInParam(ParameterIndex, stShort, Temp);
01076 end;
01077
01078 {**
01079 Sets the designated parameter to a Java <code>int</code> value.
01080 The driver converts this
01081 to an SQL <code>INTEGER</code> value when it sends it to the database.
01082
01083 @param parameterIndex the first parameter is 1, the second is 2, ...
01084 @param x the parameter value
01085 }
01086 procedure TZAbstractPreparedStatement.SetInt(ParameterIndex,
01087 Value: Integer);
01088 var
01089 Temp: TZVariant;
01090 begin
01091 DefVarManager.SetAsInteger(Temp, Value);
01092 SetInParam(ParameterIndex, stInteger, Temp);
01093 end;
01094
01095 {**
01096 Sets the designated parameter to a Java <code>long</code> value.
01097 The driver converts this
01098 to an SQL <code>BIGINT</code> value when it sends it to the database.
01099
01100 @param parameterIndex the first parameter is 1, the second is 2, ...
01101 @param x the parameter value
01102 }
01103 procedure TZAbstractPreparedStatement.SetLong(ParameterIndex: Integer;
01104 Value: Int64);
01105 var
01106 Temp: TZVariant;
01107 begin
01108 DefVarManager.SetAsInteger(Temp, Value);
01109 SetInParam(ParameterIndex, stLong, Temp);
01110 end;
01111
01112 {**
01113 Sets the designated parameter to a Java <code>float</code> value.
01114 The driver converts this
01115 to an SQL <code>FLOAT</code> value when it sends it to the database.
01116
01117 @param parameterIndex the first parameter is 1, the second is 2, ...
01118 @param x the parameter value
01119 }
01120 procedure TZAbstractPreparedStatement.SetFloat(ParameterIndex: Integer;
01121 Value: Single);
01122 var
01123 Temp: TZVariant;
01124 begin
01125 DefVarManager.SetAsFloat(Temp, Value);
01126 SetInParam(ParameterIndex, stFloat, Temp);
01127 end;
01128
01129 {**
01130 Sets the designated parameter to a Java <code>double</code> value.
01131 The driver converts this
01132 to an SQL <code>DOUBLE</code> value when it sends it to the database.
01133
01134 @param parameterIndex the first parameter is 1, the second is 2, ...
01135 @param x the parameter value
01136 }
01137 procedure TZAbstractPreparedStatement.SetDouble(ParameterIndex: Integer;
01138 Value: Double);
01139 var
01140 Temp: TZVariant;
01141 begin
01142 DefVarManager.SetAsFloat(Temp, Value);
01143 SetInParam(ParameterIndex, stDouble, Temp);
01144 end;
01145
01146 {**
01147 Sets the designated parameter to a <code>java.math.BigDecimal</code> value.
01148 The driver converts this to an SQL <code>NUMERIC</code> value when
01149 it sends it to the database.
01150
01151 @param parameterIndex the first parameter is 1, the second is 2, ...
01152 @param x the parameter value
01153 }
01154 procedure TZAbstractPreparedStatement.SetBigDecimal(
01155 ParameterIndex: Integer; Value: Extended);
01156 var
01157 Temp: TZVariant;
01158 begin
01159 DefVarManager.SetAsFloat(Temp, Value);
01160 SetInParam(ParameterIndex, stBigDecimal, Temp);
01161 end;
01162
01163 {**
01164 Sets the designated parameter to a Java <code>String</code> value.
01165 The driver converts this
01166 to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
01167 (depending on the argument's
01168 size relative to the driver's limits on <code>VARCHAR</code> values)
01169 when it sends it to the database.
01170
01171 @param parameterIndex the first parameter is 1, the second is 2, ...
01172 @param x the parameter value
01173 }
01174 procedure TZAbstractPreparedStatement.SetPChar(ParameterIndex: Integer;
01175 Value: PChar);
01176 var
01177 Temp: TZVariant;
01178 begin
01179 DefVarManager.SetAsString(Temp, AnsiString(Value));
01180 SetInParam(ParameterIndex, stString, Temp);
01181 end;
01182
01183 {**
01184 Sets the designated parameter to a Java <code>String</code> value.
01185 The driver converts this
01186 to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
01187 (depending on the argument's
01188 size relative to the driver's limits on <code>VARCHAR</code> values)
01189 when it sends it to the database.
01190
01191 @param parameterIndex the first parameter is 1, the second is 2, ...
01192 @param x the parameter value
01193 }
01194 procedure TZAbstractPreparedStatement.SetString(ParameterIndex: Integer;
01195 const Value: string);
01196 var
01197 Temp: TZVariant;
01198 begin
01199 DefVarManager.SetAsString(Temp, Value);
01200 SetInParam(ParameterIndex, stString, Temp);
01201 end;
01202
01203 {**
01204 Sets the designated parameter to a Object Pascal <code>WideString</code>
01205 value. The driver converts this
01206 to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
01207 (depending on the argument's
01208 size relative to the driver's limits on <code>VARCHAR</code> values)
01209 when it sends it to the database.
01210
01211 @param parameterIndex the first parameter is 1, the second is 2, ...
01212 @param x the parameter value
01213 }
01214 procedure TZAbstractPreparedStatement.SetUnicodeString(ParameterIndex: Integer;
01215 const Value: WideString);
01216 var
01217 Temp: TZVariant;
01218 begin
01219 DefVarManager.SetAsUnicodeString(Temp, Value);
01220 SetInParam(ParameterIndex, stUnicodeString, Temp);
01221 end;
01222
01223 {**
01224 Sets the designated parameter to a Java array of bytes. The driver converts
01225 this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
01226 (depending on the argument's size relative to the driver's limits on
01227 <code>VARBINARY</code> values) when it sends it to the database.
01228
01229 @param parameterIndex the first parameter is 1, the second is 2, ...
01230 @param x the parameter value
01231 }
01232 procedure TZAbstractPreparedStatement.SetBytes(ParameterIndex: Integer;
01233 const Value: TByteDynArray);
01234 var
01235 Temp: TZVariant;
01236 begin
01237 DefVarManager.SetAsString(Temp, BytesToStr(Value));
01238 SetInParam(ParameterIndex, stBytes, Temp);
01239 end;
01240
01241 {**
01242 Sets the designated parameter to a <code<java.sql.Date</code> value.
01243 The driver converts this to an SQL <code>DATE</code>
01244 value when it sends it to the database.
01245
01246 @param parameterIndex the first parameter is 1, the second is 2, ...
01247 @param x the parameter value
01248 }
01249 procedure TZAbstractPreparedStatement.SetDate(ParameterIndex: Integer;
01250 Value: TDateTime);
01251 var
01252 Temp: TZVariant;
01253 begin
01254 DefVarManager.SetAsDateTime(Temp, Value);
01255 SetInParam(ParameterIndex, stDate, Temp);
01256 end;
01257
01258 {**
01259 Sets the designated parameter to a <code>java.sql.Time</code> value.
01260 The driver converts this to an SQL <code>TIME</code> value
01261 when it sends it to the database.
01262
01263 @param parameterIndex the first parameter is 1, the second is 2, ...
01264 @param x the parameter value
01265 }
01266 procedure TZAbstractPreparedStatement.SetTime(ParameterIndex: Integer;
01267 Value: TDateTime);
01268 var
01269 Temp: TZVariant;
01270 begin
01271 DefVarManager.SetAsDateTime(Temp, Value);
01272 SetInParam(ParameterIndex, stTime, Temp);
01273 end;
01274
01275 {**
01276 Sets the designated parameter to a <code>java.sql.Timestamp</code> value.
01277 The driver converts this to an SQL <code>TIMESTAMP</code> value
01278 when it sends it to the database.
01279
01280 @param parameterIndex the first parameter is 1, the second is 2, ...
01281 @param x the parameter value
01282 }
01283 procedure TZAbstractPreparedStatement.SetTimestamp(ParameterIndex: Integer;
01284 Value: TDateTime);
01285 var
01286 Temp: TZVariant;
01287 begin
01288 DefVarManager.SetAsDateTime(Temp, Value);
01289 SetInParam(ParameterIndex, stTimestamp, Temp);
01290 end;
01291
01292 {**
01293 Sets the designated parameter to the given input stream, which will have
01294 the specified number of bytes.
01295 When a very large ASCII value is input to a <code>LONGVARCHAR</code>
01296 parameter, it may be more practical to send it via a
01297 <code>java.io.InputStream</code>. Data will be read from the stream
01298 as needed until end-of-file is reached. The JDBC driver will
01299 do any necessary conversion from ASCII to the database char format.
01300
01301 <P><B>Note:</B> This stream object can either be a standard
01302 Java stream object or your own subclass that implements the
01303 standard interface.
01304
01305 @param parameterIndex the first parameter is 1, the second is 2, ...
01306 @param x the Java input stream that contains the ASCII parameter value
01307 @param length the number of bytes in the stream
01308 }
01309 procedure TZAbstractPreparedStatement.SetAsciiStream(
01310 ParameterIndex: Integer; Value: TStream);
01311 begin
01312 SetBlob(ParameterIndex, stAsciiStream, TZAbstractBlob.CreateWithStream(Value));
01313 end;
01314
01315 {**
01316 Sets the designated parameter to the given input stream, which will have
01317 the specified number of bytes.
01318 When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
01319 parameter, it may be more practical to send it via a
01320 <code>java.io.InputStream</code> object. The data will be read from the stream
01321 as needed until end-of-file is reached. The JDBC driver will
01322 do any necessary conversion from UNICODE to the database char format.
01323 The byte format of the Unicode stream must be Java UTF-8, as
01324 defined in the Java Virtual Machine Specification.
01325
01326 <P><B>Note:</B> This stream object can either be a standard
01327 Java stream object or your own subclass that implements the
01328 standard interface.
01329
01330 @param parameterIndex the first parameter is 1, the second is 2, ...
01331 @param x the java input stream which contains the UNICODE parameter value
01332 }
01333 procedure TZAbstractPreparedStatement.SetUnicodeStream(
01334 ParameterIndex: Integer; Value: TStream);
01335 begin
01336 SetBlob(ParameterIndex, stUnicodeStream, TZAbstractBlob.CreateWithStream(Value));
01337 end;
01338
01339 {**
01340 Sets the designated parameter to the given input stream, which will have
01341 the specified number of bytes.
01342 When a very large binary value is input to a <code>LONGVARBINARY</code>
01343 parameter, it may be more practical to send it via a
01344 <code>java.io.InputStream</code> object. The data will be read from the stream
01345 as needed until end-of-file is reached.
01346
01347 <P><B>Note:</B> This stream object can either be a standard
01348 Java stream object or your own subclass that implements the
01349 standard interface.
01350
01351 @param parameterIndex the first parameter is 1, the second is 2, ...
01352 @param x the java input stream which contains the binary parameter value
01353 }
01354 procedure TZAbstractPreparedStatement.SetBinaryStream(
01355 ParameterIndex: Integer; Value: TStream);
01356 begin
01357 SetBlob(ParameterIndex, stBinaryStream, TZAbstractBlob.CreateWithStream(Value));
01358 end;
01359
01360 {**
01361 Sets a blob object for the specified parameter.
01362 @param ParameterIndex the first parameter is 1, the second is 2, ...
01363 @param Value the java blob object.
01364 }
01365 procedure TZAbstractPreparedStatement.SetBlob(ParameterIndex: Integer;
01366 SQLType: TZSQLType; Value: IZBlob);
01367 var
01368 Temp: TZVariant;
01369 begin
01370 if not (SQLType in [stAsciiStream, stUnicodeStream, stBinaryStream]) then
01371 raise EZSQLException.Create(SWrongTypeForBlobParameter);
01372 DefVarManager.SetAsInterface(Temp, Value);
01373 SetInParam(ParameterIndex, SQLType, Temp);
01374 end;
01375
01376 {**
01377 Sets a variant value for the specified parameter.
01378 @param ParameterIndex the first parameter is 1, the second is 2, ...
01379 @param Value the variant value.
01380 }
01381 procedure TZAbstractPreparedStatement.SetValue(ParameterIndex: Integer;
01382 const Value: TZVariant);
01383 var
01384 SQLType: TZSQLType;
01385 begin
01386 case Value.VType of
01387 vtBoolean: SQLType := stBoolean;
01388 vtInteger: SQLType := stLong;
01389 vtFloat: SQLType := stBigDecimal;
01390 vtUnicodeString: SQLType := stUnicodeString;
01391 vtDateTime: SQLType := stTimestamp;
01392 else SQLType := stString;
01393 end;
01394 SetInParam(ParameterIndex, SQLType, Value);
01395 end;
01396
01397 {**
01398 Clears the current parameter values immediately.
01399 <P>In general, parameter values remain in force for repeated use of a
01400 statement. Setting a parameter value automatically clears its
01401 previous value. However, in some cases it is useful to immediately
01402 release the resources used by the current parameter values; this can
01403 be done by calling the method <code>clearParameters</code>.
01404 }
01405 procedure TZAbstractPreparedStatement.ClearParameters;
01406 var
01407 I: Integer;
01408 begin
01409 for I := 1 to FInParamCount do
01410 begin
01411 SetInParam(I, stUnknown, NullVariant);
01412 SetDefaultValue(I, '');
01413 end;
01414 SetInParamCount(0);
01415 end;
01416
01417 {**
01418 Executes any kind of SQL statement.
01419 Some prepared statements return multiple results; the <code>execute</code>
01420 method handles these complex statements as well as the simpler
01421 form of statements handled by the methods <code>executeQuery</code>
01422 and <code>executeUpdate</code>.
01423 @see Statement#execute
01424 }
01425 function TZAbstractPreparedStatement.ExecutePrepared: Boolean;
01426 begin
01427 Result := False;
01428 RaiseUnsupportedException;
01429 end;
01430
01431 {**
01432 Adds a set of parameters to this <code>PreparedStatement</code>
01433 object's batch of commands.
01434 @see Statement#addBatch
01435 }
01436 procedure TZAbstractPreparedStatement.AddBatchPrepared;
01437 begin
01438 end;
01439
01440 {**
01441 Gets the number, types and properties of a <code>ResultSet</code>
01442 object's columns.
01443 @return the description of a <code>ResultSet</code> object's columns
01444 }
01445 function TZAbstractPreparedStatement.GetMetaData: IZResultSetMetaData;
01446 begin
01447 Result := nil;
01448 RaiseUnsupportedException;
01449 end;
01450
01451 { TZAbstractCallableStatement }
01452
01453 {**
01454 Constructs this object and assigns main properties.
01455 @param Connection a database connection object.
01456 @param Sql a prepared Sql statement.
01457 @param Info a statement parameters.
01458 }
01459 constructor TZAbstractCallableStatement.Create(Connection: IZConnection;
01460 SQL: string; Info: TStrings);
01461 begin
01462 inherited Create(Connection, SQL, Info);
01463 FOutParamCount := 0;
01464 SetOutParamCount(0);
01465 FLastWasNull := True;
01466 end;
01467
01468 {**
01469 Sets a new parameter count and initializes the buffers.
01470 @param NewParamCount a new parameters count.
01471 }
01472 procedure TZAbstractCallableStatement.SetOutParamCount(NewParamCount: Integer);
01473 var
01474 I: Integer;
01475 begin
01476 SetLength(FOutParamValues, NewParamCount);
01477 SetLength(FOutParamTypes, NewParamCount);
01478 for I := FOutParamCount to NewParamCount - 1 do
01479 begin
01480 FOutParamValues[I] := NullVariant;
01481 FOutParamTypes[I] := stUnknown;
01482 end;
01483 FOutParamCount := NewParamCount;
01484 end;
01485
01486 {**
01487 Clears the current parameter values immediately.
01488 <P>In general, parameter values remain in force for repeated use of a
01489 statement. Setting a parameter value automatically clears its
01490 previous value. However, in some cases it is useful to immediately
01491 release the resources used by the current parameter values; this can
01492 be done by calling the method <code>clearParameters</code>.
01493 }
01494 procedure TZAbstractCallableStatement.ClearParameters;
01495 var
01496 I: Integer;
01497 begin
01498 inherited;
01499 for I := 1 to FOutParamCount do
01500 begin
01501 OutParamValues[I - 1] := NullVariant;
01502 OutParamTypes[I - 1] := stUnknown;
01503 end;
01504 SetOutParamCount(0);
01505 end;
01506
01507 {**
01508 Registers the OUT parameter in ordinal position
01509 <code>parameterIndex</code> to the JDBC type
01510 <code>sqlType</code>. All OUT parameters must be registered
01511 before a stored procedure is executed.
01512 <p>
01513 The JDBC type specified by <code>sqlType</code> for an OUT
01514 parameter determines the Java type that must be used
01515 in the <code>get</code> method to read the value of that parameter.
01516 <p>
01517 If the JDBC type expected to be returned to this output parameter
01518 is specific to this particular database, <code>sqlType</code>
01519 should be <code>java.sql.Types.OTHER</code>. The method retrieves the value.
01520 @param parameterIndex the first parameter is 1, the second is 2,
01521 and so on
01522 @param sqlType the JDBC type code defined by <code>java.sql.Types</code>.
01523 If the parameter is of JDBC type <code>NUMERIC</code>
01524 or <code>DECIMAL</code>, the version of
01525 <code>registerOutParameter</code> that accepts a scale value should be used.
01526 }
01527 procedure TZAbstractCallableStatement.RegisterOutParameter(ParameterIndex,
01528 SQLType: Integer);
01529 begin
01530 SetOutParamCount(ParameterIndex);
01531 OutParamTypes[ParameterIndex - 1] := TZSQLType(SQLType);
01532 end;
01533
01534 {**
01535 Gets a output parameter value by it's index.
01536 @param ParameterIndex a parameter index.
01537 @returns a parameter value.
01538 }
01539 function TZAbstractCallableStatement.GetOutParam(
01540 ParameterIndex: Integer): TZVariant;
01541 begin
01542 if Assigned(OutParamValues) then
01543 begin
01544 Result := OutParamValues[ParameterIndex - 1];
01545 FLastWasNull := DefVarManager.IsNull(Result);
01546 end else
01547 begin
01548 Result:=NullVariant;
01549 FLastWasNull:=True;
01550 end;
01551 end;
01552
01553 {**
01554 Indicates whether or not the last OUT parameter read had the value of
01555 SQL <code>NULL</code>. Note that this method should be called only after
01556 calling a <code>getXXX</code> method; otherwise, there is no value to use in
01557 determining whether it is <code>null</code> or not.
01558 @return <code>true</code> if the last parameter read was SQL
01559 <code>NULL</code>; <code>false</code> otherwise
01560 }
01561 function TZAbstractCallableStatement.WasNull: Boolean;
01562 begin
01563 Result := FLastWasNull;
01564 end;
01565
01566 {**
01567 Indicates whether or not the specified OUT parameter read had the value of
01568 SQL <code>NULL</code>.
01569 @return <code>true</code> if the parameter read was SQL
01570 <code>NULL</code>; <code>false</code> otherwise
01571 }
01572 function TZAbstractCallableStatement.IsNull(ParameterIndex: Integer): Boolean;
01573 begin
01574 GetOutParam(ParameterIndex);
01575 Result := FLastWasNull;
01576 end;
01577
01578 {**
01579 Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
01580 or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
01581 the Java programming language.
01582 <p>
01583 For the fixed-length type JDBC <code>CHAR</code>,
01584 the <code>String</code> object
01585 returned has exactly the same value the JDBC
01586 <code>CHAR</code> value had in the
01587 database, including any padding added by the database.
01588 @param parameterIndex the first parameter is 1, the second is 2,
01589 and so on
01590 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01591 is <code>null</code>.
01592 @exception SQLException if a database access error occurs
01593 }
01594 function TZAbstractCallableStatement.GetPChar(ParameterIndex: Integer): PChar;
01595 begin
01596 FTemp := GetString(ParameterIndex);
01597 Result := PChar(FTemp);
01598 end;
01599
01600 {**
01601 Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
01602 or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
01603 the Java programming language.
01604 <p>
01605 For the fixed-length type JDBC <code>CHAR</code>,
01606 the <code>String</code> object
01607 returned has exactly the same value the JDBC
01608 <code>CHAR</code> value had in the
01609 database, including any padding added by the database.
01610 @param parameterIndex the first parameter is 1, the second is 2,
01611 and so on
01612 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01613 is <code>null</code>.
01614 @exception SQLException if a database access error occurs
01615 }
01616 function TZAbstractCallableStatement.GetString(ParameterIndex: Integer): string;
01617 begin
01618 Result := SoftVarManager.GetAsString(GetOutParam(ParameterIndex));
01619 end;
01620
01621 {**
01622 Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,
01623 or <code>LONGVARCHAR</code> parameter as a <code>String</code> in
01624 the Java programming language.
01625 <p>
01626 For the fixed-length type JDBC <code>CHAR</code>,
01627 the <code>WideString</code> object
01628 returned has exactly the same value the JDBC
01629 <code>CHAR</code> value had in the
01630 database, including any padding added by the database.
01631 @param parameterIndex the first parameter is 1, the second is 2,
01632 and so on
01633 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01634 is <code>null</code>.
01635 @exception SQLException if a database access error occurs
01636 }
01637 function TZAbstractCallableStatement.GetUnicodeString(
01638 ParameterIndex: Integer): WideString;
01639 begin
01640 Result := SoftVarManager.GetAsUnicodeString(GetOutParam(ParameterIndex));
01641 end;
01642
01643 {**
01644 Gets the value of a JDBC <code>BIT</code> parameter as a <code>boolean</code>
01645 in the Java programming language.
01646 @param parameterIndex the first parameter is 1, the second is 2,
01647 and so on
01648 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01649 is <code>false</code>.
01650 }
01651 function TZAbstractCallableStatement.GetBoolean(ParameterIndex: Integer): Boolean;
01652 begin
01653 Result := SoftvarManager.GetAsBoolean(GetOutParam(ParameterIndex));
01654 end;
01655
01656 {**
01657 Gets the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>
01658 in the Java programming language.
01659 @param parameterIndex the first parameter is 1, the second is 2,
01660 and so on
01661 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01662 is 0.
01663 }
01664 function TZAbstractCallableStatement.GetByte(ParameterIndex: Integer): ShortInt;
01665 begin
01666 Result := ShortInt(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));
01667 end;
01668
01669 {**
01670 Gets the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>
01671 in the Java programming language.
01672 @param parameterIndex the first parameter is 1, the second is 2,
01673 and so on
01674 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01675 is 0.
01676 }
01677 function TZAbstractCallableStatement.GetShort(ParameterIndex: Integer): SmallInt;
01678 begin
01679 Result := SmallInt(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));
01680 end;
01681
01682 {**
01683 Gets the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>
01684 in the Java programming language.
01685 @param parameterIndex the first parameter is 1, the second is 2,
01686 and so on
01687 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01688 is 0.
01689 }
01690 function TZAbstractCallableStatement.GetInt(ParameterIndex: Integer): Integer;
01691 begin
01692 Result := Integer(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));
01693 end;
01694
01695 {**
01696 Gets the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>
01697 in the Java programming language.
01698 @param parameterIndex the first parameter is 1, the second is 2,
01699 and so on
01700 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01701 is 0.
01702 }
01703 function TZAbstractCallableStatement.GetLong(ParameterIndex: Integer): Int64;
01704 begin
01705 Result := SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex));
01706 end;
01707
01708 {**
01709 Gets the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>
01710 in the Java programming language.
01711 @param parameterIndex the first parameter is 1, the second is 2,
01712 and so on
01713 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01714 is 0.
01715 }
01716 function TZAbstractCallableStatement.GetFloat(ParameterIndex: Integer): Single;
01717 begin
01718 Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));
01719 end;
01720
01721 {**
01722 Gets the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>
01723 in the Java programming language.
01724 @param parameterIndex the first parameter is 1, the second is 2,
01725 and so on
01726 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01727 is 0.
01728 }
01729 function TZAbstractCallableStatement.GetDouble(ParameterIndex: Integer): Double;
01730 begin
01731 Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));
01732 end;
01733
01734 {**
01735 Gets the value of a JDBC <code>NUMERIC</code> parameter as a
01736 <code>java.math.BigDecimal</code> object with scale digits to
01737 the right of the decimal point.
01738 @param parameterIndex the first parameter is 1, the second is 2,
01739 and so on
01740 @return the parameter value. If the value is SQL <code>NULL</code>, the result is
01741 <code>null</code>.
01742 }
01743 function TZAbstractCallableStatement.GetBigDecimal(ParameterIndex: Integer):
01744 Extended;
01745 begin
01746 Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));
01747 end;
01748
01749 {**
01750 Gets the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>
01751 parameter as an array of <code>byte</code> values in the Java
01752 programming language.
01753 @param parameterIndex the first parameter is 1, the second is 2,
01754 and so on
01755 @return the parameter value. If the value is SQL <code>NULL</code>, the result is
01756 <code>null</code>.
01757 }
01758 function TZAbstractCallableStatement.GetBytes(ParameterIndex: Integer):
01759 TByteDynArray;
01760 begin
01761 Result := StrToBytes(SoftVarManager.GetAsString(GetOutParam(ParameterIndex)));
01762 end;
01763
01764 {**
01765 Gets the value of a JDBC <code>DATE</code> parameter as a
01766 <code>java.sql.Date</code> object.
01767 @param parameterIndex the first parameter is 1, the second is 2,
01768 and so on
01769 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01770 is <code>null</code>.
01771 }
01772 function TZAbstractCallableStatement.GetDate(ParameterIndex: Integer):
01773 TDateTime;
01774 begin
01775 Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));
01776 end;
01777
01778 {**
01779 Get the value of a JDBC <code>TIME</code> parameter as a
01780 <code>java.sql.Time</code> object.
01781 @param parameterIndex the first parameter is 1, the second is 2,
01782 and so on
01783 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01784 is <code>null</code>.
01785 }
01786 function TZAbstractCallableStatement.GetTime(ParameterIndex: Integer):
01787 TDateTime;
01788 begin
01789 Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));
01790 end;
01791
01792 {**
01793 Gets the value of a JDBC <code>TIMESTAMP</code> parameter as a
01794 <code>java.sql.Timestamp</code> object.
01795 @param parameterIndex the first parameter is 1, the second is 2,
01796 and so on
01797 @return the parameter value. If the value is SQL <code>NULL</code>, the result
01798 is <code>null</code>.
01799 }
01800 function TZAbstractCallableStatement.GetTimestamp(ParameterIndex: Integer):
01801 TDateTime;
01802 begin
01803 Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));
01804 end;
01805
01806 {**
01807 Gets the value of a JDBC <code>Variant</code> parameter value.
01808 @param parameterIndex the first parameter is 1, the second is 2,
01809 and so on
01810 @return the parameter value. If the value is SQL <code>NULL</code>,
01811 the result is <code>null</code>.
01812 }
01813 function TZAbstractCallableStatement.GetValue(ParameterIndex: Integer):
01814 TZVariant;
01815 begin
01816 Result := GetOutParam(ParameterIndex);
01817 end;
01818
01819 { TZEmulatedPreparedStatement }
01820
01821 {**
01822 Destroys this object and cleanups the memory.
01823 }
01824 destructor TZEmulatedPreparedStatement.Destroy;
01825 begin
01826 if FCachedQuery <> nil then
01827 FCachedQuery.Free;
01828 inherited Destroy;
01829 end;
01830
01831 {**
01832 Sets a reference to the last statement.
01833 @param LastStatement the last statement interface.
01834 }
01835 procedure TZEmulatedPreparedStatement.SetLastStatement(
01836 LastStatement: IZStatement);
01837 begin
01838 if FLastStatement <> nil then
01839 FLastStatement.Close;
01840 FLastStatement := LastStatement;
01841 end;
01842
01843 {**
01844 Creates a temporary statement which executes queries.
01845 @param Info a statement parameters.
01846 @return a created statement object.
01847 }
01848 function TZEmulatedPreparedStatement.GetExecStatement: IZStatement;
01849 begin
01850 if ExecStatement = nil then
01851 begin
01852 ExecStatement := CreateExecStatement;
01853
01854 ExecStatement.SetMaxFieldSize(GetMaxFieldSize);
01855 ExecStatement.SetMaxRows(GetMaxRows);
01856 ExecStatement.SetEscapeProcessing(EscapeProcessing);
01857 ExecStatement.SetQueryTimeout(GetQueryTimeout);
01858 ExecStatement.SetCursorName(CursorName);
01859
01860 ExecStatement.SetFetchDirection(GetFetchDirection);
01861 ExecStatement.SetFetchSize(GetFetchSize);
01862 ExecStatement.SetResultSetConcurrency(GetResultSetConcurrency);
01863 ExecStatement.SetResultSetType(GetResultSetType);
01864 end;
01865 Result := ExecStatement;
01866 end;
01867
01868 {**
01869 Splits a SQL query into a list of sections.
01870 @returns a list of splitted sections.
01871 }
01872 function TZEmulatedPreparedStatement.TokenizeSQLQuery: TStrings;
01873 var
01874 I: Integer;
01875 Tokens: TStrings;
01876 Temp: string;
01877 begin
01878 if FCachedQuery = nil then
01879 begin
01880 FCachedQuery := TStringList.Create;
01881 if Pos('?', SQL) > 0 then
01882 begin
01883 Tokens := Connection.GetDriver.GetTokenizer.
01884 TokenizeBufferToList(SQL, [toUnifyWhitespaces]);
01885 try
01886 Temp := '';
01887 for I := 0 to Tokens.Count - 1 do
01888 begin
01889 if Tokens[I] = '?' then
01890 begin
01891 FCachedQuery.Add(Temp);
01892 FCachedQuery.AddObject('?', Self);
01893 Temp := '';
01894 end else
01895 Temp := Temp + Tokens[I];
01896 end;
01897 if Temp <> '' then
01898 FCachedQuery.Add(Temp);
01899 finally
01900 Tokens.Free;
01901 end;
01902 end else
01903 FCachedQuery.Add(SQL);
01904 end;
01905 Result := FCachedQuery;
01906 end;
01907
01908 {**
01909 Prepares an SQL statement and inserts all data values.
01910 @return a prepared SQL statement.
01911 }
01912 function TZEmulatedPreparedStatement.PrepareSQLQuery: string;
01913 var
01914 I: Integer;
01915 ParamIndex: Integer;
01916 Tokens: TStrings;
01917 begin
01918 ParamIndex := 0;
01919 Result := '';
01920 Tokens := TokenizeSQLQuery;
01921
01922 for I := 0 to Tokens.Count - 1 do
01923 begin
01924 if Tokens[I] = '?' then
01925 begin
01926 Result := Result + PrepareSQLParam(ParamIndex);
01927 Inc(ParamIndex);
01928 end else
01929 Result := Result + Tokens[I];
01930 end;
01931 end;
01932
01933 {**
01934 Closes this statement and frees all resources.
01935 }
01936 procedure TZEmulatedPreparedStatement.Close;
01937 begin
01938 inherited Close;
01939 if LastStatement <> nil then
01940 begin
01941 FLastStatement.Close;
01942 FLastStatement := nil;
01943 end;
01944 end;
01945
01946 {**
01947 Executes an SQL statement that may return multiple results.
01948 Under some (uncommon) situations a single SQL statement may return
01949 multiple result sets and/or update counts. Normally you can ignore
01950 this unless you are (1) executing a stored procedure that you know may
01951 return multiple results or (2) you are dynamically executing an
01952 unknown SQL string. The methods <code>execute</code>,
01953 <code>getMoreResults</code>, <code>getResultSet</code>,
01954 and <code>getUpdateCount</code> let you navigate through multiple results.
01955
01956 The <code>execute</code> method executes an SQL statement and indicates the
01957 form of the first result. You can then use the methods
01958 <code>getResultSet</code> or <code>getUpdateCount</code>
01959 to retrieve the result, and <code>getMoreResults</code> to
01960 move to any subsequent result(s).
01961
01962 @param sql any SQL statement
01963 @return <code>true</code> if the next result is a <code>ResultSet</code> object;
01964 <code>false</code> if it is an update count or there are no more results
01965 }
01966 function TZEmulatedPreparedStatement.Execute(const SQL: string): Boolean;
01967 begin
01968 LastStatement := GetExecStatement;
01969 Result := LastStatement.Execute(SQL);
01970 if Result then
01971 LastResultSet := LastStatement.GetResultSet
01972 else
01973 LastUpdateCount := LastStatement.GetUpdateCount;
01974 end;
01975
01976 {**
01977 Executes an SQL statement that returns a single <code>ResultSet</code> object.
01978 @param sql typically this is a static SQL <code>SELECT</code> statement
01979 @return a <code>ResultSet</code> object that contains the data produced by the
01980 given query; never <code>null</code>
01981 }
01982 function TZEmulatedPreparedStatement.ExecuteQuery(const SQL: string): IZResultSet;
01983 begin
01984 Result := GetExecStatement.ExecuteQuery(SQL);
01985 end;
01986
01987 {**
01988 Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or
01989 <code>DELETE</code> statement. In addition,
01990 SQL statements that return nothing, such as SQL DDL statements,
01991 can be executed.
01992
01993 @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
01994 <code>DELETE</code> statement or an SQL statement that returns nothing
01995 @return either the row count for <code>INSERT</code>, <code>UPDATE</code>
01996 or <code>DELETE</code> statements, or 0 for SQL statements that return nothing
01997 }
01998 function TZEmulatedPreparedStatement.ExecuteUpdate(const SQL: string): Integer;
01999 begin
02000 Result := GetExecStatement.ExecuteUpdate(SQL);
02001 LastUpdateCount := Result;
02002 end;
02003
02004 {**
02005 Executes the SQL query in this <code>PreparedStatement</code> object
02006 and returns the result set generated by the query.
02007
02008 @return a <code>ResultSet</code> object that contains the data produced by the
02009 query; never <code>null</code>
02010 }
02011 function TZEmulatedPreparedStatement.ExecutePrepared: Boolean;
02012 begin
02013 Result := Execute(PrepareSQLQuery);
02014 end;
02015
02016 {**
02017 Executes the SQL query in this <code>PreparedStatement</code> object
02018 and returns the result set generated by the query.
02019
02020 @return a <code>ResultSet</code> object that contains the data produced by the
02021 query; never <code>null</code>
02022 }
02023 function TZEmulatedPreparedStatement.ExecuteQueryPrepared: IZResultSet;
02024 begin
02025 Result := ExecuteQuery(PrepareSQLQuery);
02026 end;
02027
02028 {**
02029 Executes the SQL INSERT, UPDATE or DELETE statement
02030 in this <code>PreparedStatement</code> object.
02031 In addition,
02032 SQL statements that return nothing, such as SQL DDL statements,
02033 can be executed.
02034
02035 @return either the row count for INSERT, UPDATE or DELETE statements;
02036 or 0 for SQL statements that return nothing
02037 }
02038 function TZEmulatedPreparedStatement.ExecuteUpdatePrepared: Integer;
02039 begin
02040 Result := ExecuteUpdate(PrepareSQLQuery);
02041 end;
02042
02043 end.