Toby Fox
Toby Fox

Reputation: 105

Insert into SQL syntax error delphi

I am wanting to insert a record into a database table (website) by using a procedure with parameters. The SQL code has been tested in mysql workbench and works properly to insert new data. However, with delphi i am getting an 'SQL Syntax error near [insert whole line of code here]'. I was wondering if one of you could tell me where I'm going wrong. Thanks again.

procedure TNewWebsite.InsertData(WID, D, T, Wh, Dr, Od, Rd, Rc, Pm, OStat,  Cstat, Rstat, N, U1, P1, P2, PStat, CID : string);
  begin
   WebsiteTable.WebsiteQuery.SQL.Add('INSERT INTO website VALUES ( '+WID+', '''+D+''', '''+T+''', '''+Wh+''', '''+D+''', '''+Od+''', '''+Rd+''', '+Rc+', '''+Pm+''', '+Ostat+', '+Cstat+', '''+Rstat+''', '''+N+''', '''+U1+''', '''+P1+''', '''+P2+''', '+Pstat+', '+CID+';)');
   WebsiteTable.WebsiteQuery.Open;
 end;

Upvotes: 1

Views: 3340

Answers (4)

whosrdaddy
whosrdaddy

Reputation: 11860

You have quite a few problems in your code.

A) Don't exaggerate with function parameters, if you have a lot of variables, assemble them in a record or class depending on your needs.

B) Your SQL code is vulnerable for SQL injection. You probably never heard of SQL injection, please Google it or read this really good answer. The solution against SQL injection is to use parameters (see my code example). An added bonus is that your SQL statement will be human readable, and less error prone.

C) The Open function is only used in conjunction for queries that return a result set, like SELECT statements. For INSERT, DELETE and UPDATE statements, you need to use the ExecSQL function.

Sanitized code:

interface

type 
  TMyDataRecord = record
   WID : String;
   D : String; 
   T : String;
   Wh : String; 
   Dr : String; 
   Od : String; 
   Rd : String; 
   Rc : String; 
   Pm : String; 
   OStat : String;
   Cstat : String; 
   Rstat : String; 
   N : String; 
   U1 : String; 
   P1 : String; 
   P2 : String;
   PStat : String; 
   CID : String;
  end;
...
implementation

procedure TNewWebsite.InsertData(Data : TMyDataRecord);

var 
  SQL : String;

begin
 SQL := 'INSERT INTO website VALUES (:WID, :D1, :T, :Wh, :D2, :Od, :Rd, :Rc',+   
        'Pm, :Ostat, :Cstat, :Rstat, :N, :U1, :P1, :P2, :Pstat, :CID)'; 
 WebsiteTable.WebsiteQuery.ParamCheck := True;
 WebsiteTable.WebsiteQuery.SQL.Text := SQL;
 WebsiteTable.WebsiteQuery.Params.ParamByName('WID').AsString := Data.WID;
 WebsiteTable.WebsiteQuery.Params.ParamByName('D1').AsString := Data.D;
 ...// rest of parameters
 WebsiteTable.WebsiteQuery.Params.ParamByName('CID').AsString := Data.CID;
 WebsiteTable.WebsiteQuery.ExecSQL;
end;

Upvotes: 5

crefird
crefird

Reputation: 1610

There is insufficient information about the table and the data you are trying to insert to fix your code. T_G's answer may be correct and the answers recommending parameterized queries are good but there may be other errors. I will offer you some suggestions on how to diagnose your exact problem.

First, do not try to debug your SQL statements through Delphi. Use a database admin tool specifically designed for your database, such as MySQL Workbench http://www.mysql.com/products/workbench/ It will give much more detailed error messages which can help you find what is causing the error.

If you create your SQL statement programatically, as shown in your question, assign it to a variable so you can capture it while debugging and then copy it to the database admin tool of you choice to debug it.

var
  SQL : string;
begin
  SQL := 'INSERT INTO website VALUES ( '+WID+', '''+D+''', '''+T+''', '''+Wh+''', '''+D+''', '''+Od+''', '''+Rd+''', '+Rc+', '''+Pm+''', '+Ostat+', '+Cstat+', '''+Rstat+''', '''+N+''', '''+U1+''', '''+P1+''', '''+P2+''', '+Pstat+', '+CID+';)');
  WebsiteTable.WebsiteQuery.SQL.Text := SQL;

Second, it is bad practice to not include the column names in the SQL statement. You should make your SQL like the following

INSERT INTO WEBSITE (COLUMN1, COLUMN2, COLUMN3) VALUES (1, 'ABC', 'XYZ')

or using a parameterized query

INSERT INTO WEBSITE (COLUMN1, COLUMN2, COLUMN3) VALUES (:C1, :C2, :C3)

Yes, it is more typing, but it prevents assumptions from being the cause of errors, such data going into the wrong columns.

Upvotes: 1

MSB
MSB

Reputation: 181

perhaps you can use it like this

function FormatQuery(Query: String; Args: array of const): string;
var S:string; FmtSet: TFormatSettings;
begin
  Result:= Query;
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FmtSet);
  FmtSet.DecimalSeparator := '.';
  FmtStr(S, Query, Args, FmtSet);
  Result:= S;
end;

procedure TNewWebsite.InsertData(Query: String; Args: array of const);
var MyQuery: string;
begin
  MyQuery:= FormatQuery(Query, Args);
  WebsiteTable.WebsiteQuery.SQL.Clear;
  WebsiteTable.WebsiteQuery.SQL.Add(MyQuery);
  WebsiteTable.WebsiteQuery.Open;
end;

After that you can Call it like this

var MyQuery: string;
MyQuery:= 'INSERT INTO website VALUES (%s,"%s","%s","%s","%s","%s","%s",%s,"%s",%s,%s,"%s","%s","%s","%s","%s",%s,%s;)';
InsertData(MyQuery,[WID,D,T,Wh,D,Od,Rd,Rc,Pm,Ostat,Cstat,Rstat,N,U1,P1,P2,Pstat,CID]);

I hope that can Help u.

Upvotes: 0

user2941651
user2941651

Reputation:

Please replace '+CID+';)'); with '+CID+');'); in the end of your query line. The ; was in wrong place.

Upvotes: 1

Related Questions