TLobLocator.AsWideString D7 / D2009 not storing same value in DB

mobermaier

Member²
I have a 10.2.04 Oracle UTF DB, and I try to write some Unicode data to a clob.
Compiled with D2009 the clob content looks ok,
using D7 (and TMS Unicode Controls) the clob content is wrong.

==== snip ====
{$IFDEF VER150}
var slFile: TTNTStringList;
{$ENDIF}
{$IFDEF VER200}
var slFile: TStrings;
{$ENDIF}
sLobContent: WideString;

begin
. . .

{$IFDEF VER150}
slFile := TTNTStringList.Create;
{$ENDIF}
{$IFDEF VER200}
slFile := TStringList.Create;
{$ENDIF}

. . .

slFile.SaveToFile('D:\Temp\test_clob.txt');
sLobContent := slFile.Text;
FORABlob.AsWideString := sLobContent; // here everything as expected
sLobContent := FORABlob.AsWideString; // here not so much ?

==== snip ====

I'm probaly missing something obvious,
can anybody help?

Thanks,

Michael
 
Yes, it is.
Could it be Preferences ConvertUTF (that is currently set to cuNone)?
BytesPerCharacter is the only non default value (bcAutoDetect).

 
D7 Debugging / Evaluate sLobContent (WideString)

sLobContent := slFile.Text;

'/^/ version='5.0.02.01' ; shell_name='TEST76' /**/'#$D#$A'/^/insert into TC$_GROUPS

FORABlob.AsWideString := sLobContent;
sLobContent := FORABlob.AsWideString;

'/'#0'^'#0'/'#0' '#0'v'#0'e'#0'r'#0's'#0'i'#0'o'#0'n'#0'='#0'''#0'5'#0'.'#0'0'#0'.'#0'0'#0'2'#0'.'#0'0'#0'1'#0'''#0' '#0' '#0';'#0' '#0's'#0'h'#0'e'#0'l'#0'l'#0'_'#0'n'#0'a'#0'm'#0'e'#0'='#0'''#0'T'#0'E'#0'S'#0'T'#0'7'#0'6'#0'''#0' '#0' '#0'/'#0'*'#0'*'#0'/'#0#$D#$A#0'/'#0'^'#0'/'#0'i'#0'n'#0's'#0'e'#0'r'#0't'#0' '#0'i'#0'n'#0't'#0'o'#0' '#0'T'#0'C'#0'$'#0'_'#0'G'#0'R'#0'O'#0'U'#0'P'#0'S'#0'

that is also the way it shows in PL/SQl Developer. Looks like every character was converted to widechar twice.

At FORABlob.AsWideString := sLobContent;

the memory dump for sLobContent starts with

$2F $00 $5E $00 $2F $00 $20 $00 $76 $00

after sLobContent := FORABlob.AsWideString; it looks like this:

$2F $00 $00 $00 $5E $00 $00 $00 $2F $00 $00 $00 $20 $00 $00 $00 $76 $00 $00 $00

HTH,

Michael
 
This is fixed in 4.1.2 (Delphi 2009) but not in 4.1.1 D7.
The problem is in TLobLocator.Write()

D7 4.1.1

function TLOBLocator.Write(const Buffer; Count: Longint): Longint;
var CharCount: LongInt;
begin
if Count > 0 then
begin
if MonitorPresent then SendStartActivity('LOB.Write(' + IntToStr(Count) + ')');
try
Session.ClearInTransaction;
if IsUTF16 then CharCount := Count div 2 else CharCount := Count;
OCICall(OCILobWrite(Session.svchp, errhp, PLOB^, CharCount, FPosition + 1,
@Buffer, Count, OCI_ONE_PIECE, nil, nil, FCharSetID, FCharSetForm));
except
on E:Exception do
begin
if MonitorPresent then SendEndActivity('', E.Message);
raise;
end;
end;
if MonitorPresent then SendEndActivity('', '');
Inc(FPosition, Count);
if FBuffering then Modified := True;
end;
Result := Count;
end;

D2009 4.1.2

function TLOBLocator.Write(const Buffer; Count: Longint): Longint;
var CharCount: LongInt;
LCharSetID: ub2;
begin
if Count > 0 then
begin
if MonitorPresent then SendStartActivity('LOB.Write(' + IntToStr(Count) + ')');
try
Session.ClearInTransaction;
if IsUTF16 then
begin
CharCount := Count div 2;
LCharSetID := ocsUTF16;
end else begin
CharCount := Count;
LCharSetID := FCharSetID;
end;
OCICall(OCILobWrite(Session.svchp, errhp, PLOB^, CharCount, FPosition + 1,
@Buffer, Count, OCI_ONE_PIECE, nil, nil, LCharSetID, FCharSetForm));
except
on E:Exception do
begin
if MonitorPresent then SendEndActivity('', E.Message);
raise;
end;
end;
if MonitorPresent then SendEndActivity('', '');
Inc(FPosition, Count);
if FBuffering then Modified := True;
end;
Result := Count;
end;

Then it works correctly.

Michael
 
Back
Top