Oracle Lock fails on Datetime value?

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
tobias_cd
Posts: 56
Joined: Thu 18 Dec 2008 22:10

Oracle Lock fails on Datetime value?

Post by tobias_cd » Sat 06 Mar 2010 10:06

Hi,
within a TUniQuery I have a row which upon "Edit" causes a "record changed by another user" on Oracle 10.2.0.2.

Setup: Win7, 32bit; Delphi 2007 (with SP); UniDac 3.0.0.4 w/src; LockMode = lmPessimistic; default datetimeformat in session: 'dd.mm.yyyy hh24:mi:ss'

I tracked it down to these calls in order:
1) unit DBAccess, function "CopyRecBuf" calls in line 10015:
2) unit DBAccess, function "LockCompare" calls in line 9662:
3) unit MemUtils.pas, function "VarEqual" (starting line 433)

The last function returns, well, incorrect results with datetimes:

Within "VarEqual" the 2 variables "value1" AND "value2" display both the same text within the debugger like this: '31.12.1899 14:45:00'.

Both columns show the same values as well in TOAD (SQL tool); during debugging the dates as double value show as "1,61458333333333" for both variables.

Now, in "VarEqual" the very last line in the original source

Code: Select all

 Result := Value1 = Value2;
returns FALSE with above values.

Btw, the same would occur for this version:
Result := VarToDateTime(Value1) = VarToDateTime(Value2);

Somehow the assignments in "CopyRecBuf" before the comparison "mix up" the precision of those values although the data was not changed by anyone - except maybe Delphi due to use of variants.

My suggestion for a workaround for this is to change the last lines in "VarEqual" from this:

Code: Select all

  else
    else Result := Value1 = Value2;
end;
to this:

Code: Select all

  else
  // treat dates as strings:
  if (VarType(Value1) = varDate) and (VarType(Value2) = varDate)
    then Result := VarToStr(Value1) = VarToStr(Value2)
    else Result := Value1 = Value2;
end;
Since this workaround at this level may have sideeffects, I hope the UniDac team can provide a better solution, which maybe located in e.g. "CopyRecBuf" itself and/or be dependent on the provider (Oracle).
I haven't tested/reproduced this issue with other databases types.

As always, such matters are urgent and I'd very much appreciate any fast assistance/code changes by the UniDac team, thanks so much in advance!

Regards,
Tobias

Challenger
Devart Team
Posts: 925
Joined: Thu 17 Nov 2005 10:53

Post by Challenger » Tue 09 Mar 2010 12:44

We will compare date values as double values and check that the difference is not greater than 1 millisecond (by default). This fix will be included in the next build of UniDAC.

tobias_cd
Posts: 56
Joined: Thu 18 Dec 2008 22:10

Post by tobias_cd » Fri 12 Mar 2010 06:24

Challenger wrote:We will compare date values as double values and check that the difference is not greater than 1 millisecond (by default). This fix will be included in the next build of UniDAC.
Thank you, I'll be looking forward to the next build.

Post Reply