-7

enter image description here

I've created 'qry' as a private variable. I've been trying to fix this error for sometime now. The code that I'm using is this:

procedure TfrmMaintenance.btnInsertNutsManyClick(Sender: TObject);
begin
  with dmNutsData do

Begin

qry.SQL.Clear;

qry.SQL.Clear;

qry.SQL.Add('INSERT INTO CompnayList (CompanyID, CompanyName, CompanyNumber, CompanyEmail, ') ;

qry.SQL.Add('Values (edtCompID.Text, edtCompName.Text, edtCompNumb.Text, edtCompanyEmail.Text') ;

qry.ExecSQL;

  End;
end;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Jamie
  • 1
  • 2
  • 2
    I suggest you show your complete code, including the part where you define the qry variable, and where you create the qry object. Have you run the code in the debugger to find the line on which the exception occurs? – frogb Jul 26 '18 at 08:32
  • Here's an old stack overflow question on how to debug access violations in Delphi programs. https://stackoverflow.com/questions/6214458/debugging-access-violation-errors – Sam M Jul 26 '18 at 08:55
  • Btw, do you really mean "Com**pn**ayList" in your INSERT statement? – MartynA Jul 26 '18 at 08:57
  • Where exactly do you create qry as a private variable? I don't see that anywhere in your code. If it's a private variable in dmNutsData, then you can't be accessing it at all from your form `TfrmMaintenance`, and if it's a private variable of your form or that form's unit then the `with` isn't needed. Post an actual [mcve] that demonstrates the actual problem. The code you've posted is incomplete. (And somewhat silly - what do you think two successive calls to `qry.SQL.Clear` are going to do? Double-check to make sure the SQL is actually clear?) – Ken White Jul 26 '18 at 17:51

2 Answers2

5

Typically this means one of the following:

  • dmNutsData is nil
  • dmNutsData.qry is nil
  • dmNutsData.qry.SQL is nil
  • qry is not a member of dmNutsData, but is declared elsewhere, and is nil
  • etc.

Use your debugger to find out which it is. Step through the code and inspect the values to see which one is nil.

I would strongly recommend that you don't use with in this way. Doing so makes it likely that you encounter unexpected scoping clashes and it also makes your program harder to debug. If you want to avoid writing dmNutsData.qry repeatedly, declare a local variable and assign ``dmNutsData.qry` to it.

Finally, your program, like so many that came before it, is susceptible to SQL injection. Don't fall into that trap. Use parameters.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
2

In addition to the points mentioned in @DavidHeffernan's answer, there are at least four syntax errors in your INSERT statement. Any of these could give rise to the AV you're reported, depending on the type of query component you are using, which you have not stated, or at least cause the INSERT to fail.

In your qry.SQL.Add('INSERT INTO CompnayList (CompanyID, CompanyName, CompanyNumber, CompanyEmail, ') ;

  • firstly, presumably CompnayList should read CompanyList. I mentioned this in a comment to which you have not replied.

  • secondly, there should be no comma in the SQL statement after `CompanyEmail'

  • thirdly there should be a closong parenthesis after `CompanyEmail'

So the corrected version should read

qry.SQL.Add('INSERT INTO Comp**an**yList (CompanyID, CompanyName, CompanyNumber, CompanyEmail)') ;

Next, the SQL in your

qry.SQL.Add('Values (edtCompID.Text, edtCompName.Text, edtCompNumb.Text, edtCompanyEmail.Text') ;

is again missing a closing parenthesis and if you are intending to access the texts of edtCompID, you are doing it incorrectly and the line should read

qry.SQL.Add('Values (' + edtCompID.Text + ', ' + edtCompName.Text + ', ' +  edtCompNumb.Text + ', ' + edtCompanyEmail.Text + ')') ;

As David has said, it is better if you parameterize your SQL statements, but not just because of the risk of SQL-Injection.

Btw, you are making things more error-prone than they need be by using calls to qry.SQL.Add() to build your SQL statement. This is because the outer parentheses make it more difficult to spot error in the text you are trying to add, especially when the text is supposed to contain parentheses of its own. It is better to use a string variable as a temporary "holder" to receive the SQL as you build it up and then, once it's complete, assign it to the qry's Sql.Text property like this

var
  S : String;
begin
  [...]
  S := 'select * from mytable';
  qry.SQL.Text := S;
  qry.Open;
  [...]
end;
MartynA
  • 30,454
  • 4
  • 32
  • 73
  • Sorry for relying so late, been very busy with preparing for exams. Thank you for the help I really appreciate it and I'll take a look at it again. – Jamie Jul 30 '18 at 10:21