You are not logged in.
Pages: 1
I just test Orcale DB access. I found AV when db free. I use XE/Ora 11g. Here is a simple code.
var fProps: TSQLDBOracleConnectionProperties;
_sql: RAWUTF8;
Rows: ISQLDBRows;
begin
fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage(fOraTNS,
fOraUser, fOraPass,0);
fProps.ForcedSchemaName:= fOraUser;
try
_sql:='select * from dual';
Rows:= fProps.Execute(_sql,[],nil) ;
With Rows Do
While Step Do
Begin
Memo1.Lines.Add(ColumnString(0));
End;
Rows:=nil;
finally
fProps.Free;
end;
After fProps.Free , AV of OCI in TSQLDBOracleStatement.FreeHandles was fired.
folowing code also have AV problem
fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage(fOraTNS,
fOraUser, fOraPass,0);
fProps.ForcedSchemaName:= fOraUser;
try
_sql:='select * from dual where rownum=?';
With fProps.Execute(_sql,[1],nil) Do
While Step Do
Begin
Memo1.Lines.Add(ColumnString(0));
End;
finally
fProps.Free;
end;
But the strange thing is Execute() function, the following code works no problem.
try
_sql:='select * from dual where rownum=?';
Rows:= fProps.Execute(_sql,[1],nil) ;
With Rows Do
While Step Do
Begin
Memo1.Lines.Add(ColumnString(0));
End;
Rows:=nil;
finally
fProps.Free;
end;
the param there or empty is differ.
Is there something I missed or a bug?
Last edited by richard6688 (2013-11-26 00:38:17)
Offline
I do not have Oracle here since end of this week to reproduce it.
Please debug your code, checking how interfaces memory are handled.
Use the CPU view to check the context - perhaps your Rows := nil is not enough in some cases.
Or at least use F7 to step by step and find WHERE the AV occurs, in which stack trace.
Your statement is certainly released after the fProps is freed.
Offline
Thanks for your replay.
I do debug the code, I think the problem is cache used. AV code found at
if fStatement<>nil then begin
if fUseServerSideStatementCache then
OCI.Check(OCI.StmtRelease(fStatement,fError,nil,0,OCI_DEFAULT),fError) else
OCI.HandleFree(fStatement,OCI_HTYPE_STMT);
usecache property seems readonly, so cannot change
maybe , I will wait you to reproduce the error.
Last edited by richard6688 (2013-11-26 07:36:27)
Offline
after digging code, this error is not related to mORMot but delphi XE compiler. following is delphi code generated:
smain.pas.47: Rows:= fProps.Execute(_sql,[],nil);
0056BBA6 6AFF push $ff
0056BBA8 6A00 push $00
0056BBAA 8D45E4 lea eax,[ebp-$1c]
0056BBAD 50 push eax
0056BBAE 8D4DE4 lea ecx,[ebp-$1c]
0056BBB1 8B55F4 mov edx,[ebp-$0c]
0056BBB4 8B45F8 mov eax,[ebp-$08]
0056BBB7 E89C96FEFF call TSQLDBConnectionProperties.Execute
0056BBBC 8B55E4 mov edx,[ebp-$1c]
0056BBBF 8D45F0 lea eax,[ebp-$10]
0056BBC2 E861EFE9FF call @IntfCopy
0056BBC7 EB24 jmp $0056bbed
--------------------------------------------------------
smain.pas.47: Rows:= fProps.Execute(_sql,[1],nil);
0056BBA3 6A00 push $00
0056BBA5 6A00 push $00
0056BBA7 8D45F0 lea eax,[ebp-$10]
0056BBAA 50 push eax
0056BBAB C745E001000000 mov [ebp-$20],$00000001
0056BBB2 C645E400 mov byte ptr [ebp-$1c],$00
0056BBB6 8D4DE0 lea ecx,[ebp-$20]
0056BBB9 8B55F4 mov edx,[ebp-$0c]
0056BBBC 8B45F8 mov eax,[ebp-$08]
0056BBBF E89496FEFF call TSQLDBConnectionProperties.Execute
0056BBC4 EB24 jmp $0056bbea
call fProps.Execute with no parameter in open array will make ISQLDBRows interface refcount increase 1, which will result a AV.
anyone has experient about this? how to resolve?
any feedback is welcome?
Offline
This is just some weird behavior of the Delphi compiler automatic reference counting of interfaces.
In fact, Delphi creates an hidden local ISQLDBRows interface variable, which is copied to Rows, and is still there after fProps.Free...
procedure TForm1.btn1Click(Sender: TObject);
var Rows: ISQLDBRows;
LocalVariable: ISQLDBRows; // code generated by the compiler
begin
fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage('OCTB',
'MIS', 'mis',0);
LocalVariable := fProps.Execute('select * from dual',[],nil);
Rows := LocalVariable; // code generated by the compiler
while Rows.Step do
mmo1.Lines.Add(Rows.ColumnUTF8(0));
Rows := nil; // but LocalVariable is still set!
fProps.Free; // release the statement
LocalVariable := nil; // code generated by the compiler -> here AV since the statement is already released!!!
end;
There is no known workaround, unless we change the fProps.Execute() from one function into a procedure with an var/out parameter....
No so convenient.
Usual code is the following:
procedure TForm1.FormCreate(Sender: TObject);
begin
fProps:= TSQLDBOracleConnectionProperties.CreateWithCodePage('tnsname',
'username', 'password',0);
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
with fProps.Execute('select * from dual',[],nil) do
while Step do
mmo1.Lines.Add(ColumnString(0));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
fProps.Free;
end;
There is no problem.
You should always use a share fProps instance in your application.
Individual connections will then be handled by the SynDB* classes.
The same fProps instance can be used between all threads, without any problem.
Offline
Thank you for your kind reply.
To konw such weird behavior, we can avoid similar situation. for mORMot, we have many solution here. using TSQLDBStatement, or do that as the code you show.
Anyway, Thank you again.
Offline
Pages: 1