Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 10 total
Thread EDBQuery Close raises Access Violation Exception
Wed, May 29 2013 11:39 AMPermanent Link

Norman Clark

Clark-Tech Inc.

I'm stumped.  I think I need some fresh eyes on a simple problem.  Using ElevateDB Version 2.12 build 2 in a client/server application.

On a form I have dropped an EDBQuery with the name EDBQueryNames.
...
type
 TfrmTest = class(TForm)
   EDBQueryNames: TEDBQuery;
...

In the form's OnCreate event, I set the EDBQueryNames.sessionname and databasename properties.  In the form's OnShow event I use a simple query as
....
With EDBQueryNames do
   begin
     Close;
     ReadOnly := true;
     SQL.Clear;
     SQL.Add('SELECT * FROM User WHERE CommissionRate > 0.0');
     Open;
     First;
     while Not EOF do
       begin
         name := FieldByName('UserName').AsString;
         iLeft := ListBoxLeft.Items.Count;
         namefound := false;
         for i := 1 to iLeft do
           if name = ListBoxLeft.Items[i-1] then
             namefound := true;
         if NOT namefound then
           ListBoxLeft.Items.Add(name);
         Next;
       end;
     Close; // release the query
   end;
 iLeft := ListBoxLeft.Items.Count;
... etc.

The above works just fine and I have the resulting list of Usernames in the listbox and the form responds as expected.

NOW in a subsequent OnClick event of a button on this form I attempt to "re-use" the EDBQuery as ....
...
     name := ListBoxLeft.Items[iLeftSelected];
     EDBQueryNames.Close;  <================== Creates an Exception 'Access violation '
     EDBQueryNames.ReadOnly := true;
     EDBQueryNames.SQL.Clear;
     EDBQueryNames.SQL.Add('SELECT * FROM User WHERE UserName=' +
       edbcomps.Engine.QuotedSQLStr(name));
     EDBQueryNames.Open;
     if EDBQueryNames.RecordCount > 0 then
       begin
... etc.

the Close statement raises an Access violation.  
In fact, any attempt to use the Query produces the exception as even if I remove the Close statement and just attempt to change the ReadOnly property I receive the same exception.

I'm certain that I've "re-used" queries like this before without any problem.
Am I missing something here?
Wed, May 29 2013 1:45 PMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Norman


There are  only two reasons why you should get that.

The most likely is that somewhere tucked away in a hidden corner of your code is a EDBQueryNames.Free.

The other reason (and damned improbable in your case since you close the query) is that the AV doesn't refer to the query but a linked control and closing the query causes some action on it.

Quick test - add the following

ShowMessage(IntToStr(EDBQueryNames.RecordCount));

just in front of the close statement.

    name := ListBoxLeft.Items[iLeftSelected];
ShowMessage(IntToStr(EDBQueryNames.RecordCount));
     EDBQueryNames.Close;  <================== Creates an Exception 'Access violation

if it AVs at that point you've freed the query somewhere. If not its a linked control problem.

Roy Lambert [Team Elevate]
Wed, May 29 2013 2:35 PMPermanent Link

Norman Clark

Clark-Tech Inc.

Roy Lambert wrote:

Norman


There are  only two reasons why you should get that.

The most likely is that somewhere tucked away in a hidden corner of your code is a EDBQueryNames.Free.

The other reason (and damned improbable in your case since you close the query) is that the AV doesn't refer to the query but a linked control and closing the query causes some action on it.

Quick test - add the following

ShowMessage(IntToStr(EDBQueryNames.RecordCount));

just in front of the close statement.

    name := ListBoxLeft.Items[iLeftSelected];
ShowMessage(IntToStr(EDBQueryNames.RecordCount));
     EDBQueryNames.Close;  <================== Creates an Exception 'Access violation

if it AVs at that point you've freed the query somewhere. If not its a linked control problem.

Roy Lambert [Team Elevate]

---------------------------------------------------------------------------------------------------------
Roy:  Thanks for the reply but the Query has not been "freed" in any code on this form.  It has been closed in the OnShow form event but it has not been freed.  There are no linked controls on this form.  BTW, a Showmessage as you suggested also AV's so it appears that any reference to the query after it was closed in the OnShow event will throw the exception.  It does act like the query has been "freed" but there is nothing on the form that could (obviously) do that.  I'll post the form to the binaries so you can see the whole thing.  Boy, this has me stumped.  
Wed, May 29 2013 3:27 PMPermanent Link

Barry

>I'm stumped.  I think I need some fresh eyes on a simple problem.  Using ElevateDB Version 2.12 build 2 in a client/server application.<

Norman,

Get rid of the With statement.
Hint: "A rose by any other *name* would be as sweet".

Barry
Thu, May 30 2013 3:52 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Norman


Unfortunately I can't see anything in that form. I would have expected ShowMessage(IntToStr(EDBQueryNames.RecordCount)); to throw an error because the query is closed but not because its not there.

If its not being freed here then it must be being freed elsewhere. The "fun" part is tracking it down. All I can suggest is to insert more showmessages (say ShowMessage(EDBQueryNames.Name); so that it will only throw an error if the query is freed) at the start / end of every function & procedure, isloate the area and then sprinkle more in to identify the line - probably easier than walking through the code in the debugger.

Roy Lambert [Team Elevate]
Thu, May 30 2013 10:20 AMPermanent Link

Norman Clark

Clark-Tech Inc.

Barry wrote:

>I'm stumped.  I think I need some fresh eyes on a simple problem.  Using ElevateDB Version 2.12 build 2 in a client/server application.<

Norman,

Get rid of the With statement.
Hint: "A rose by any other *name* would be as sweet".

Barry
---------------------------------------------------------------------------------------
Barry: Thanks for the fresh set of eyes.  You were right.  I am joining the group to discourage the use of the "do with" statement.  See http://hallvards.blogspot.ca/2004/08/with-statement-considered-harmful.html

Thanks again all,
... Norm
Thu, May 30 2013 10:21 AMPermanent Link

Norman Clark

Clark-Tech Inc.

Roy Lambert wrote:

Norman


Unfortunately I can't see anything in that form. I would have expected ShowMessage(IntToStr(EDBQueryNames.RecordCount)); to throw an error because the query is closed but not because its not there.

If its not being freed here then it must be being freed elsewhere. The "fun" part is tracking it down. All I can suggest is to insert more showmessages (say ShowMessage(EDBQueryNames.Name); so that it will only throw an error if the query is freed) at the start / end of every function & procedure, isloate the area and then sprinkle more in to identify the line - probably easier than walking through the code in the debugger.

Roy Lambert [Team Elevate]
----------------------------------------
Roy:  See Barry's hint for the root of the cause.  It is a case of "coders blinders" not any issue with ElevateDB.
Thanks again for your help.
... Norm
Thu, May 30 2013 11:28 AMPermanent Link

Barry

>Barry: Thanks for the fresh set of eyes.  You were right.  I am joining the group to discourage the use of the "do with" statement.  See http://hallvards.blogspot.ca/2004/08/with-statement-considered-harmful.html<

Norm,
I use the With statements all the time, and I hope your group is not going to throw me in jail for using it. Smile

The problem is often the naming conventions. I never ever use a variable/property/method name that can be mistaken for a keyword. I am also in the habit of prefixing local variables with "_" and in "_FirstName" and parameters with "a" as in "aFirstName" so I know where the variable is defined.

Barry

With all do respects to Willie Shakespeare, I suppose I should have said:
"A variable with any other name, would have compiled more sweet"
--Ah yes, there is poet blood in me after all
Thu, May 30 2013 12:15 PMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Norman


Even with the clue it took me ages to spot the problem.

I've actually done something similar, or my other favourite is to create a component dynamically and forget to give it a name.

Roy Lambert
Thu, May 30 2013 12:15 PMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Barry

>I use the With statements all the time, and I hope your group is not going to throw me in jail for using it. Smile

I use them occasionally for simple assignment blocks just to save typing but more generally I use autocomplete.

>The problem is often the naming conventions. I never ever use a variable/property/method name that can be mistaken for a keyword. I am also in the habit of prefixing local variables with "_" and in "_FirstName" and parameters with "a" as in "aFirstName" so I know where the variable is defined.

I try and avoid reserved words like the plague. For that reason ALL my column names start with _

Roy
Image