1 {*********************************************************}
3 { Zeos Database Objects }
4 { ASA Database Connectivity Classes }
6 { Originally written by Sergey Seroukhov }
7 { and Sergey Merkuriev }
9 {*********************************************************}
11 {@********************************************************}
12 { Copyright (c) 1999-2012 Zeos Development Group }
14 { License Agreement: }
16 { This library is distributed in the hope that it will be }
17 { useful, but WITHOUT ANY WARRANTY; without even the }
18 { implied warranty of MERCHANTABILITY or FITNESS FOR }
19 { A PARTICULAR PURPOSE. See the GNU Lesser General }
20 { Public License for more details. }
22 { The source code of the ZEOS Libraries and packages are }
23 { distributed under the Library GNU General Public }
24 { License (see the file COPYING / COPYING.ZEOS) }
25 { with the following modification: }
26 { As a special exception, the copyright holders of this }
27 { library give you permission to link this library with }
28 { independent modules to produce an executable, }
29 { regardless of the license terms of these independent }
30 { modules, and to copy and distribute the resulting }
31 { executable under terms of your choice, provided that }
32 { you also meet, for each linked independent module, }
33 { the terms and conditions of the license of that module. }
34 { An independent module is a module which is not derived }
35 { from or based on this library. If you modify this }
36 { library, you may extend this exception to your version }
37 { of the library, but you are not obligated to do so. }
38 { If you do not wish to do so, delete this exception }
39 { statement from your version. }
42 { The project web site is located on: }
43 { http://zeos.firmos.at (FORUM) }
44 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
45 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
47 { http://www.sourceforge.net/projects/zeoslib. }
50 { Zeos Development Group. }
51 {********************************************************@}
60 Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types,
61 ZSysUtils, ZDbcIntfs, ZPlainASADriver, ZDbcLogging, ZCompatibility, ZDbcASA,
62 ZDbcStatement, ZVariant, ZPlainASAConstants;
71 EZASAConvertError = class(Exception);
73 TZASADECLTYPE = record
78 { Base interface for sqlda }
79 IZASASQLDA = interface
80 ['{7606E8EB-9FC8-4F76-8D91-E23AB96409E1}']
81 procedure AllocateSQLDA( NumVars: Word);
85 function GetData: PASASQLDA;
86 function IsBlob(const Index: Word): boolean;
87 function IsNullable(const Index: Word): boolean;
89 function GetFieldCount: Integer;
90 function GetFieldName(const Index: Word): string;
91 function GetFieldIndex(const Name: String): Word;
92 function GetFieldScale(const Index: Word): integer;
93 function GetFieldSqlType(const Index: Word): TZSQLType;
94 function GetFieldLength(const Index: Word): Word;
96 procedure UpdateNull(const Index: Integer; Value: boolean);
97 procedure UpdateBoolean(const Index: Integer; Value: boolean);
98 procedure UpdateByte(const Index: Integer; Value: Byte);
99 procedure UpdateShort(const Index: Integer; Value: SmallInt);
100 procedure UpdateInt(const Index: Integer; Value: Integer);
101 procedure UpdateLong(const Index: Integer; Value: Int64);
102 procedure UpdateFloat(const Index: Integer; Value: Single);
103 procedure UpdateDouble(const Index: Integer; Value: Double);
104 procedure UpdateBigDecimal(const Index: Integer; Value: Extended);
105 procedure UpdatePChar(const Index: Integer; Value: PChar);
106 procedure UpdateString(const Index: Integer; Value: RawByteString);
107 procedure UpdateBytes(const Index: Integer; Value: TByteDynArray);
108 procedure UpdateDate(const Index: Integer; Value: TDateTime);
109 procedure UpdateTime(const Index: Integer; Value: TDateTime);
110 procedure UpdateTimestamp(const Index: Integer; Value: TDateTime);
111 procedure UpdateValue(const Index: Word; Value: Variant);
112 procedure WriteBlob(const Index: Integer; Stream: TStream; const BlobType: TZSQLType);
114 function IsNull(const Index: Integer): Boolean;
115 function IsAssigned(const Index: Integer): Boolean;
116 function GetBoolean(const Index: Integer): Boolean;
117 function GetByte(const Index: Integer): Byte;
118 function GetShort(const Index: Integer): SmallInt;
119 function GetInt(const Index: Integer): Integer;
120 function GetLong(const Index: Integer): Int64;
121 function GetFloat(const Index: Integer): Single;
122 function GetDouble(const Index: Integer): Double;
123 function GetBigDecimal(const Index: Integer): Extended;
124 function GetPChar(const Index: Integer): PAnsiChar;
125 function GetString(const Index: Integer): RawByteString;
126 function GetBytes(const Index: Integer): TByteDynArray;
127 function GetDate(const Index: Integer): TDateTime;
128 function GetTime(const Index: Integer): TDateTime;
129 function GetTimestamp(const Index: Integer): TDateTime;
130 function GetValue(const Index: Word): Variant;
132 procedure ReadBlobToMem(const Index: Word; var Buffer: Pointer; var Length: LongWord);
133 procedure ReadBlobToStream(const Index: Word; Stream: TStream);
134 procedure ReadBlobToString(const Index: Word; var str: RawByteString);
135 procedure ReadBlobToVariant(const Index: Word; var Value: Variant);
138 { Base class contain core functions to work with sqlda structure
139 Can allocate memory for sqlda structure get basic information }
140 TZASASQLDA = class (TInterfacedObject, IZASASQLDA)
142 FConSettings: PZConSettings;
144 FPlainDriver: IZASAPlainDriver;
146 FCursorName: AnsiString;
147 procedure CreateException( Msg: string);
148 procedure CheckIndex(const Index: Word);
149 procedure CheckRange(const Index: Word);
150 procedure SetFieldType(const Index: Word; ASAType: Smallint; Len: LongWord;
151 SetDeclType: Boolean = true); overload;
152 procedure SetFieldType(ToSQLDA: PASASQLDA; const Index: Word; ASAType: Smallint; Len: LongWord;
153 SetDeclType: Boolean = true); overload;
155 FDeclType: array of TZASADECLTYPE;
156 procedure ReadBlob(const Index: Word; Buffer: Pointer; Length: LongWord);
158 constructor Create(PlainDriver: IZASAPlainDriver; Handle: PZASASQLCA;
159 CursorName: AnsiString; ConSettings: PZConSettings; NumVars: Word = StdVars);
160 destructor Destroy; override;
162 procedure AllocateSQLDA( NumVars: Word);
163 procedure InitFields;
166 function GetData: PASASQLDA;
167 function IsBlob(const Index: Word): boolean;
168 function IsNullable(const Index: Word): boolean;
170 function GetFieldCount: Integer;
171 function GetFieldName(const Index: Word): string;
172 function GetFieldIndex(const Name: String): Word;
173 function GetFieldScale(const Index: Word): Integer;
174 function GetFieldSqlType(const Index: Word): TZSQLType;
175 function GetFieldLength(const Index: Word): Word;
177 procedure UpdateNull(const Index: Integer; Value: boolean);
178 procedure UpdateBoolean(const Index: Integer; Value: boolean);
179 procedure UpdateByte(const Index: Integer; Value: Byte);
180 procedure UpdateShort(const Index: Integer; Value: SmallInt);
181 procedure UpdateInt(const Index: Integer; Value: Integer);
182 procedure UpdateLong(const Index: Integer; Value: Int64);
183 procedure UpdateFloat(const Index: Integer; Value: Single);
184 procedure UpdateDouble(const Index: Integer; Value: Double);
185 procedure UpdateBigDecimal(const Index: Integer; Value: Extended);
186 procedure UpdatePChar(const Index: Integer; Value: PChar);
187 procedure UpdateString(const Index: Integer; Value: RawByteString);
188 procedure UpdateBytes(const Index: Integer; Value: TByteDynArray);
189 procedure UpdateDate(const Index: Integer; Value: TDateTime);
190 procedure UpdateTime(const Index: Integer; Value: TDateTime);
191 procedure UpdateDateTime(const Index: Integer; Value: TDateTime);
192 procedure UpdateTimestamp(const Index: Integer; Value: TDateTime);
193 procedure UpdateValue(const Index: Word; Value: Variant);
194 procedure WriteBlob(const Index: Integer; Stream: TStream; const BlobType: TZSQLType);
196 function IsNull(const Index: Integer): Boolean;
197 function IsAssigned(const Index: Integer): Boolean;
198 function GetBoolean(const Index: Integer): Boolean;
199 function GetByte(const Index: Integer): Byte;
200 function GetShort(const Index: Integer): SmallInt;
201 function GetInt(const Index: Integer): Integer;
202 function GetLong(const Index: Integer): Int64;
203 function GetFloat(const Index: Integer): Single;
204 function GetDouble(const Index: Integer): Double;
205 function GetBigDecimal(const Index: Integer): Extended;
206 function GetPChar(const Index: Integer): PAnsiChar;
207 function GetString(const Index: Integer): RawByteString;
208 function GetBytes(const Index: Integer): TByteDynArray;
209 function GetDate(const Index: Integer): TDateTime;
210 function GetTime(const Index: Integer): TDateTime;
211 function GetTimestamp(const Index: Integer): TDateTime;
212 function GetValue(const Index: Word): Variant;
214 procedure ReadBlobToMem(const Index: Word; var Buffer: Pointer; var Length: LongWord);
215 procedure ReadBlobToStream(const Index: Word; Stream: TStream);
216 procedure ReadBlobToString(const Index: Word; var str: RawByteString);
217 procedure ReadBlobToVariant(const Index: Word; var Value: Variant);
221 Converts a ASA native type into ZDBC SQL types.
222 @param FieldHandle a handler to field description structure.
223 @return a SQL undepended type.
225 function ConvertASATypeToSQLType(const SQLType: SmallInt; const CtrlsCPType: TZControlsCodePage): TZSQLType;
228 Converts a ASA native type into String.
229 @param SQLType Field of TASASQLVar structure.
230 @return type description.
232 function ConvertASATypeToString( SQLType: SmallInt): String;
234 function ConvertASAJDBCToSqlType(const FieldType: SmallInt;
235 CtrlsCPType: TZControlsCodePage): TZSQLType;
237 procedure TSQLTimeStampToASADateTime( DT: TSQLTimeStamp; const ASADT: PZASASQLDateTime);
238 function ASADateTimeToSQLTimeStamp( ASADT: PZASASQLDateTime): TSQLTimeStamp;
241 Checks for possible sql errors.
242 @param PlainDriver a MySQL plain driver.
243 @param Handle a MySQL connection handle.
244 @param LogCategory a logging category.
245 @param LogMessage a logging message.
247 procedure CheckASAError(PlainDriver: IZASAPlainDriver;
248 Handle: PZASASQLCA; LogCategory: TZLoggingCategory; LogMessage: string = '';
249 SupressExceptionID: Integer = 0);
251 function GetCachedResultSet(SQL: string;
252 Statement: IZStatement; NativeResultSet: IZResultSet): IZResultSet;
254 procedure DescribeCursor( FASAConnection: IZASAConnection; FSQLData: IZASASQLDA;
255 Cursor: AnsiString; SQL: String);
257 procedure ASAPrepare( FASAConnection: IZASAConnection; FSQLData, FParamsSQLData: IZASASQLDA;
258 const SQL: RawByteString; const LogSQL: String; StmtNum: PSmallInt; var FPrepared, FMoreResults: Boolean);
260 procedure PrepareParameters( PlainDriver: IZASAPlainDriver;
261 InParamValues: TZVariantDynArray; InParamTypes: TZSQLTypeArray;
262 InParamCount: Integer; ParamSqlData: IZASASQLDA;
263 ConSettings: PZConSettings);
265 function RandomString( Len: integer): string;
269 uses Variants, ZMessages, ZDbcCachedResultSet, Math, ZEncoding
270 {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};
274 procedure TZASASQLDA.CreateException( Msg: string);
276 DriverManager.LogError( lcOther, FPlainDriver.GetProtocol, '', -1, Msg);
277 raise EZSQLException.Create( Format( SSQLError1, [ Msg]));
281 Check range count fields. If index out of range raised exception.
282 @param Index the index field
284 procedure TZASASQLDA.CheckIndex(const Index: Word);
286 Assert( Assigned( FSQLDA), 'SQLDA not initialized.');
287 Assert( Index < Word(FSQLDA.sqld), 'Out of Range.');
290 procedure TZASASQLDA.CheckRange(const Index: Word);
293 Assert( Assigned( FSQLDA.sqlVar[ Index].sqlData),
294 'No memory for variable in SQLDA.');
297 procedure TZASASQLDA.SetFieldType(ToSQLDA: PASASQLDA; const Index: Word;
298 ASAType: Smallint; Len: LongWord; SetDeclType: Boolean = true);
301 with ToSQLDA.sqlvar[Index] do
303 if ( ASAType and $FFFE = DT_LONGBINARY) or
304 ( ASAType and $FFFE = DT_LONGNVARCHAR) or
305 ( ASAType and $FFFE = DT_LONGVARCHAR) then
307 if Assigned( sqlData) then
308 ReallocMem( sqlData, SizeOf( TZASABlobStruct) + Len)
310 GetMem( sqlData, SizeOf( TZASABlobStruct) + Len);
311 PZASABlobStruct( sqlData).array_len := Len;
312 PZASABlobStruct( sqlData).stored_len := 0;
313 PZASABlobStruct( sqlData).untrunc_len := 0;
314 PZASABlobStruct( sqlData).arr[0] := #0;
315 Inc( Len, SizeOf( TZASABlobStruct));
319 if ( ASAType and $FFFE = DT_BINARY) or
320 ( ASAType and $FFFE = DT_VARCHAR) then
321 Inc( Len, SizeOf( TZASASQLSTRING));
322 if Assigned( sqlData) then
323 ReallocMem( sqlData, Len)
325 GetMem( sqlData, Len);
326 if ( ASAType and $FFFE = DT_BINARY) or
327 ( ASAType and $FFFE = DT_VARCHAR) then
328 PZASASQLSTRING( sqlData).length := 0;
334 FDeclType[Index].sqlType := sqlType;
335 FDeclType[Index].sqlLen := sqlLen;
340 procedure TZASASQLDA.SetFieldType(const Index: Word; ASAType: Smallint;
341 Len: LongWord; SetDeclType: Boolean = true);
343 SetFieldType(FSQLDA, Index, ASAType, Len, SetDeclType);
346 constructor TZASASQLDA.Create(PlainDriver: IZASAPlainDriver; Handle: PZASASQLCA;
347 CursorName: AnsiString; ConSettings: PZConSettings; NumVars: Word = StdVars);
349 FPlainDriver := PlainDriver;
351 FCursorName := CursorName;
352 AllocateSQLDA(NumVars);
353 FConSettings := ConSettings;
357 destructor TZASASQLDA.Destroy;
364 Reallocate SQLDA to fields count length
365 @param Value the count fields
367 procedure TZASASQLDA.AllocateSQLDA( NumVars: Word);
370 FSQLDA := FPlainDriver.db_alloc_sqlda( NumVars);
371 if not Assigned( FSQLDA) then
372 CreateException( 'Not enough memory for SQLDA');
373 SetLength(FDeclType, FSQLDA.sqln);
377 Allocate memory for SQLVar in SQLDA structure for every
380 procedure TZASASQLDA.InitFields;
384 if Assigned( FSQLDA) then
386 for i := 0 to FSQLDA.sqld-1 do
388 FDeclType[i].sqlType := FSQLDA.sqlVar[i].sqlType;
389 FDeclType[i].sqlLen := FSQLDA.sqlVar[i].sqlLen;
390 case FSQLDA.sqlVar[i].sqlType and $FFFE of
395 FSQLDA.sqlVar[i].sqlType := DT_TIMESTAMP_STRUCT +
396 ( FSQLDA.sqlVar[i].sqlType and $0001);
397 FSQLDA.sqlVar[i].sqlLen := SizeOf( TZASASQLDateTime);
401 FSQLDA.sqlVar[i].sqlType := DT_DOUBLE +
402 ( FSQLDA.sqlVar[i].sqlType and $0001);
403 FSQLDA.sqlVar[i].sqlLen := SizeOf( Double);
408 DT_LONGVARCHAR: if FSQLDA.sqlVar[i].sqlLen < MinBLOBSize then
409 FSQLDA.sqlVar[i].sqlType := DT_VARCHAR +
410 ( FSQLDA.sqlVar[i].sqlType and $0001)
413 FSQLDA.sqlVar[i].sqlType := DT_LONGVARCHAR +
414 ( FSQLDA.sqlVar[i].sqlType and $0001);
415 FSQLDA.sqlVar[i].sqlLen := 0;
418 DT_LONGBINARY: if FSQLDA.sqlVar[i].sqlLen < MinBLOBSize then
419 FSQLDA.sqlVar[i].sqlType := DT_BINARY +
420 ( FSQLDA.sqlVar[i].sqlType and $0001)
423 FSQLDA.sqlVar[i].sqlType := DT_LONGBINARY +
424 ( FSQLDA.sqlVar[i].sqlType and $0001);
425 FSQLDA.sqlVar[i].sqlLen := 0;
428 SetFieldType( i, FSQLDA.sqlVar[i].sqlType, FSQLDA.sqlVar[i].sqlLen, False);
434 Clear allocated data for SQLDA parameters
436 procedure TZASASQLDA.FreeSQLDA;
440 if Assigned( FSQLDA) then
442 for i := 0 to FSQLDA.sqln-1 do
444 FSQLDA.sqlVar[i].sqlInd := nil;
445 if Assigned( FSQLDA.sqlVar[i].sqlData) then
447 FreeMem( FSQLDA.sqlVar[i].sqlData);
448 FSQLDA.sqlVar[i].sqlData := nil;
451 FPlainDriver.db_free_sqlda( FSQLDA);
454 SetLength(FDeclType, 0);
459 Return pointer to SQLDA structure
461 function TZASASQLDA.GetData: PASASQLDA;
468 @param Index the index fields
469 @return true if blob field overwise false
471 function TZASASQLDA.IsBlob(const Index: Word): boolean;
473 Result := GetFieldSqlType( Index) in
474 [ stAsciiStream, stUnicodeStream, stBinaryStream];
478 Indicate nullable field
479 @param Index the index fields
480 @return true if field nullable overwise false
482 function TZASASQLDA.IsNullable(const Index: Word): boolean;
485 Result := FSQLDA.sqlvar[Index].sqlType and 1 = 1
489 Get fields count not allocated.
492 function TZASASQLDA.GetFieldCount: Integer;
494 if Assigned( FSQLDA) then
495 Result := FSQLDA.sqld
501 Return Name for field
502 @param Index the index fields
505 function TZASASQLDA.GetFieldName(const Index: Word): string;
506 {$IFDEF WITH_RAWBYTESTRING}
507 var Temp: RawByteString;
511 {$IFDEF WITH_RAWBYTESTRING}
512 SetLength(Temp, FSQLDA.sqlvar[Index].sqlname.length-1);
513 Move(FSQLDA.sqlvar[Index].sqlname.data, PAnsiChar(Temp)^, FSQLDA.sqlvar[Index].sqlname.length-1);
514 Result := FPlainDriver.ZDbcString(Temp, FConSettings);
516 SetString( Result, FSQLDA.sqlvar[Index].sqlname.data,
517 FSQLDA.sqlvar[Index].sqlname.length-1);
522 Return field index by it name
523 @param Index the index fields
524 @return the index field
526 function TZASASQLDA.GetFieldIndex(const Name: String): Word;
528 for Result := 0 to FSQLDA.sqld - 1 do
529 if FSQLDA.sqlvar[Result].sqlname.length = Length(name) then
530 if {$IFDEF WITH_STRLICOMP_DEPRECATED}AnsiStrings.{$ENDIF}StrLIComp(@FSQLDA.sqlvar[Result].sqlname.data, PAnsiChar(FPlainDriver.ZPlainString(Name, FConSettings)), Length(name)) = 0 then
532 CreateException( Format( SFieldNotFound1, [name]));
533 Result := 0; // satisfy compiler
538 @param Index the index fields
539 @return the field lenth
541 function TZASASQLDA.GetFieldLength(const Index: Word): Word;
544 if FSQLDA.sqlvar[Index].sqlType and $FFFE <> DT_DECIMAL then
545 Result := FSQLDA.sqlvar[Index].sqlLen
547 Result := (FSQLDA.sqlvar[Index].sqlLen and $FF) div 2 + 1;
552 @param Index the index fields
553 @return the field scale
555 function TZASASQLDA.GetFieldScale(const Index: Word): integer;
558 if FSQLDA.sqlvar[Index].sqlType and $FFFE <> DT_DECIMAL then
561 Result := FSQLDA.sqlvar[Index].sqlLen div 256;
565 Convert ASA sql type to SQLType
566 @param Index the index fields
569 function TZASASQLDA.GetFieldSqlType(const Index: Word): TZSQLType;
572 if FSQLDA.sqlvar[Index].sqlType and $FFFE <> DT_TIMESTAMP_STRUCT then
573 Result := ConvertASATypeToSQLType(FSQLDA.sqlvar[Index].sqlType,
576 Result := ConvertASATypeToSQLType( FDeclType[Index].sqlType,
581 Set up parameter null value
582 @param Index the target parameter index
583 @param Value the source value
585 procedure TZASASQLDA.UpdateNull(const Index: Integer; Value: Boolean);
588 with FSQLDA.sqlvar[ Index] do
590 if not Assigned( sqlData) then
591 SetFieldType( Index, DT_TINYINT or 1, SizeOf( Byte));
595 sqlind^ := 0; //NOT NULL
600 Set up parameter Boolean value
601 @param Index the target parameter index
602 @param Value the source value
604 procedure TZASASQLDA.UpdateBoolean(const Index: Integer; Value: boolean);
607 SetFieldType( Index, DT_BIT or 1, SizeOf( Byte));
608 with FSQLDA.sqlvar[Index] do
610 case sqlType and $FFFE of
612 DT_UNSSMALLINT : PSmallint(sqldata)^ := ord(Value);
614 DT_UNSINT : PInteger(sqldata)^ := ord(Value);
615 DT_FLOAT : PSingle(sqldata)^ := ord(Value);
616 DT_DOUBLE : PDouble(sqldata)^ := ord(Value);
619 PZASASQLSTRING( sqlData).length := 1;
620 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
621 AnsiString(IntToStr(ord(Value))), sqllen-3);
624 DT_BIT : PByte(sqldata)^ := ord(Value);
626 DT_UNSBIGINT : PInt64(sqldata)^ := ord(Value);
628 CreateException( SUnsupportedParameterType);
630 if (sqlind <> nil) then
631 sqlind^ := 0; // not null
636 Set up parameter Byte value
637 @param Index the target parameter index
638 @param Value the source value
640 procedure TZASASQLDA.UpdateByte(const Index: Integer; Value: Byte);
643 SetFieldType( Index, DT_TINYINT or 1, SizeOf( Byte));
644 with FSQLDA.sqlvar[Index] do
646 case sqlType and $FFFE of
648 DT_UNSSMALLINT : PWord(sqldata)^ := Value; //was PSmallint
650 DT_UNSINT : PInteger(sqldata)^ := Value;
651 DT_FLOAT : PSingle(sqldata)^ := Value;
652 DT_DOUBLE : PDouble(sqldata)^ := Value;
655 PZASASQLSTRING( sqlData).length :=
656 Length( IntToStr( Value));
657 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
658 AnsiString(IntToStr(Value)), sqllen-3);
661 DT_BIT : PByte(sqldata)^ := Value;
663 DT_UNSBIGINT : PInt64(sqldata)^ := Value;
665 CreateException( SUnsupportedParameterType);
667 if (sqlind <> nil) then
668 sqlind^ := 0; // not null
673 Set up parameter short value
674 @param Index the target parameter index
675 @param Value the source value
677 procedure TZASASQLDA.UpdateShort(const Index: Integer; Value: SmallInt);
680 SetFieldType( Index, DT_SMALLINT or 1, SizeOf( SmallInt));
681 with FSQLDA.sqlvar[Index] do
683 case sqlType and $FFFE of
685 DT_UNSSMALLINT : PSmallInt(sqldata)^ := Value;
687 DT_UNSINT : PInteger(sqldata)^ := Value;
688 DT_FLOAT : PSingle(sqldata)^ := Value;
689 DT_DOUBLE : PDouble(sqldata)^ := Value;
692 PZASASQLSTRING( sqlData).length :=
693 Length( IntToStr( Value));
694 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
695 AnsiString(IntToStr(Value)), sqllen-3);
698 DT_BIT : PByte(sqldata)^ := Value;
700 DT_UNSBIGINT : PInt64(sqldata)^ := Value;
702 CreateException( SUnsupportedParameterType);
704 if (sqlind <> nil) then
705 sqlind^ := 0; // not null
710 Set up parameter integer value
711 @param Index the target parameter index
712 @param Value the source value
714 procedure TZASASQLDA.UpdateInt(const Index: Integer; Value: Integer);
717 SetFieldType( Index, DT_INT or 1, SizeOf( Integer));
718 with FSQLDA.sqlvar[Index] do
720 case sqlType and $FFFE of
722 DT_UNSSMALLINT : PSmallint(sqldata)^ := Value;
724 DT_UNSINT : PInteger(sqldata)^ := Value;
725 DT_FLOAT : PSingle(sqldata)^ := Value;
726 DT_DOUBLE : PDouble(sqldata)^ := Value;
729 PZASASQLSTRING( sqlData).length :=
730 Length( IntToStr(Value));
731 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
732 AnsiString(IntToStr( Value)), sqllen-3);
735 DT_BIT : PByte(sqldata)^ := Value;
737 DT_UNSBIGINT : PInt64(sqldata)^ := Value;
739 CreateException( SUnsupportedParameterType);
741 if (sqlind <> nil) then
742 sqlind^ := 0; // not null
747 Set up parameter Long value
748 @param Index the target parameter index
749 @param Value the source value
751 procedure TZASASQLDA.UpdateLong(const Index: integer; Value: Int64);
754 SetFieldType( Index, DT_BIGINT or 1, SizeOf( Int64));
755 with FSQLDA.sqlvar[Index] do
757 case sqlType and $FFFE of
759 DT_UNSSMALLINT : PSmallint(sqldata)^ := Value;
761 DT_UNSINT : PInteger(sqldata)^ := Value;
762 DT_FLOAT : PSingle(sqldata)^ := Value;
763 DT_DOUBLE : PDouble(sqldata)^ := Value;
766 PZASASQLSTRING( sqlData).length :=
767 Length( IntToStr( Value));
768 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
769 AnsiString(IntToStr(Value)), sqllen-3);
772 DT_BIT : PByte(sqldata)^ := Value;
774 DT_UNSBIGINT : PInt64(sqldata)^ := Value;
776 CreateException( SUnsupportedParameterType);
778 if (sqlind <> nil) then
779 sqlind^ := 0; // not null
784 Set up parameter Float value
785 @param Index the target parameter index
786 @param Value the source value
788 procedure TZASASQLDA.UpdateFloat(const Index: Integer; Value: Single);
791 SetFieldType( Index, DT_FLOAT or 1, SizeOf( Single));
792 with FSQLDA.sqlvar[Index] do
794 case sqlType and $FFFE of
796 DT_UNSSMALLINT : PSmallint(sqldata)^ := Trunc( Value);
798 DT_UNSINT : PInteger(sqldata)^ := Trunc( Value);
799 DT_FLOAT : PSingle(sqldata)^ := Value;
800 DT_DOUBLE : PDouble(sqldata)^ := Value;
803 PZASASQLSTRING( sqlData).length :=
804 Length( FloatToStr( Value));
805 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
806 AnsiString(FloatToStr(Value)), sqllen-3);
809 DT_BIT : PByte(sqldata)^ := Trunc( Value);
811 DT_UNSBIGINT : PInt64(sqldata)^ := Trunc( Value);
813 CreateException( SUnsupportedParameterType);
815 if (sqlind <> nil) then
816 sqlind^ := 0; // not null
821 Set up parameter Double value
822 @param Index the target parameter index
823 @param Value the source value
825 procedure TZASASQLDA.UpdateDouble(const Index: Integer; Value: Double);
828 SetFieldType( Index, DT_DOUBLE or 1, SizeOf( Double));
829 with FSQLDA.sqlvar[Index] do
831 case sqlType and $FFFE of
833 DT_UNSSMALLINT : PSmallint(sqldata)^ := Trunc( Value);
835 DT_UNSINT : PInteger(sqldata)^ := Trunc( Value);
836 DT_FLOAT : PSingle(sqldata)^ := Value;
837 DT_DOUBLE : PDouble(sqldata)^ := Value;
840 PZASASQLSTRING( sqlData).length :=
841 Length( FloatToStr( Value));
842 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
843 AnsiString(FloatToStr( Value)), sqllen-3);
846 DT_BIT : PByte(sqldata)^ := Trunc( Value);
848 DT_UNSBIGINT : PInt64(sqldata)^ := Trunc( Value);
850 CreateException( SUnsupportedParameterType);
852 if (sqlind <> nil) then
853 sqlind^ := 0; // not null
858 Set up parameter BigDecimal value
859 @param Index the target parameter index
860 @param Value the source value
862 procedure TZASASQLDA.UpdateBigDecimal(const Index: Integer; Value: Extended);
865 SetFieldType( Index, DT_DOUBLE or 1, SizeOf( Double));
866 with FSQLDA.sqlvar[Index] do
868 case sqlType and $FFFE of
870 DT_UNSSMALLINT : PSmallint(sqldata)^ := Trunc( Value);
872 DT_UNSINT : PInteger(sqldata)^ := Trunc( Value);
873 DT_FLOAT : PSingle(sqldata)^ := Value;
874 DT_DOUBLE : PDouble(sqldata)^ := Value;
877 PZASASQLSTRING( sqlData).length :=
878 Length( FloatToStr( Value));
879 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
880 AnsiString(FloatToStr( Value)), sqllen-3);
883 DT_BIT : PByte(sqldata)^ := Trunc( Value);
885 DT_UNSBIGINT : PInt64(sqldata)^ := Trunc( Value);
887 CreateException( SUnsupportedParameterType);
889 if (sqlind <> nil) then
890 sqlind^ := 0; // not null
895 Set up parameter PAnsiChar value
896 @param Index the target parameter index
897 @param Value the source value
899 procedure TZASASQLDA.UpdatePChar(const Index: Integer; Value: PChar);
902 AnsiTmp: RawByteString;
905 AnsiTmp := FPlainDriver.ZPlainString(Value, FConSettings);
906 BlobSize := StrLen( Value);
907 if BlobSize < MinBLOBSize then
908 SetFieldType( Index, DT_VARCHAR or 1, MinBLOBSize - 1)
910 SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);
911 with FSQLDA.sqlvar[Index] do
913 case sqlType and $FFFE of
916 PZASASQLSTRING( sqlData).length := BlobSize;
917 {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( @PZASASQLSTRING( sqlData).data[0],
918 PAnsiChar(AnsiTmp), BlobSize);
922 {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( @PZASABlobStruct( sqlData).arr[0],
923 PAnsiChar(AnsiTmp), BlobSize);
924 PZASABlobStruct( sqlData).stored_len := BlobSize;
925 PZASABlobStruct( sqlData).untrunc_len := BlobSize;
928 CreateException( SUnsupportedParameterType);
930 if (sqlind <> nil) then
931 sqlind^ := 0; // not null
936 Set up parameter String value
937 @param Index the target parameter index
938 @param Value the source value
940 procedure TZASASQLDA.UpdateString(const Index: Integer; Value: RawByteString);
945 BlobSize := Length( Value);
946 if BlobSize < MinBLOBSize then
947 SetFieldType( Index, DT_VARCHAR or 1, MinBLOBSize - 1)
949 SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);
950 with FSQLDA.sqlvar[Index] do
952 case sqlType and $FFFE of
955 PZASASQLSTRING( sqlData).length := BlobSize;
956 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],
961 {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASABlobStruct( sqlData).arr[0], Value,
963 PZASABlobStruct( sqlData).stored_len := BlobSize;
964 PZASABlobStruct( sqlData).untrunc_len := BlobSize;
967 CreateException( SUnsupportedParameterType);
969 if (sqlind <> nil) then
970 sqlind^ := 0; // not null
975 Set up parameter byte value
976 @param Index the target parameter index
977 @param Value the source value
979 procedure TZASASQLDA.UpdateBytes(const Index: Integer; Value: TByteDynArray);
984 BlobSize := Length( Value);
985 if BlobSize < MinBLOBSize then
986 SetFieldType( Index, DT_BINARY or 1, MinBLOBSize - 1)
988 SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);
989 with FSQLDA.sqlvar[Index] do
991 case sqlType and $FFFE of
994 PZASASQLSTRING( sqlData).length := BlobSize;
995 Move( Value[0], PZASASQLSTRING( sqlData).data[0], BlobSize);
999 Move( Value[0], PZASABlobStruct( sqlData).arr[0], BlobSize);
1000 PZASABlobStruct( sqlData).stored_len := BlobSize;
1001 PZASABlobStruct( sqlData).untrunc_len := BlobSize;
1004 CreateException( SUnsupportedParameterType);
1006 if (sqlind <> nil) then
1007 sqlind^ := 0; // not null
1012 Set up parameter Date value
1013 @param Index the target parameter index
1014 @param Value the source value
1016 procedure TZASASQLDA.UpdateDate(const Index: Integer; Value: TDateTime);
1018 UpdateDateTime(Index, Value);
1019 FDeclType[Index].sqlType := DT_DATE;
1023 Set up parameter Time value
1024 @param Index the target parameter index
1025 @param Value the source value
1027 procedure TZASASQLDA.UpdateTime(const Index: Integer; Value: TDateTime);
1029 UpdateDateTime(Index, Value);
1030 FDeclType[Index].sqlType := DT_TIME;
1034 Set up parameter DateTime value
1035 @param Index the target parameter index
1036 @param Value the source value
1038 procedure TZASASQLDA.UpdateDateTime(const Index: Integer;
1042 hr, min, sec, msec: word;
1045 SetFieldType( Index, DT_TIMESTAMP_STRUCT or 1, SizeOf( TZASASQLDateTime));
1046 with FSQLDA.sqlvar[Index] do
1048 case sqlType and $FFFE of
1049 DT_TIMESTAMP_STRUCT:
1051 DecodeDate( Value, y, m, d);
1052 DecodeTime( Value, hr, min, sec, msec);
1053 PZASASQLDateTime( sqlData).Year := y;
1054 PZASASQLDateTime( sqlData).Month := m - 1;
1055 PZASASQLDateTime( sqlData).Day := d;
1056 PZASASQLDateTime( sqlData).Hour := hr;
1057 PZASASQLDateTime( sqlData).Minute := min;
1058 PZASASQLDateTime( sqlData).Second := sec;
1059 PZASASQLDateTime( sqlData).MicroSecond :=
1061 PZASASQLDateTime( sqlData).Day_of_Week := 0;
1062 PZASASQLDateTime( sqlData).Day_of_Year := 0;
1065 CreateException( SUnsupportedParameterType);
1067 if (sqlind <> nil) then
1068 sqlind^ := 0; // not null
1070 FDeclType[Index].sqlType := DT_TIMESTAMP;
1074 Set up parameter Timestamp value
1075 @param Index the target parameter index
1076 @param Value the source value
1078 procedure TZASASQLDA.UpdateTimestamp(const Index: Integer; Value: TDateTime);
1080 UpdateDateTime(Index, Value);
1084 Set up parameter Type value
1085 @param Index the target parameter index
1086 @param Value the source value
1088 procedure TZASASQLDA.UpdateValue(const Index: Word; Value: Variant);
1090 case VarType(Value) of
1092 varNull : UpdateNull( Index, True);
1093 varSmallint : UpdateShort( Index, Value);
1094 varInteger : UpdateInt( Index, Value);
1095 varSingle : UpdateFloat( Index, Value);
1096 varDouble : UpdateDouble( Index, Value);
1097 varCurrency : UpdateBigDecimal( Index, Value);
1098 varDate : UpdateDateTime( Index, Value);
1100 varString : UpdateString(Index, AnsiString(Value));
1101 varOleStr : UpdateString(Index, FPlainDriver.ZPlainString(WideString(Value), FConSettings));
1102 varBoolean : UpdateBoolean( Index, Value);
1103 varByte : UpdateByte( Index, Value);
1104 varInt64 : UpdateLong( Index, Value);
1105 varShortInt : UpdateByte( Index, Value);
1106 varLongWord : UpdateInt( Index, Value);
1107 varWord : UpdateShort( Index, Value);
1109 if VarArrayDimCount( Value) = 1 then
1111 UpdateBytes( Index, VarArrayLock( Value));
1112 VarArrayUnlock( Value);
1115 CreateException( SUnsupportedParameterType);
1120 Write stream to blob field
1121 @param Index an index field number
1122 @param Stream the souse data stream
1124 procedure TZASASQLDA.WriteBlob(const Index: Integer; Stream: TStream;
1125 const BlobType: TZSQLType);
1130 stream.Position := 0;
1131 BlobSize := stream.Size;
1133 stAsciiStream: SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);
1134 stUnicodeStream: SetFieldType( Index, DT_LONGNVARCHAR or 1, BlobSize);
1135 stBinaryStream: SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);
1137 CreateException( SUnsupportedParameterType);
1139 {case FSQLDA.sqlvar[Index].sqlType and $FFFE of
1141 SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);
1143 SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);
1145 SetFieldType( Index, DT_LONGNVARCHAR or 1, BlobSize);
1147 SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);}
1148 with FSQLDA.sqlvar[Index] do
1150 case sqlType and $FFFE of
1151 DT_LONGVARCHAR, DT_LONGNVARCHAR,
1154 stream.ReadBuffer( PZASABlobStruct( sqlData).arr[0], BlobSize);
1155 stream.Position := 0;
1156 PZASABlobStruct( sqlData).stored_len := BlobSize;
1157 PZASABlobStruct( sqlData).untrunc_len := BlobSize;
1160 CreateException( SUnsupportedParameterType);
1162 if (sqlind <> nil) then
1163 sqlind^ := 0; // not null
1169 @param Index the field index
1170 @return true if fied value NULL overwise false
1172 function TZASASQLDA.IsNull(const Index: Integer): Boolean;
1175 with FSQLDA.sqlvar[Index] do
1176 Result := Assigned( sqlind) and (sqlind^ < 0);
1180 Indicate sqldata assigned
1181 @param Index the field index
1182 @return true if assigned field data
1184 function TZASASQLDA.IsAssigned(const Index: Integer): Boolean;
1187 with FSQLDA.sqlvar[Index] do
1188 Result := Assigned( sqldata);
1192 Return BigDecimal field value
1193 @param Index the field index
1194 @return the field BigDecimal value
1196 function TZASASQLDA.GetBigDecimal(const Index: Integer): Extended;
1201 with FSQLDA.sqlvar[Index] do
1204 if (sqlind^ < 0) then
1207 case sqlType and $FFFE of
1208 DT_SMALLINT : Result := PSmallint(sqldata)^;
1209 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1210 DT_INT : Result := PInteger(sqldata)^;
1211 DT_UNSINT : Result := PLongWord(sqldata)^;
1212 DT_FLOAT : Result := PSingle(sqldata)^;
1213 DT_DOUBLE : Result := PDouble(sqldata)^;
1216 {$IFDEF WITH_RAWBYTESTRING}
1217 SetLength(s, PZASASQLSTRING( sqlData).length);
1218 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsichar(s)^, PZASASQLSTRING( sqlData).length);
1220 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1222 Result := ZStrToFloat(s);
1225 DT_BIT : Result := PByte(sqldata)^;
1227 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1229 CreateException( Format( SErrorConvertionField,
1230 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1236 Return Boolean field value
1237 @param Index the field index
1238 @return the field boolean value
1240 function TZASASQLDA.GetBoolean(const Index: Integer): Boolean;
1245 with FSQLDA.sqlvar[Index] do
1248 if (sqlind^ < 0) then
1251 case sqlType and $FFFE of
1252 DT_SMALLINT : Result := PSmallint(sqldata)^ <> 0;
1253 DT_UNSSMALLINT : Result := PWord(sqldata)^ <> 0;
1254 DT_INT : Result := PInteger(sqldata)^ <> 0;
1255 DT_UNSINT : Result := PLongWord(sqldata)^ <> 0;
1256 DT_FLOAT : Result := PSingle(sqldata)^ <> 0;
1257 DT_DOUBLE : Result := PDouble(sqldata)^ <> 0;
1260 {$IFDEF WITH_RAWBYTESTRING}
1261 SetLength(s, PZASASQLSTRING( sqlData).length);
1262 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1264 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1266 Result := StrToInt(String(s)) = 1;
1269 DT_BIT : Result := PByte(sqldata)^ <> 0;
1271 DT_UNSBIGINT : Result := PInt64(sqldata)^ <> 0;
1273 CreateException( Format( SErrorConvertionField,
1274 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1280 Return Byte field value
1281 @param Index the field index
1282 @return the field Byte value
1284 function TZASASQLDA.GetByte(const Index: Integer): Byte;
1289 with FSQLDA.sqlvar[Index] do
1292 if (sqlind^ < 0) then
1295 case sqlType and $FFFE of
1296 DT_SMALLINT : Result := PSmallint(sqldata)^;
1297 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1298 DT_INT : Result := PInteger(sqldata)^;
1299 DT_UNSINT : Result := PLongWord(sqldata)^;
1300 DT_FLOAT : Result := Trunc( PSingle(sqldata)^);
1301 DT_DOUBLE : Result := Trunc( PDouble(sqldata)^);
1304 {$IFDEF WITH_RAWBYTESTRING}
1305 SetLength(s, PZASASQLSTRING( sqlData).length);
1306 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1308 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1310 Result := StrToInt(String(s));
1313 DT_BIT : Result := PByte(sqldata)^;
1315 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1317 CreateException( Format( SErrorConvertionField,
1318 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1324 Return Bytes field value
1325 @param Index the field index
1326 @return the field Bytes value
1328 function TZASASQLDA.GetBytes(const Index: Integer): TByteDynArray;
1331 with FSQLDA.sqlvar[Index] do
1334 if (sqlind^ < 0) then
1337 case sqlType and $FFFE of
1340 SetLength( Result, PZASASQLSTRING( sqlData).length);
1341 Move(PZASASQLSTRING(sqlData).data[0], Result[0], PZASASQLSTRING(sqlData).length);
1344 CreateException( Format( SErrorConvertionField,
1345 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1351 Return Date field value
1352 @param Index the field index
1353 @return the field Date value
1355 function TZASASQLDA.GetDate(const Index: Integer): TDateTime;
1357 Result := Trunc( GetTimestamp( Index));
1361 Return Double field value
1362 @param Index the field index
1363 @return the field Double value
1365 function TZASASQLDA.GetDouble(const Index: Integer): Double;
1370 with FSQLDA.sqlvar[Index] do
1373 if (sqlind^ < 0) then
1376 case sqlType and $FFFE of
1377 DT_SMALLINT : Result := PSmallint(sqldata)^;
1378 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1379 DT_INT : Result := PInteger(sqldata)^;
1380 DT_UNSINT : Result := PLongWord(sqldata)^;
1381 DT_FLOAT : Result := PSingle(sqldata)^;
1382 DT_DOUBLE : Result := PDouble(sqldata)^;
1385 {$IFDEF WITH_RAWBYTESTRING}
1386 SetLength(s, PZASASQLSTRING( sqlData).length);
1387 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1389 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1391 Result := ZStrToFloat(s);
1394 DT_BIT : Result := PByte(sqldata)^;
1396 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1398 CreateException( Format( SErrorConvertionField,
1399 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1405 Return Float field value
1406 @param Index the field index
1407 @return the field Float value
1409 function TZASASQLDA.GetFloat(const Index: Integer): Single;
1414 with FSQLDA.sqlvar[Index] do
1417 if (sqlind^ < 0) then
1420 case sqlType and $FFFE of
1421 DT_SMALLINT : Result := PSmallint(sqldata)^;
1422 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1423 DT_INT : Result := PInteger(sqldata)^;
1424 DT_UNSINT : Result := PLongWord(sqldata)^;
1425 DT_FLOAT : Result := PSingle(sqldata)^;
1426 DT_DOUBLE : Result := PDouble(sqldata)^;
1429 {$IFDEF WITH_RAWBYTESTRING}
1430 SetLength(s, PZASASQLSTRING( sqlData).length);
1431 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1433 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1435 Result := ZStrToFloat(s);
1438 DT_BIT : Result := PByte(sqldata)^;
1440 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1442 CreateException( Format( SErrorConvertionField,
1443 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1449 Return Integer field value
1450 @param Index the field index
1451 @return the field Integer value
1453 function TZASASQLDA.GetInt(const Index: Integer): Integer;
1458 with FSQLDA.sqlvar[Index] do
1461 if (sqlind^ < 0) then
1464 case sqlType and $FFFE of
1465 DT_SMALLINT : Result := PSmallint(sqldata)^;
1466 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1467 DT_INT : Result := PInteger(sqldata)^;
1468 DT_UNSINT : Result := PLongWord(sqldata)^;
1469 DT_FLOAT : Result := Trunc( PSingle(sqldata)^);
1470 DT_DOUBLE : Result := Trunc( PDouble(sqldata)^);
1473 {$IFDEF WITH_RAWBYTESTRING}
1474 SetLength(s, PZASASQLSTRING( sqlData).length);
1475 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1477 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1479 Result := StrToInt(String(s));
1482 DT_BIT : Result := PByte(sqldata)^;
1484 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1486 CreateException( Format( SErrorConvertionField,
1487 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1493 Return Long field value
1494 @param Index the field index
1495 @return the field Long value
1497 function TZASASQLDA.GetLong(const Index: Integer): Int64;
1502 with FSQLDA.sqlvar[Index] do
1505 if (sqlind^ < 0) then
1508 case sqlType and $FFFE of
1509 DT_SMALLINT : Result := PSmallint(sqldata)^;
1510 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1511 DT_INT : Result := PInteger(sqldata)^;
1512 DT_UNSINT : Result := PLongWord(sqldata)^;
1513 DT_FLOAT : Result := Trunc( PSingle(sqldata)^);
1514 DT_DOUBLE : Result := Trunc( PDouble(sqldata)^);
1517 {$IFDEF WITH_RAWBYTESTRING}
1518 SetLength(s, PZASASQLSTRING( sqlData).length);
1519 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1521 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1523 Result := StrToInt64(String(s));
1526 DT_BIT : Result := PByte(sqldata)^;
1528 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1530 CreateException( Format( SErrorConvertionField,
1531 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1537 Return PAnsiChar field value
1538 @param Index the field index
1539 @return the field PAnsiChar value
1541 function TZASASQLDA.GetPChar(const Index: Integer): PAnsiChar;
1544 with FSQLDA.sqlvar[Index] do
1547 if (sqlind^ < 0) then
1550 case sqlType and $FFFE of
1553 GetMem( Result, PZASASQLSTRING( sqlData).length + 1);
1554 {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( Result, @PZASASQLSTRING( sqlData).data[0], PZASASQLSTRING( sqlData).length);
1557 Result := PAnsiChar(GetString(Index));
1563 Return String field value
1564 @param Index the field index
1565 @return the field String value
1567 function TZASASQLDA.GetString(const Index: Integer): RawByteString;
1570 with FSQLDA.sqlvar[Index] do
1573 if (sqlind^ < 0) then
1576 case sqlType and $FFFE of
1577 DT_SMALLINT : Result := RawByteString(IntToStr( PSmallint(sqldata)^));
1578 DT_UNSSMALLINT : Result := RawByteString(IntToStr( PWord(sqldata)^));
1579 DT_INT : Result := RawByteString(IntToStr( PInteger(sqldata)^));
1580 DT_UNSINT : Result := RawByteString(IntToStr( PLongWord(sqldata)^));
1581 DT_FLOAT : Result := RawByteString(FloatToStr( PSingle(sqldata)^));
1582 DT_DOUBLE : Result := RawByteString(FloatToStr( PDouble(sqldata)^));
1585 {$IFDEF WITH_RAWBYTESTRING}
1586 SetLength(Result, PZASASQLSTRING( sqlData).length);
1587 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(Result)^, PZASASQLSTRING( sqlData).length);
1589 SetString(Result, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1592 DT_LONGVARCHAR : ReadBlobToString( Index, Result);
1593 DT_TIMESTAMP_STRUCT : Result := RawByteString(DateToStr( GetTimestamp( Index)));
1594 DT_TINYINT : Result := RawByteString(IntToStr( PByte(sqldata)^));
1595 DT_BIT : Result := RawByteString(BoolToStr( ( PByte(sqldata)^ = 1), True));
1597 DT_UNSBIGINT : Result := RawByteString(IntToStr( PInt64(sqldata)^));
1599 CreateException( Format( SErrorConvertionField,
1600 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1606 Return Short field value
1607 @param Index the field index
1608 @return the field Short value
1610 function TZASASQLDA.GetShort(const Index: Integer): SmallInt;
1615 with FSQLDA.sqlvar[Index] do
1618 if (sqlind^ < 0) then
1621 case sqlType and $FFFE of
1622 DT_SMALLINT : Result := PSmallint(sqldata)^;
1623 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1624 DT_INT : Result := PInteger(sqldata)^;
1625 // DT_UNSINT : Result := PLongWord(sqldata)^;
1626 DT_FLOAT : Result := Trunc( PSingle(sqldata)^);
1627 DT_DOUBLE : Result := Trunc( PDouble(sqldata)^);
1630 {$IFDEF WITH_RAWBYTESTRING}
1631 SetLength(s, PZASASQLSTRING( sqlData).length);
1632 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1634 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1636 Result := StrToInt(String(s));
1639 DT_BIT : Result := PByte(sqldata)^;
1641 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1643 CreateException( Format( SErrorConvertionField,
1644 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1650 Return Time field value
1651 @param Index the field index
1652 @return the field Time value
1654 function TZASASQLDA.GetTime(const Index: Integer): TDateTime;
1656 Result := Frac( GetTimestamp( Index));
1660 Return Timestamp field value
1661 @param Index the field index
1662 @return the field Timestamp value
1664 function TZASASQLDA.GetTimestamp(const Index: Integer): TDateTime;
1667 with FSQLDA.sqlvar[Index] do
1670 if (sqlind^ < 0) then
1673 case sqlType and $FFFE of
1674 DT_TIMESTAMP_STRUCT:
1676 Result := EncodeDate( PZASASQLDateTime( sqlData).Year,
1677 PZASASQLDateTime( sqlData).Month + 1,
1678 PZASASQLDateTime( sqlData).Day) +
1679 EncodeTime( PZASASQLDateTime( sqlData).Hour,
1680 PZASASQLDateTime( sqlData).Minute,
1681 PZASASQLDateTime( sqlData).Second,
1682 PZASASQLDateTime( sqlData).MicroSecond div 1000);
1685 CreateException( Format( SErrorConvertionField,
1686 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1692 Return Variant field value
1693 @param Index the field index
1694 @return the field Variant value
1696 function TZASASQLDA.GetValue(const Index: Word): Variant;
1701 with FSQLDA.sqlvar[Index] do
1704 if (sqlind^ < 0) then
1707 case sqlType and $FFFE of
1708 DT_SMALLINT : Result := PSmallint(sqldata)^;
1709 DT_UNSSMALLINT : Result := PWord(sqldata)^;
1710 DT_INT : Result := PInteger(sqldata)^;
1711 // DT_UNSINT : Result := PLongWord(sqldata)^;
1712 DT_FLOAT : Result := PSingle(sqldata)^;
1713 DT_DOUBLE : Result := PDouble(sqldata)^;
1716 {$IFDEF WITH_RAWBYTESTRING}
1717 SetLength(s, PZASASQLSTRING( sqlData).length);
1718 Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);
1720 SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);
1725 DT_LONGBINARY : ReadBlobToVariant(Index, Result);
1726 DT_TIMESTAMP_STRUCT : Result := GetTimeStamp( Index);
1727 DT_TINYINT : Result := PByte(sqldata)^;
1728 DT_BIT : Result := Boolean( PByte(sqldata)^);
1730 DT_UNSBIGINT : Result := PInt64(sqldata)^;
1732 CreateException( Format( SErrorConvertionField,
1733 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1738 procedure TZASASQLDA.ReadBlob(const Index: Word; Buffer: Pointer;
1741 TempSQLDA: PASASQLDA;
1746 with FSQLDA.sqlvar[Index] do
1748 if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or
1749 ( sqlType and $FFFE = DT_LONGNVARCHAR) or
1750 ( sqlType and $FFFE = DT_LONGBINARY)) and
1751 ( PZASABlobStruct( sqlData).array_len > 0) then
1753 Assert( PZASABlobStruct( sqlData).array_len = PZASABlobStruct( sqlData).untrunc_len,
1754 'Blob Record is not correctly initialized');
1755 if PZASABlobStruct( sqlData).array_len <> Length then
1756 CreateException( 'Could''nt complete BLOB-Read');
1757 move( PZASABlobStruct( sqlData).arr[0], PAnsiChar( Buffer)[0], PZASABlobStruct( sqlData).array_len);
1761 TempSQLDA := FPlainDriver.db_alloc_sqlda( 1);
1762 if not Assigned( TempSQLDA) then
1763 CreateException( 'Not enough memory for SQLDA');
1765 with TempSQLDA.sqlvar[ 0] do
1767 case Self.GetFieldSqlType(Index) of
1769 SetFieldType(TempSQLDA, 0, DT_LONGVARCHAR, Min( BlockSize, Length));
1771 SetFieldType(TempSQLDA, 0, DT_LONGNVARCHAR, Min( BlockSize, Length));
1773 SetFieldType(TempSQLDA, 0, DT_LONGBINARY, Min( BlockSize, Length));
1775 sqlType := DT_FIXCHAR;
1777 sqlname.length := 0;
1778 sqlname.data[0] := #0;
1779 TempSQLDA.sqld := TempSQLDA.sqln;
1786 FPlainDriver.db_get_data(FHandle, PAnsiChar(FCursorName), Index + 1, Offs, TempSQLDA);
1787 CheckASAError( FPlainDriver, FHandle, lcOther);
1788 if ( sqlind^ < 0 ) then
1790 Inc( Rd, PZASABlobStruct( sqlData)^.stored_len);
1791 if Offs = 0 then ReallocMem(Buffer, PZASABlobStruct( sqlData)^.untrunc_len);
1792 Move((PZASABlobStruct( sqlData)^.arr[0]), (PAnsiChar(Buffer)+Offs)^, PZASABlobStruct( sqlData)^.stored_len);
1793 if ( sqlind^ = 0 ) or ( RD = Length) then
1795 Inc( Offs, PZASABlobStruct( sqlData)^.stored_len);
1796 sqllen := Min( BlockSize, Length-Rd);
1798 if Rd <> Length then
1799 CreateException( 'Could''nt complete BLOB-Read');
1801 DriverManager.LogMessage( lcExecute, FPlainDriver.GetProtocol,
1802 Format( 'GET DATA for Column: %s', [ GetFieldName(Index)]));
1803 FreeMem(sqlData, SizeOf(TZASABlobStruct)+Min( BlockSize, Length));
1804 FPlainDriver.db_free_sqlda( TempSQLDA);
1808 if Assigned( TempSQLDA) then
1809 FPlainDriver.db_free_sqlda( TempSQLDA);
1817 Read blob data to Buffer
1818 @param Index an filed index
1819 @param Str destination string
1821 procedure TZASASQLDA.ReadBlobToMem(const Index: Word; var Buffer: Pointer;
1822 var Length: LongWord);
1825 with FSQLDA.sqlvar[Index] do
1829 if (sqlind^ < 0) then
1832 if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or
1833 ( sqlType and $FFFE = DT_LONGBINARY)) then
1835 Length := PZASABlobStruct( sqlData).untrunc_len;
1836 GetMem( Buffer, Length);
1837 ReadBlob( Index, Buffer, Length);
1840 CreateException( Format( SErrorConvertionField,
1841 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1846 Read blob data to string
1847 @param Index an filed index
1848 @param Str destination string
1850 procedure TZASASQLDA.ReadBlobToString(const Index: Word; var Str: RawByteString);
1853 with FSQLDA.sqlvar[Index] do
1856 if (sqlind^ < 0) then
1859 if sqlType and $FFFE = DT_LONGVARCHAR then
1861 SetLength( Str, PZASABlobStruct( sqlData).untrunc_len);
1862 ReadBlob(Index, PAnsiChar(Str), Length(Str));
1865 CreateException( Format( SErrorConvertionField,
1866 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1871 Read blob data to stream
1872 @param Index an filed index
1873 @param Stream destination stream object
1875 procedure TZASASQLDA.ReadBlobToStream(const Index: Word; Stream: TStream);
1878 with FSQLDA.sqlvar[Index] do
1881 if (sqlind^ < 0) then
1884 if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or
1885 ( sqlType and $FFFE = DT_LONGBINARY)) and
1886 ( Stream is TMemoryStream) then
1888 Stream.Size := PZASABlobStruct( sqlData).untrunc_len;
1889 ReadBlob( Index, TMemoryStream( Stream).Memory, Stream.Size);
1892 CreateException( Format( SErrorConvertionField,
1893 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1898 Read blob data to variant value
1899 @param Index an filed index
1900 @param Value destination variant value
1902 procedure TZASASQLDA.ReadBlobToVariant(const Index: Word;
1903 var Value: Variant);
1908 with FSQLDA.sqlvar[Index] do
1911 if (sqlind^ < 0) then
1914 if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or
1915 ( sqlType and $FFFE = DT_LONGBINARY)) then
1917 Value := VarArrayCreate( [ 0, PZASABlobStruct( sqlData).untrunc_len-1], varByte);
1918 PData := VarArrayLock( Value);
1920 ReadBlob( Index, PData, PZASABlobStruct( sqlData).untrunc_len);
1922 VarArrayUnlock( Value);
1926 CreateException( Format( SErrorConvertionField,
1927 [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));
1932 Converts a ASA native types into ZDBC SQL types.
1933 @param SQLType Field of TASASQLVar structure.
1934 @return a SQL undepended type.
1936 function ConvertASATypeToSQLType(const SQLType: SmallInt;
1937 const CtrlsCPType: TZControlsCodePage): TZSQLType;
1939 case SQLType and $FFFE of
1941 Result := stUnknown;
1945 Result := stInteger;
1947 Result := stDouble; //BCD Fields not supported
1954 DT_VARIABLE, DT_STRING, DT_FIXCHAR, DT_VARCHAR, DT_NSTRING, DT_NFIXCHAR, DT_NVARCHAR:
1955 if (CtrlsCPType = cCP_UTF16) then
1956 Result := stUnicodeString
1959 DT_LONGVARCHAR, DT_LONGNVARCHAR:
1960 if (CtrlsCPType = cCP_UTF16) then
1961 Result := stUnicodeStream
1963 Result := stAsciiStream;
1967 Result := stTimestamp;
1968 DT_TIMESTAMP_STRUCT:
1969 Result := stTimestamp;
1973 Result := stBinaryStream;
1979 Result := stInteger;
1985 Result := stBoolean;
1987 Result := stUnknown;
1992 Converts a ASA native type into String.
1993 @param SQLType Field of TASASQLVar structure.
1994 @return type description.
1996 function ConvertASATypeToString( SQLType: SmallInt): String;
1998 case SQLType and $FFFE of
2000 Result := 'DT_SMALLINT';
2004 Result := 'DT_DECIMAL'; //BCD Fields not supported
2006 Result := 'DT_FLOAT';
2008 Result := 'DT_DOUBLE';
2010 Result := 'DT_DATE';
2012 Result := 'DT_VARIABLE';
2014 Result := 'DT_STRING';
2016 Result := 'DT_FIXCHAR';
2018 Result := 'DT_VARCHAR';
2020 Result := 'DT_LONGVARCHAR';
2022 Result := 'DT_TIME';
2024 Result := 'DT_TIMESTAMP';
2025 DT_TIMESTAMP_STRUCT:
2026 Result := 'DT_TIMESTAMP_STRUCT';
2028 Result := 'DT_BINARY';
2030 Result := 'DT_LONGBINARY';
2032 Result := 'DT_TINYINT';
2034 Result := 'DT_BIGINT';
2036 Result := 'DT_UNSINT';
2038 Result := 'DT_UNSSMALLINT';
2040 Result := 'DT_UNSBIGINT';
2044 Result := 'DT_NSTRING';
2046 Result := 'DT_NFIXCHAR';
2048 Result := 'DT_NVARCHAR';
2050 Result := 'DT_LONGNVARCHAR';
2052 Result := 'Unknown';
2057 Converts an ODBC native types into ZDBC SQL types.
2058 @param FieldType dblibc native field type.
2059 @return a SQL undepended type.
2061 function ConvertASAJDBCToSqlType(const FieldType: SmallInt;
2062 CtrlsCPType: TZControlsCodePage): TZSQLType;
2066 if (CtrlsCPType = cCP_UTF16) then
2067 Result := stUnicodeString
2070 -7: Result := stBoolean;
2071 -6: Result := stByte;
2072 5: Result := stShort;
2073 4: Result := stInteger;
2074 -5 : Result := stLong;
2075 6, 7, 8: Result := stDouble;
2076 2, 3: Result := stDouble; //BCD Feld
2077 11, 93: Result := stTimestamp;
2079 if (CtrlsCPType = cCP_UTF16) then
2080 Result := stUnicodeStream
2082 Result := stAsciiStream;
2083 -4, -11, 1111: Result := stBinaryStream;
2084 -3, -2: Result := stBytes;
2085 92: Result := stTime;
2086 91: Result := stDate;
2088 Result := stUnknown;
2092 procedure TSQLTimeStampToASADateTime( DT: TSQLTimeStamp; const ASADT: PZASASQLDateTime);
2094 ASADT.Year := DT.Year;
2095 ASADT.Month := DT.Month - 1;
2096 ASADT.Day := DT.Day;
2097 ASADT.Hour := DT.Hour;
2098 ASADT.Minute := DT.Minute;
2099 ASADT.Second := DT.Second;
2100 ASADT.MicroSecond := DT.Fractions * 10;
2101 ASADT.Day_of_Week := 0;
2102 ASADT.Day_of_Year := 0;
2105 function ASADateTimeToSQLTimeStamp( ASADT: PZASASQLDateTime): TSQLTimeStamp;
2107 DT.Year := ASADT.Year;
2108 DT.Month := ASADT.Month + 1;
2109 DT.Day := ASADT.Day;
2110 DT.Hour := ASADT.Hour;
2111 DT.Minute := ASADT.Minute;
2112 DT.Second := ASADT.Second;
2113 DT.Fractions := ASADT.MicroSecond div 10;
2117 Checks for possible sql errors.
2118 @param PlainDriver a MySQL plain driver.
2119 @param Handle a MySQL connection handle.
2120 @param LogCategory a logging category.
2121 @param LogMessage a logging message.
2123 procedure CheckASAError( PlainDriver: IZASAPlainDriver;
2124 Handle: PZASASQLCA; LogCategory: TZLoggingCategory; LogMessage: string = '';
2125 SupressExceptionID: Integer = 0);
2127 ErrorBuf: array[0..1024] of AnsiChar;
2128 ErrorMessage: string;
2130 if Handle.SqlCode < SQLE_NOERROR then
2132 ErrorMessage := String(PlainDriver.sqlError_Message( Handle, ErrorBuf, SizeOf( ErrorBuf)));
2133 //SyntaxError Position in SQLCount
2134 if not (SupressExceptionID = Handle.SqlCode ) then
2136 DriverManager.LogError( LogCategory, PlainDriver.GetProtocol, LogMessage,
2137 Handle.SqlCode, ErrorMessage);
2139 raise EZSQLException.CreateWithCode( Handle.SqlCode,
2140 Format(SSQLError1, [ErrorMessage]));
2146 Create CachedResultSet with using TZCachedResultSet and return it.
2147 @param SQL a sql query command
2148 @param Statement a zeos statement object
2149 @param NativeResultSet a native result set
2150 @return cached ResultSet
2152 function GetCachedResultSet(SQL: string;
2153 Statement: IZStatement; NativeResultSet: IZResultSet): IZResultSet;
2155 CachedResultSet: TZCachedResultSet;
2157 if (Statement.GetResultSetConcurrency <> rcReadOnly)
2158 or (Statement.GetResultSetType <> rtForwardOnly) then
2160 CachedResultSet := TZCachedResultSet.Create( NativeResultSet, SQL, nil,
2161 Statement.GetConnection.GetConSettings);
2162 CachedResultSet.SetResolver( TZASACachedResolver.Create(
2163 Statement, NativeResultSet.GetMetadata));
2164 CachedResultSet.SetConcurrency( Statement.GetResultSetConcurrency);
2165 Result := CachedResultSet;
2168 Result := NativeResultSet;
2171 procedure DescribeCursor( FASAConnection: IZASAConnection; FSQLData: IZASASQLDA;
2172 Cursor: AnsiString; SQL: String);
2174 FSQLData.AllocateSQLDA( StdVars);
2175 with FASAConnection do
2177 GetPlainDriver.db_describe_cursor(GetDBHandle, PAnsiChar(Cursor), FSQLData.GetData, SQL_DESCRIBE_OUTPUT);
2178 ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, SQL);
2179 if FSQLData.GetData^.sqld <= 0 then
2180 raise EZSQLException.Create( SCanNotRetrieveResultSetData)
2181 else if ( FSQLData.GetData^.sqld > FSQLData.GetData^.sqln) then
2183 FSQLData.AllocateSQLDA( FSQLData.GetData^.sqld);
2184 GetPlainDriver.db_describe_cursor(GetDBHandle, PAnsiChar(Cursor), FSQLData.GetData, SQL_DESCRIBE_OUTPUT);
2185 ZDbcASAUtils.CheckASAError(GetPlainDriver, GetDBHandle, lcExecute, SQL);
2187 FSQLData.InitFields;
2191 procedure ASAPrepare( FASAConnection: IZASAConnection; FSQLData, FParamsSQLData: IZASASQLDA;
2192 const SQL: RawByteString; const LogSQL: String; StmtNum: PSmallInt; var FPrepared, FMoreResults: Boolean);
2194 with FASAConnection do
2198 FParamsSQLData.AllocateSQLDA( StdVars);
2199 FSQLData.AllocateSQLDA( StdVars);
2200 if StmtNum^ <> 0 then
2202 GetPlainDriver.db_dropstmt( GetDBHandle, nil, nil, StmtNum);
2207 GetPlainDriver.db_prepare_describe( GetDBHandle, nil, StmtNum,
2208 PAnsiChar(SQL), FParamsSQLData.GetData, SQL_PREPARE_DESCRIBE_STMTNUM +
2209 SQL_PREPARE_DESCRIBE_INPUT + SQL_PREPARE_DESCRIBE_VARRESULT, 0);
2210 ZDbcASAUtils.CheckASAError(GetPlainDriver, GetDBHandle, lcExecute, LogSQL);
2212 FMoreResults := GetDBHandle.sqlerrd[2] = 0;
2214 if FParamsSQLData.GetData^.sqld > FParamsSQLData.GetData^.sqln then
2216 FParamsSQLData.AllocateSQLDA( FParamsSQLData.GetData^.sqld);
2217 GetPlainDriver.db_describe( GetDBHandle, nil, StmtNum,
2218 FParamsSQLData.GetData, SQL_DESCRIBE_INPUT);
2219 ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);
2222 if not FMoreResults then
2224 GetPlainDriver.db_describe( GetDBHandle, nil, StmtNum,
2225 FSQLData.GetData, SQL_DESCRIBE_OUTPUT);
2226 ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);
2227 if FSQLData.GetData^.sqld > FSQLData.GetData^.sqln then
2229 FSQLData.AllocateSQLDA( FSQLData.GetData^.sqld);
2230 GetPlainDriver.db_describe( GetDBHandle, nil, StmtNum,
2231 FSQLData.GetData, SQL_DESCRIBE_OUTPUT);
2232 ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);
2234 FSQLData.InitFields;
2238 { Logging SQL Command }
2239 DriverManager.LogMessage( lcExecute, GetPlainDriver.GetProtocol,
2240 'Prepare: '+ LogSQL);
2244 if StmtNum^ <> 0 then
2245 GetPlainDriver.db_dropstmt( GetDBHandle, nil, nil, StmtNum);
2252 procedure PrepareParameters( PlainDriver: IZASAPlainDriver;
2253 InParamValues: TZVariantDynArray; InParamTypes: TZSQLTypeArray;
2254 InParamCount: Integer; ParamSqlData: IZASASQLDA; ConSettings: PZConSettings);
2258 TempStream: TStream;
2260 if InParamCount <> ParamSqlData.GetFieldCount then
2261 raise EZSQLException.Create( SInvalidInputParameterCount);
2262 for i := 0 to ParamSqlData.GetFieldCount-1 do
2263 if DefVarManager.IsNull( InParamValues[i])then
2264 ParamSqlData.UpdateNull( i, True)
2266 case InParamTypes[i] of
2268 ParamSqlData.UpdateBoolean( i,
2269 SoftVarManager.GetAsBoolean( InParamValues[i]));
2271 ParamSqlData.UpdateByte( i,
2272 SoftVarManager.GetAsInteger( InParamValues[i]));
2274 ParamSqlData.UpdateShort( i,
2275 SoftVarManager.GetAsInteger( InParamValues[i]));
2277 ParamSqlData.UpdateInt( i,
2278 SoftVarManager.GetAsInteger( InParamValues[i]));
2280 ParamSqlData.UpdateLong( i,
2281 SoftVarManager.GetAsInteger( InParamValues[i]));
2283 ParamSqlData.UpdateFloat( i,
2284 SoftVarManager.GetAsFloat( InParamValues[i]));
2286 ParamSqlData.UpdateDouble( i,
2287 SoftVarManager.GetAsFloat( InParamValues[i]));
2289 ParamSqlData.UpdateBigDecimal( i,
2290 SoftVarManager.GetAsFloat( InParamValues[i]));
2292 ParamSqlData.UpdateString( i,
2293 PlainDriver.ZPlainString(SoftVarManager.GetAsString( InParamValues[i]), ConSettings));
2295 ParamSqlData.UpdateString( i,
2296 PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString( InParamValues[i]), ConSettings));
2298 ParamSqlData.UpdateBytes( i, SoftVarManager.GetAsBytes( InParamValues[i]));
2300 ParamSqlData.UpdateDate( i,
2301 SoftVarManager.GetAsDateTime( InParamValues[i]));
2303 ParamSqlData.UpdateTime( i,
2304 SoftVarManager.GetAsDateTime( InParamValues[i]));
2306 ParamSqlData.UpdateTimestamp( i,
2307 SoftVarManager.GetAsDateTime( InParamValues[i]));
2312 TempBlob := DefVarManager.GetAsInterface(InParamValues[I]) as IZBlob;
2313 if not TempBlob.IsEmpty then
2315 if (InParamTypes[i] in [stUnicodeStream, stAsciiStream]) then
2316 TempStream := TStringStream.Create(GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,
2317 TempBlob.Length, TempBlob.WasDecoded, ConSettings))
2319 TempStream := TempBlob.GetStream;
2320 if Assigned(TempStream) then
2322 ParamSqlData.WriteBlob(I, TempStream, InParamTypes[i]);
2328 raise EZASAConvertError.Create( SUnsupportedParameterType);
2333 Generate specific length random string and return it
2334 @param Len a length result string
2335 @return random string
2337 function RandomString( Len: integer): string;
2340 while Length( Result) < Len do
2341 Result := Result + IntToStr( Trunc( Random( High( Integer))));
2342 if Length( Result) > Len then
2343 Result := Copy( Result, 1, Len);