My Solution:
1. step: make the TZAbstractRODataset.Options property to published or public (originally this is protected)
2. step: modify the ZDatasetUtils.CompareFieldsFromResultSet function:
uses ...., Windows, .....
function StrToOem(const AnsiStr : String) : String;
begin
SetLength(Result, Length(AnsiStr));
if Length(Result) > 0 then CharToOem(PChar(AnsiStr), PChar(Result));
end;
function OemToStr(const OemStr : String) : String;
begin
SetLength(Result, Length(OemStr));
if Length(Result) > 0 then OemToChar(PChar(OemStr), PChar(Result));
end;
function CompareFieldsFromResultSet(FieldRefs: TObjectDynArray;
KeyValues: TZVariantDynArray; ResultSet: IZResultSet; PartialKey: Boolean;
CaseInsensitive: Boolean): Boolean;
var
I: Integer;
ColumnIndex: Integer;
Value1, Value2: AnsiString;
CurrentType : TZSQLType;
OEMConvert : Boolean;
begin
Result := True;
if Length(KeyValues) > 0 then OEMConvert := doOemTranslate in TZAbstractRODataset(TField(FieldRefs[0]).DataSet).Options;
for I := 0 to High(KeyValues) do
begin
ColumnIndex := TField(FieldRefs).FieldNo;
if KeyValues.VType = vtNull then
begin
Result := ResultSet.IsNull(ColumnIndex);
if not Result then Break;
Continue;
end;
CurrentType := ResultSet.GetMetadata.GetColumnType(ColumnIndex);
if PartialKey then
begin
if CurrentType = stUnicodeString then
begin
Value1 := KeyValues.VUnicodeString;
Value2 := ResultSet.GetUnicodeString(ColumnIndex);
end
else
begin
Value1 := KeyValues.VString;
Value2 := ResultSet.GetString(ColumnIndex);
if OEMConvert then Value2 := OemToStr(Value2);
end;
if CaseInsensitive then
Value2 := AnsiUpperCase(Value2);
Result := AnsiStrLComp(PChar(Value2), PChar(Value1), Length(Value1)) = 0;
end
else
begin
case CurrentType of
stBoolean:
begin
Result := KeyValues.VBoolean =
ResultSet.GetBoolean(ColumnIndex);
end;
stByte, stShort, stInteger, stLong:
begin
Result := KeyValues.VInteger =
ResultSet.GetLong(ColumnIndex);
end;
stFloat, stDouble, stBigDecimal:
begin
Result := Abs(KeyValues.VFloat -
ResultSet.GetBigDecimal(ColumnIndex)) < FLOAT_COMPARE_PRECISION;
end;
stDate, stTime, stTimestamp:
begin
Result := KeyValues.VDateTime =
ResultSet.GetTimestamp(ColumnIndex);
end;
stUnicodeString:
begin
if CaseInsensitive then
begin
{$IFNDEF VER130BELOW}
Result := KeyValues.VUnicodeString =
WideUpperCase(ResultSet.GetUnicodeString(ColumnIndex));
{$ELSE}
Result := AnsiString(KeyValues.VUnicodeString) =
AnsiUpperCase(ResultSet.GetUnicodeString(ColumnIndex));
{$ENDIF}
end
else
begin
Result := KeyValues[I].VUnicodeString =
ResultSet.GetUnicodeString(ColumnIndex);
end;
end;
else
Value1 := KeyValues[I].VString;
Value2 := ResultSet.GetString(ColumnIndex);
if OEMConvert then Value2 := OemToStr(Value2);
if CaseInsensitive then
begin
Result := Value1 = AnsiUpperCase(Value2);
end
else
begin
Result := Value1 = Value2;
end;
end;
end;
Result := Result and not ResultSet.WasNull;
if not Result then
Break;
end;
end;
OEMConvert doesn't work on Locate
Moderators: gto, cipto_kh, EgonHugeist, mdaems