Print Thread
TLobLocator.AsWideString D7 / D2009 not storing same value in DB
#38013 05/07/10 12:48 PM
Joined: Apr 2006
Posts: 10
M
Member
OP Offline
Member
M
Joined: Apr 2006
Posts: 10
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

Re: TLobLocator.AsWideString D7 / D2009 not storing same value in DB
mobermaier #38018 05/10/10 10:03 AM
Joined: Aug 1999
Posts: 22,217
Member
Offline
Member
Joined: Aug 1999
Posts: 22,217
Can you check if TOracleSession.BytesPerCharacter is set to bcAutoDetect in your Delphi 7 project?


Marco Kalter
Allround Automations
Re: TLobLocator.AsWideString D7 / D2009 not storing same value in DB
mobermaier #38022 05/10/10 12:48 PM
Joined: Apr 2006
Posts: 10
M
Member
OP Offline
Member
M
Joined: Apr 2006
Posts: 10
Yes, it is.
Could it be Preferences ConvertUTF (that is currently set to cuNone)?
BytesPerCharacter is the only non default value (bcAutoDetect).


Re: TLobLocator.AsWideString D7 / D2009 not storing same value in DB
mobermaier #38024 05/11/10 10:31 AM
Joined: Aug 1999
Posts: 22,217
Member
Offline
Member
Joined: Aug 1999
Posts: 22,217
I don't think so.

Can you let me know what string values you see in D7 and D2009?


Marco Kalter
Allround Automations
Re: TLobLocator.AsWideString D7 / D2009 not storing same value in DB
Marco Kalter #38026 05/11/10 02:34 PM
Joined: Apr 2006
Posts: 10
M
Member
OP Offline
Member
M
Joined: Apr 2006
Posts: 10
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

Re: TLobLocator.AsWideString D7 / D2009 not storing same value in DB
mobermaier #38028 05/11/10 05:15 PM
Joined: Apr 2006
Posts: 10
M
Member
OP Offline
Member
M
Joined: Apr 2006
Posts: 10
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

Re: TLobLocator.AsWideString D7 / D2009 not storing same value in DB
mobermaier #38035 05/12/10 10:30 AM
Joined: Aug 1999
Posts: 22,217
Member
Offline
Member
Joined: Aug 1999
Posts: 22,217
We'll check it out.


Marco Kalter
Allround Automations

Moderated by  support 

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.4
(Release build 20200307)
Responsive Width:

PHP: 7.1.33 Page Time: 0.052s Queries: 14 (0.025s) Memory: 2.5316 MB (Peak: 3.0437 MB) Data Comp: Off Server Time: 2024-05-13 21:37:44 UTC
Valid HTML 5 and Valid CSS