Reputation: 105
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
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
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
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
Reputation:
Please replace '+CID+';)');
with '+CID+');');
in the end of your query line. The ;
was in wrong place.
Upvotes: 1