00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { Oracle 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 ZDbcOracleUtils;
00055
00056 interface
00057
00058 {$I ZDbc.inc}
00059
00060 uses
00061 {$IFNDEF VER130BELOW}
00062 Types,
00063 {$ENDIF}
00064 Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZVariant, ZPlainOracleDriver,
00065 ZDbcLogging, ZCompatibility;
00066
00067 const
00068 MAX_SQLVAR_LIMIT = 1024;
00069
00070 type
00071 {** Declares SQL Object }
00072 TZSQLVar = packed record
00073 Handle: POCIHandle;
00074 Define: POCIHandle;
00075 BindHandle: POCIBind;
00076 Data: Pointer;
00077 DupData: Pointer;
00078 DataType: ub2;
00079 DataSize: ub2;
00080 Length: Integer;
00081 Precision: Integer;
00082 Scale: Integer;
00083 ColType: TZSQLType;
00084 TypeCode: ub2;
00085 Indicator: sb2;
00086 Blob: IZBlob;
00087 end;
00088 PZSQLVar = ^TZSQLVar;
00089
00090 TZSQLVars = packed record
00091 AllocNum: ub4;
00092 ActualNum: ub4;
00093 Variables: array[1..MAX_SQLVAR_LIMIT] of TZSQLVar;
00094 end;
00095 PZSQLVars = ^TZSQLVars;
00096
00097 {**
00098 Allocates memory for Oracle SQL Variables.
00099 @param Variables a pointer to array of variables.
00100 @param Count a number of SQL variables.
00101 }
00102 procedure AllocateOracleSQLVars(var Variables: PZSQLVars; Count: Integer);
00103
00104 {**
00105 Frees memory Oracle SQL Variables from the memory.
00106 @param PlainDriver an Oracle plain driver.
00107 @param Variables a pointer to array of variables.
00108 }
00109 procedure FreeOracleSQLVars(PlainDriver: IZOraclePlainDriver;
00110 var Variables: PZSQLVars);
00111
00112 {**
00113 Allocates in memory and initializes the Oracle variable.
00114 @param PlainDriver an Oracle plain driver.
00115 @param Connection an Oracle connection Object.
00116 @param Variable an Oracle variable holder.
00117 @param DataType a DBC data type.
00118 @param OracleType a correspondent Oracle type.
00119 @param DataSize a length for string variables.
00120 }
00121 procedure InitializeOracleVar(PlainDriver: IZOraclePlainDriver;
00122 Connection: IZConnection; var Variable: PZSQLVar;
00123 DataType: TZSQLType; OracleType: ub2; DataSize: Integer);
00124
00125 {**
00126 Loads Oracle variables binded to SQL statement with data.
00127 @param PlainDriver an Oracle plain driver.
00128 @param Connection an Oracle connection Object.
00129 @param Variables Oracle variable holders.
00130 @param Values a values to be loaded.
00131 }
00132 procedure LoadOracleVars(PlainDriver: IZOraclePlainDriver;
00133 Connection: IZConnection; ErrorHandle: POCIError; Variables: PZSQLVars;
00134 Values: TZVariantDynArray);
00135
00136 {**
00137 Unloads Oracle variables binded to SQL statement with data.
00138 @param Variables Oracle variable holders.
00139 }
00140 procedure UnloadOracleVars(Variables: PZSQLVars);
00141
00142 {**
00143 Converts a MySQL native types into ZDBC SQL types.
00144 @param PlainDriver a native MySQL plain driver.
00145 @param FieldHandle a handler to field description structure.
00146 @param FieldFlags field flags.
00147 @return a SQL undepended type.
00148 }
00149
00150
00151
00152 {**
00153 Convert string Oracle field type to SQLType
00154 @param string field type value
00155 @result the SQLType field type value
00156 }
00157 function ConvertOracleTypeToSQLType(TypeName: string;
00158 Size: Integer; Precision: Integer): TZSQLType;
00159
00160 {**
00161 Converts Oracle internal date into TDateTime
00162 @param Value a pointer to Oracle internal date.
00163 @return a decoded TDateTime value.
00164 }
00165 function OraDateToDateTime(Value: PChar): TDateTime;
00166
00167 {**
00168 Checks for possible SQL errors.
00169 @param PlainDriver an Oracle plain driver.
00170 @param Handle an Oracle error handle.
00171 @param Status a command return status.
00172 @param LogCategory a logging category.
00173 @param LogMessage a logging message.
00174 }
00175 procedure CheckOracleError(PlainDriver: IZOraclePlainDriver;
00176 ErrorHandle: POCIError; Status: Integer; LogCategory: TZLoggingCategory;
00177 LogMessage: string);
00178
00179 {**
00180 Creates an Oracle result set based on the current settings.
00181 @return a created result set object.
00182 }
00183 function CreateOracleResultSet(PlainDriver: IZOraclePlainDriver;
00184 Statement: IZStatement; SQL: string; Handle: POCIStmt;
00185 ErrorHandle: POCIError): IZResultSet;
00186
00187 {**
00188 Allocates in memory Oracle handlers for Statement object.
00189 @param PlainDriver an Oracle plain driver.
00190 @param Connection an Oracle connection object.
00191 @param Handle a holder for Statement handle.
00192 @param ErrorHandle a holder for Error handle.
00193 }
00194 procedure AllocateOracleStatementHandles(PlainDriver: IZOraclePlainDriver;
00195 Connection: IZConnection; var Handle: POCIStmt; var ErrorHandle: POCIError);
00196
00197 {**
00198 Frees from memory Oracle handlers for Statement object.
00199 @param PlainDriver an Oracle plain driver.
00200 @param Handle a holder for Statement handle.
00201 @param ErrorHandle a holder for Error handle.
00202 }
00203 procedure FreeOracleStatementHandles(PlainDriver: IZOraclePlainDriver;
00204 var Handle: POCIStmt; var ErrorHandle: POCIError);
00205
00206 {**
00207 Prepares an Oracle statement.
00208 @param PlainDriver an Oracle plain driver.
00209 @param SQL an SQL query to be prepared.
00210 @param Handle a holder for Statement handle.
00211 @param ErrorHandle a holder for Error handle.
00212 }
00213 procedure PrepareOracleStatement(PlainDriver: IZOraclePlainDriver;
00214 SQL: string; Handle: POCIStmt; ErrorHandle: POCIError);
00215
00216 {**
00217 Executes an Oracle statement.
00218 @param PlainDriver an Oracle plain driver.
00219 @param Connection an Oracle connection Object.
00220 @param SQL an SQL query to be prepared.
00221 @param Handle a holder for Statement handle.
00222 @param ErrorHandle a holder for Error handle.
00223 }
00224 procedure ExecuteOracleStatement(PlainDriver: IZOraclePlainDriver;
00225 Connection: IZConnection; SQL: string; Handle: POCIStmt;
00226 ErrorHandle: POCIError);
00227
00228 {**
00229 Gets a number of updates made by executed Oracle statement.
00230 @param PlainDriver an Oracle plain driver.
00231 @param Handle a holder for Statement handle.
00232 @param ErrorHandle a holder for Error handle.
00233 @returns a number of updates.
00234 }
00235 function GetOracleUpdateCount(PlainDriver: IZOraclePlainDriver;
00236 Handle: POCIStmt; ErrorHandle: POCIError): ub4;
00237
00238 implementation
00239
00240 uses ZMessages, ZDbcOracle, ZDbcOracleResultSet, ZDbcCachedResultSet,
00241 ZDbcGenericResolver;
00242
00243 {**
00244 Calculates size of SQLVars record.
00245 @param Count a number of variable.
00246 @returns a record size.
00247 }
00248 function CalculateSQLVarsSize(Count: Integer): Integer;
00249 begin
00250 Result := SizeOf(TZSQLVars) + Count * SizeOf(TZSQLVar);
00251 end;
00252
00253 {**
00254 Allocates memory for Oracle SQL Variables.
00255 @param Variables a pointer to array of variables.
00256 @param Count a number of SQL variables.
00257 }
00258 procedure AllocateOracleSQLVars(var Variables: PZSQLVars; Count: Integer);
00259 var
00260 Size: Integer;
00261 begin
00262 if Variables <> nil then
00263 FreeMem(Variables);
00264
00265 Size := CalculateSQLVarsSize(Count);
00266 GetMem(Variables, Size);
00267 FillChar(Variables^, Size, 0);
00268 Variables^.AllocNum := Count;
00269 Variables^.ActualNum := 0;
00270 end;
00271
00272 {**
00273 Frees memory Oracle SQL Variables from the memory.
00274 @param PlainDriver an Oracle plain driver.
00275 @param Variables a pointer to array of variables.
00276 }
00277 procedure FreeOracleSQLVars(PlainDriver: IZOraclePlainDriver;
00278 var Variables: PZSQLVars);
00279 var
00280 I: Integer;
00281 CurrentVar: PZSQLVar;
00282 begin
00283 if Variables <> nil then
00284 begin
00285 { Frees allocated memory for output variables }
00286 for I := 1 to Variables.ActualNum do
00287 begin
00288 CurrentVar := @Variables.Variables[I];
00289 if CurrentVar.Data <> nil then
00290 begin
00291 if CurrentVar.TypeCode in [SQLT_BLOB, SQLT_CLOB] then
00292 begin
00293 PlainDriver.DescriptorFree(PPOCIDescriptor(CurrentVar.Data)^,
00294 OCI_DTYPE_LOB);
00295 end
00296 else if CurrentVar.TypeCode = SQLT_TIMESTAMP then
00297 begin
00298 PlainDriver.DescriptorFree(PPOCIDescriptor(CurrentVar.Data)^,
00299 OCI_DTYPE_TIMESTAMP);
00300 end;
00301 FreeMem(CurrentVar.Data);
00302 CurrentVar.Data := nil;
00303 end;
00304 end;
00305
00306 FreeMem(Variables);
00307 end;
00308 Variables := nil;
00309 end;
00310
00311 {**
00312 Allocates in memory and initializes the Oracle variable.
00313 @param PlainDriver an Oracle plain driver.
00314 @param Connection an Oracle connection Object.
00315 @param Variable an Oracle variable holder.
00316 @param DataType a DBC data type.
00317 @param OracleType a correspondent Oracle type.
00318 @param DataSize a length for string variables.
00319 }
00320 procedure InitializeOracleVar(PlainDriver: IZOraclePlainDriver;
00321 Connection: IZConnection; var Variable: PZSQLVar;
00322 DataType: TZSQLType; OracleType: ub2; DataSize: Integer);
00323 var
00324 Length: Integer;
00325 OracleConnection: IZOracleConnection;
00326 begin
00327 OracleConnection := Connection as IZOracleConnection;
00328 Variable.ColType := DataType;
00329 Variable.TypeCode := OracleType;
00330 Variable.DataSize := DataSize;
00331 Length := 0;
00332 case Variable.ColType of
00333 stByte, stShort, stInteger, stLong:
00334 begin
00335 Variable.TypeCode := SQLT_INT;
00336 Length := SizeOf(LongInt);
00337 end;
00338 stFloat, stDouble:
00339 begin
00340 Variable.TypeCode := SQLT_FLT;
00341 Length := SizeOf(Double);
00342 end;
00343 stDate, stTime, stTimestamp:
00344 begin
00345 Variable.TypeCode := SQLT_TIMESTAMP;
00346 Length := SizeOf(POCIDateTime);
00347 end;
00348 stString:
00349 begin
00350 Variable.TypeCode := SQLT_STR;
00351 Length := Variable.DataSize + 1;
00352 end;
00353 stAsciiStream, stBinaryStream:
00354 begin
00355 if not (Variable.TypeCode in [SQLT_CLOB, SQLT_BLOB]) then
00356 begin
00357 if Variable.ColType = stAsciiStream then
00358 Variable.TypeCode := SQLT_LVC
00359 else Variable.TypeCode := SQLT_LVB;
00360 if Variable.DataSize = 0 then
00361 Length := 128 * 1024 + SizeOf(Integer)
00362 else Length := Variable.DataSize + SizeOf(Integer);
00363 end else
00364 Length := SizeOf(POCILobLocator);
00365 end;
00366 stUnknown:
00367 Exit;
00368 end;
00369
00370 Variable.Length := Length;
00371 GetMem(Variable.Data, Variable.Length);
00372 if Variable.TypeCode in [SQLT_BLOB, SQLT_CLOB] then
00373 begin
00374 PlainDriver.DescriptorAlloc(OracleConnection.GetConnectionHandle,
00375 PPOCIDescriptor(Variable.Data)^, OCI_DTYPE_LOB, 0, nil);
00376 end
00377 else if Variable.TypeCode = SQLT_TIMESTAMP then
00378 begin
00379 PlainDriver.DescriptorAlloc(OracleConnection.GetConnectionHandle,
00380 PPOCIDescriptor(Variable.Data)^, OCI_DTYPE_TIMESTAMP, 0, nil);
00381 end;
00382 end;
00383
00384 {**
00385 Loads Oracle variables binded to SQL statement with data.
00386 @param PlainDriver an Oracle plain driver.
00387 @param Connection an Oracle connection Object.
00388 @param Variables Oracle variable holders.
00389 @param Values a values to be loaded.
00390 }
00391 procedure LoadOracleVars(PlainDriver: IZOraclePlainDriver;
00392 Connection: IZConnection; ErrorHandle: POCIError; Variables: PZSQLVars;
00393 Values: TZVariantDynArray);
00394 var
00395 I: Integer;
00396 Status: Integer;
00397 CurrentVar: PZSQLVar;
00398 TempDate: TDateTime;
00399 TempBlob: IZBlob;
00400 WriteTempBlob: IZOracleBlob;
00401 TempStream: TStream;
00402 Year, Month, Day, Hour, Min, Sec, MSec: Word;
00403 OracleConnection: IZOracleConnection;
00404 begin
00405 OracleConnection := Connection as IZOracleConnection;
00406 for I := 0 to Variables.ActualNum - 1 do
00407 begin
00408 CurrentVar := @Variables.Variables[I + 1];
00409 CurrentVar.DupData := CurrentVar.Data;
00410 if DefVarManager.IsNull(Values[I]) then
00411 begin
00412 CurrentVar.Indicator := -1;
00413 CurrentVar.Data := nil;
00414 end
00415 else
00416 begin
00417 CurrentVar.Indicator := 0;
00418 case CurrentVar.TypeCode of
00419 SQLT_INT:
00420 begin
00421 PLongInt(CurrentVar.Data)^ :=
00422 DefVarManager.GetAsInteger(Values[I]);
00423 end;
00424 SQLT_FLT:
00425 begin
00426 PDouble(CurrentVar.Data)^ :=
00427 DefVarManager.GetAsFloat(Values[I]);
00428 end;
00429 SQLT_STR:
00430 begin
00431 StrLCopy(PChar(CurrentVar.Data),
00432 PChar(DefVarManager.GetAsString(Values[I])), 1024);
00433 end;
00434 SQLT_TIMESTAMP:
00435 begin
00436 TempDate := DefVarManager.GetAsDateTime(Values[I]);
00437 DecodeDate(TempDate, Year, Month, Day);
00438 DecodeTime(TempDate, Hour, Min, Sec, MSec);
00439 Status := PlainDriver.DateTimeConstruct(
00440 OracleConnection.GetConnectionHandle,
00441 ErrorHandle, PPOCIDescriptor(CurrentVar.Data)^,
00442 Year, Month, Day, Hour, Min, Sec, MSec, nil, 0);
00443 CheckOracleError(PlainDriver, ErrorHandle, Status, lcOther, '');
00444 end;
00445 SQLT_BLOB, SQLT_CLOB:
00446 begin
00447 TempBlob := DefVarManager.GetAsInterface(Values[I]) as IZBlob;
00448 TempStream := TempBlob.GetStream;
00449 try
00450 WriteTempBlob := TZOracleBlob.Create(PlainDriver,
00451 nil, 0, Connection, PPOCIDescriptor(CurrentVar.Data)^,
00452 CurrentVar.ColType);
00453 WriteTempBlob.SetStream(TempStream);
00454 WriteTempBlob.CreateBlob;
00455 WriteTempBlob.WriteBlob;
00456 CurrentVar.Blob := WriteTempBlob;
00457 finally
00458 WriteTempBlob := nil;
00459 TempStream.Free;
00460 end;
00461 end;
00462 end;
00463 end;
00464 end;
00465 end;
00466
00467 {**
00468 Unloads Oracle variables binded to SQL statement with data.
00469 @param Variables Oracle variable holders.
00470 }
00471 procedure UnloadOracleVars(Variables: PZSQLVars);
00472 var
00473 I: Integer;
00474 CurrentVar: PZSQLVar;
00475 begin
00476 for I := 1 to Variables.ActualNum do
00477 begin
00478 CurrentVar := @Variables.Variables[I + 1];
00479 CurrentVar.Blob := nil;
00480 CurrentVar.Data := CurrentVar.DupData;
00481 end;
00482 end;
00483
00484 (*
00485
00486 {**
00487 Converts a MySQL native types into ZDBC SQL types.
00488 @param PlainDriver a native MySQL plain driver.
00489 @param FieldHandle a handler to field description structure.
00490 @param FieldFlags a field flags.
00491 @return a SQL undepended type.
00492 }
00493 function ConvertMySQLHandleToSQLType(PlainDriver: IZMySQLPlainDriver;
00494 FieldHandle: PZMySQLField; FieldFlags: Integer): TZSQLType;
00495 begin
00496 case PlainDriver.GetFieldType(FieldHandle) of
00497 FIELD_TYPE_TINY:
00498 begin
00499 if (UNSIGNED_FLAG and FieldFlags) = 0 then
00500 Result := stByte
00501 else Result := stShort;
00502 end;
00503 FIELD_TYPE_YEAR, FIELD_TYPE_SHORT:
00504 begin
00505 if (UNSIGNED_FLAG and FieldFlags) = 0 then
00506 Result := stShort
00507 else Result := stInteger;
00508 end;
00509 FIELD_TYPE_INT24, FIELD_TYPE_LONG:
00510 begin
00511 if (UNSIGNED_FLAG and FieldFlags) = 0 then
00512 Result := stInteger
00513 else Result := stLong;
00514 end;
00515 FIELD_TYPE_LONGLONG:
00516 begin
00517 if (UNSIGNED_FLAG and FieldFlags) = 0 then
00518 Result := stLong
00519 else Result := stBigDecimal;
00520 end;
00521 FIELD_TYPE_FLOAT:
00522 Result := stFloat;
00523 FIELD_TYPE_DECIMAL:
00524 begin
00525 if PlainDriver.GetFieldDecimals(FieldHandle) = 0 then
00526 begin
00527 if PlainDriver.GetFieldLength(FieldHandle) < 11 then
00528 Result := stInteger
00529 else Result := stLong;
00530 end else
00531 Result := stDouble;
00532 end;
00533 FIELD_TYPE_DOUBLE:
00534 Result := stDouble;
00535 FIELD_TYPE_DATE, FIELD_TYPE_NEWDATE:
00536 Result := stDate;
00537 FIELD_TYPE_TIME:
00538 Result := stTime;
00539 FIELD_TYPE_DATETIME, FIELD_TYPE_TIMESTAMP:
00540 Result := stTimestamp;
00541 FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB,
00542 FIELD_TYPE_LONG_BLOB, FIELD_TYPE_BLOB:
00543 if (FieldFlags and BINARY_FLAG) = 0 then
00544 Result := stAsciiStream
00545 else Result := stBinaryStream;
00546 else
00547 Result := stString;
00548 end;
00549 end;
00550 *)
00551
00552 {**
00553 Convert string Oracle field type to SQLType
00554 @param string field type value
00555 @result the SQLType field type value
00556 }
00557 function ConvertOracleTypeToSQLType(TypeName: string;
00558 Size: Integer; Precision: Integer): TZSQLType;
00559 begin
00560 TypeName := UpperCase(TypeName);
00561 Result := stUnknown;
00562
00563 if (TypeName = 'CHAR') or (TypeName = 'VARCHAR2') then
00564 Result := stString
00565 else if (TypeName = 'NCHAR') or (TypeName = 'NVARCHAR2') then
00566 Result := stUnicodeString
00567 else if TypeName = 'FLOAT' then
00568 Result := stDouble
00569 else if TypeName = 'DATE' then
00570 Result := stDate
00571 else if TypeName = 'BLOB' then
00572 Result := stBinaryStream
00573 else if (TypeName = 'RAW') or (TypeName = 'LONG RAW') then
00574 Result := stBinaryStream
00575 else if TypeName = 'CLOB' then
00576 Result := stAsciiStream
00577 else if TypeName = 'NCLOB' then
00578 Result := stUnicodeStream
00579 else if TypeName = 'LONG' then
00580 Result := stAsciiStream
00581 else if StartsWith(TypeName, 'TIMESTAMP') then
00582 Result := stTimestamp
00583 else if TypeName = 'NUMBER' then
00584 begin
00585 if Precision = 0 then
00586 begin
00587 if Size = 0 then
00588 Result := stLong
00589 else if Size <= 2 then
00590 Result := stByte
00591 else if Size <= 4 then
00592 Result := stShort
00593 else if Size <= 9 then
00594 Result := stInteger
00595 else Result := stLong
00596 end else
00597 Result := stDouble;
00598 end;
00599 end;
00600
00601 {**
00602 Converts Oracle internal date into TDateTime
00603 @param Value a pointer to Oracle internal date.
00604 @return a decoded TDateTime value.
00605 }
00606 function OraDateToDateTime(Value: PChar): TDateTime;
00607 type
00608 TOraDate = array[1..7] of Byte;
00609 POraDate = ^TOraDate;
00610 var
00611 Ptr: POraDate;
00612 begin
00613 Ptr := POraDate(Value);
00614 Result := EncodeDate((Ptr[1] - 100) * 100 + Ptr[2] - 100, Ptr[3], Ptr[4]) +
00615 EncodeTime(Ptr[5]-1, Ptr[6]-1, Ptr[7]-1, 0);
00616 end;
00617
00618 {**
00619 Checks for possible SQL errors.
00620 @param PlainDriver an Oracle plain driver.
00621 @param Handle an Oracle error handle.
00622 @param Status a command return status.
00623 @param LogCategory a logging category.
00624 @param LogMessage a logging message.
00625 }
00626 procedure CheckOracleError(PlainDriver: IZOraclePlainDriver;
00627 ErrorHandle: POCIError; Status: Integer; LogCategory: TZLoggingCategory;
00628 LogMessage: string);
00629 var
00630 ErrorMessage: string;
00631 ErrorBuffer: array[0..255] of Char;
00632 ErrorCode: SB4;
00633 begin
00634 ErrorMessage := '';
00635 ErrorCode := Status;
00636
00637 case Status of
00638 OCI_SUCCESS:
00639 Exit;
00640 OCI_SUCCESS_WITH_INFO:
00641 ErrorMessage := 'OCI_SUCCESS_WITH_INFO';
00642 OCI_NEED_DATA:
00643 ErrorMessage := 'OCI_NEED_DATA';
00644 OCI_NO_DATA:
00645 ErrorMessage := 'OCI_NO_DATA';
00646 OCI_ERROR:
00647 begin
00648 PlainDriver.ErrorGet(ErrorHandle, 1, nil, ErrorCode, ErrorBuffer, 255,
00649 OCI_HTYPE_ERROR);
00650 ErrorMessage := StrPas(ErrorBuffer);
00651 end;
00652 OCI_INVALID_HANDLE:
00653 ErrorMessage := 'OCI_INVALID_HANDLE';
00654 OCI_STILL_EXECUTING:
00655 ErrorMessage := 'OCI_STILL_EXECUTING';
00656 OCI_CONTINUE:
00657 ErrorMessage := 'OCI_CONTINUE';
00658 end;
00659
00660 if (ErrorCode <> OCI_SUCCESS) and (ErrorMessage <> '') then
00661 begin
00662 DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,
00663 ErrorCode, ErrorMessage);
00664 raise EZSQLException.CreateWithCode(ErrorCode,
00665 Format(SSQLError1, [ErrorMessage]));
00666 end;
00667 end;
00668
00669 {**
00670 Creates an Oracle result set based on the current settings.
00671 @return a created result set object.
00672 }
00673 function CreateOracleResultSet(PlainDriver: IZOraclePlainDriver;
00674 Statement: IZStatement; SQL: string; Handle: POCIStmt;
00675 ErrorHandle: POCIError): IZResultSet;
00676 var
00677 NativeResultSet: TZOracleResultSet;
00678 CachedResultSet: TZCachedResultSet;
00679 begin
00680 NativeResultSet := TZOracleResultSet.Create(PlainDriver, Statement,
00681 SQL, Handle, ErrorHandle);
00682 NativeResultSet.SetConcurrency(rcReadOnly);
00683 if (Statement.GetResultSetConcurrency = rcUpdatable)
00684 or (Statement.GetResultSetType <> rtForwardOnly) then
00685 begin
00686 CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL, nil);
00687 CachedResultSet.SetConcurrency(rcUpdatable);
00688 CachedResultSet.SetResolver(TZOracleCachedResolver.Create(
00689 Statement, NativeResultSet.GetMetadata));
00690 Result := CachedResultSet;
00691 end else
00692 Result := NativeResultSet;
00693 end;
00694
00695 {**
00696 Allocates in memory Oracle handlers for Statement object.
00697 @param PlainDriver an Oracle plain driver.
00698 @param Connection an Oracle connection object.
00699 @param Handle a holder for Statement handle.
00700 @param ErrorHandle a holder for Error handle.
00701 }
00702 procedure AllocateOracleStatementHandles(PlainDriver: IZOraclePlainDriver;
00703 Connection: IZConnection; var Handle: POCIStmt; var ErrorHandle: POCIError);
00704 var
00705 OracleConnection: IZOracleConnection;
00706 begin
00707 OracleConnection := Connection as IZOracleConnection;
00708 ErrorHandle := nil;
00709 PlainDriver.HandleAlloc(OracleConnection.GetConnectionHandle,
00710 ErrorHandle, OCI_HTYPE_ERROR, 0, nil);
00711 Handle := nil;
00712 PlainDriver.HandleAlloc(OracleConnection.GetConnectionHandle,
00713 Handle, OCI_HTYPE_STMT, 0, nil);
00714 end;
00715
00716 {**
00717 Frees from memory Oracle handlers for Statement object.
00718 @param PlainDriver an Oracle plain driver.
00719 @param Handle a holder for Statement handle.
00720 @param ErrorHandle a holder for Error handle.
00721 }
00722 procedure FreeOracleStatementHandles(PlainDriver: IZOraclePlainDriver;
00723 var Handle: POCIStmt; var ErrorHandle: POCIError);
00724 begin
00725 if ErrorHandle <> nil then
00726 begin
00727 PlainDriver.HandleFree(ErrorHandle, OCI_HTYPE_ERROR);
00728 ErrorHandle := nil;
00729 end;
00730 if Handle <> nil then
00731 begin
00732 PlainDriver.HandleFree(Handle, OCI_HTYPE_STMT);
00733 Handle := nil;
00734 end;
00735 end;
00736
00737 {**
00738 Prepares an Oracle statement.
00739 @param PlainDriver an Oracle plain driver.
00740 @param SQL an SQL query to be prepared.
00741 @param Handle a holder for Statement handle.
00742 @param ErrorHandle a holder for Error handle.
00743 }
00744 procedure PrepareOracleStatement(PlainDriver: IZOraclePlainDriver;
00745 SQL: string; Handle: POCIStmt; ErrorHandle: POCIError);
00746 var
00747 Status: Integer;
00748 begin
00749 Status := PlainDriver.StmtPrepare(Handle, ErrorHandle, PChar(SQL),
00750 Length(SQL), OCI_NTV_SYNTAX, OCI_DEFAULT);
00751 CheckOracleError(PlainDriver, ErrorHandle, Status, lcExecute, SQL);
00752 end;
00753
00754 {**
00755 Executes an Oracle statement.
00756 @param PlainDriver an Oracle plain driver.
00757 @param Connection an Oracle connection Object.
00758 @param SQL an SQL query to be prepared.
00759 @param Handle a holder for Statement handle.
00760 @param ErrorHandle a holder for Error handle.
00761 }
00762 procedure ExecuteOracleStatement(PlainDriver: IZOraclePlainDriver;
00763 Connection: IZConnection; SQL: string; Handle: POCIStmt; ErrorHandle: POCIError);
00764 var
00765 Status: Integer;
00766 OracleConnection: IZOracleConnection;
00767 begin
00768 OracleConnection := Connection as IZOracleConnection;
00769 Status := PlainDriver.StmtExecute(OracleConnection.GetContextHandle,
00770 Handle, ErrorHandle, 1, 0, nil, nil, OCI_DEFAULT);
00771 CheckOracleError(PlainDriver, ErrorHandle, Status, lcExecute, SQL);
00772 end;
00773
00774 {**
00775 Gets a number of updates made by executed Oracle statement.
00776 @param PlainDriver an Oracle plain driver.
00777 @param Handle a holder for Statement handle.
00778 @param ErrorHandle a holder for Error handle.
00779 @returns a number of updates.
00780 }
00781 function GetOracleUpdateCount(PlainDriver: IZOraclePlainDriver;
00782 Handle: POCIStmt; ErrorHandle: POCIError): ub4;
00783 begin
00784 Result := 0;
00785 PlainDriver.AttrGet(Handle, OCI_HTYPE_STMT, @Result, nil,
00786 OCI_ATTR_ROW_COUNT, ErrorHandle);
00787 end;
00788
00789 end.