1

I'm using the insert function in SQL code for Delphi. The program compiles and runs however, upon clicking the button which executes the insert function I receieve a message saying

Syntax error in FROM clause.

Upon breaking the program, it highlights the last line of code before end. If I were to remove that line of code and re-run the program, I am greeted with the same error and upon breaking it highlights the end; of the buttonclick procedure.

Please keep in mind that I am still a student and a novice to this language.

ADOQuery1.Close;
ADOQuery1.SQL.Add('insert into FPS_Tbl([MatchID],[kills],[standings],[GrenadeKill],[TimePlayed],[Username],[Comments],[Headshots],[Dates])');
ADOQuery1.SQL.Add('values("'+IntToStr(ids)+'","'+IntToStr(Kills)+'","'+standings+'","'+IntToStr(grenKills)+'","'+times+'","'+user+'","'+comment+'","'+IntToStr(HedShots)+'","'+DateToStr(Now)+'");');
ADOQuery1.ExecSQL;

end;
recalls;

recalls is a procedure for displaying the contents of the table in a Richedit.

Not really sure as to why I am getting this error as there is no 'From' clause in my SQL statements. To those who do assist Thank you very much.

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
S Govender
  • 19
  • 2
  • Be aware of SQL injection! – Alejandro Nov 17 '18 at 18:15
  • apologies i am not aware of what sql injection is but i have found the reason as to why it was not working...but my thanks for your input – S Govender Nov 17 '18 at 18:16
  • Have a look [here](http://bobby-tables.com/) for details about the serious security issue. Certainly unrelated to the question, but worth a look at. – Alejandro Nov 17 '18 at 18:20
  • In this case your FROM clause is actually the VALUES list. I think the values should be surrounded by single and not double quotes independently of the DBMS, so try that - and in this case you need to know how to escape the single quotes inside the Add method, or try to use double quotes there. – Dávid Laczkó Nov 17 '18 at 18:26
  • Why you are using `Add()` there? Since you don't clear the `Tstrings` there, it will always add an `INSERT` statement to another and so on. And please **use parameters** instead of concatenationa string. And why `recalls;` is after the `end;`? – Ilyes Nov 17 '18 at 18:26
  • i had realised that i needed to clear the sql beforehand so once i did the profram ran fine and the values were dded but thank you guys for the input. the recalls is after the end because that specific end is for a with statement. – S Govender Nov 17 '18 at 18:46
  • Do not concatenate user input into a SQL string like that use a PreparedStatement. https://wiki.freepascal.org/Working_With_TSQLQuery –  Sep 25 '19 at 20:00

2 Answers2

0

try to insert simple space to separate (last word in first add) and (first word in second add), may like so:

ADOQuery1.SQL.Add(' values("'+IntToStr(ids)+'","'+IntToStr(Kills)+'","'+standings+'","'+IntToStr(grenKills)+'","'+times+'","'+user+'","'+comment+'","'+IntToStr(HedShots)+'","'+DateToStr(Now)+'");');
Bashar Issa
  • 101
  • 2
  • 4
0

When invoking a multi-line SQL query, you need to Clear() the SQL before you then Add() lines to it, otherwise you will be adding on to a previous query:

ADOQuery1.Close;
ADOQuery1.SQL.Clear; // <-- ADD THIS!!!
ADOQuery1.SQL.Add('insert into FPS_Tbl([MatchID],[kills],[standings],[GrenadeKill],[TimePlayed],[Username],[Comments],[Headshots],[Dates])');
ADOQuery1.SQL.Add('values("' + IntToStr(ids) + '","' + IntToStr(Kills) + '","' + standings + '","' + IntToStr(grenKills) + '","' + times + '","' + user + '","' + comment + '","' + IntToStr(HedShots) + '","' + DateToStr(Now) + '");');
ADOQuery1.ExecSQL;

Otherwise, use the Text property instead:

ADOQuery1.Close;
ADOQuery1.SQL.Text := 'insert into FPS_Tbl([MatchID],[kills],[standings],[GrenadeKill],[TimePlayed],[Username],[Comments],[Headshots],[Dates]) values("' + IntToStr(ids) + '","' + IntToStr(Kills) + '","' + standings + '","' + IntToStr(grenKills) + '","' + times + '","' + user + '","' + comment + '","' + IntToStr(HedShots) + '","' + DateToStr(Now) + '");');
ADOQuery1.ExecSQL;

That said, your code is subject to an SQL Injection attack. You can avoid that by using AnsiQuotedStr() for all string inputs:

ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('insert into FPS_Tbl([MatchID],[kills],[standings],[GrenadeKill],[TimePlayed],[Username],[Comments],[Headshots],[Dates])');
ADOQuery1.SQL.Add('values("' + IntToStr(ids) + '","' + IntToStr(Kills) + '",' + AnsiQuotedStr(standings,'"') + ',"' + IntToStr(grenKills) + '",' + AnsiQuotedStr(times,'"') + ',' + AnsiQuotedStr(user,'"') + ',' + AnsiQuotedStr(comment,'"') + ',"' + IntToStr(HedShots) + '","' + DateToStr(Now) + '");');
ADOQuery1.ExecSQL;

Or better, by using a parameterized query instead:

ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('insert into FPS_Tbl([MatchID],[kills],[standings],[GrenadeKill],[TimePlayed],[Username],[Comments],[Headshots],[Dates])');
ADOQuery1.SQL.Add('values(:PId,:PKills,:PStandings,:PGrenKills,:PTimes,:PUser,:PComment,:PHeadShots,:PDate);');
ADOQuery1.Parameters.ParamByName('PId').Value := IntToStr(ids);
ADOQuery1.Parameters.ParamByName('PKills').Value := IntToStr(Kills);
ADOQuery1.Parameters.ParamByName('PStandings').Value := standings;
ADOQuery1.Parameters.ParamByName('PGrenKills').Value := IntToStr(grenKills);
ADOQuery1.Parameters.ParamByName('PTimes').Value := times;
ADOQuery1.Parameters.ParamByName('PUser').Value := user;
ADOQuery1.Parameters.ParamByName('PComment').Value := comment;
ADOQuery1.Parameters.ParamByName('PHeadShots').Value := IntToStr(HedShots);
ADOQuery1.Parameters.ParamByName('PDate').Value := DateToStr(Now);
ADOQuery1.ExecSQL;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770