插入SQL语法错误delphi

时间:2015-01-17 18:29:27

标签: mysql sql database delphi

我想通过使用带参数的过程将记录插入数据库表(网站)。 SQL代码已经在mysql工作台中进行了测试,并且可以正常工作以插入新数据。但是,使用delphi,我在[插入整行代码]附近得到了一个“SQL语法”错误'。我想知道你们其中一个人是否可以告诉我哪里出错了。再次感谢。

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;

4 个答案:

答案 0 :(得分:5)

您的代码中存在很多问题。

A)不要夸大函数参数,如果你有很多变量,可以根据需要将它们组装成记录或类。

B)您的SQL代码易受SQL注入攻击。您可能从未听说过SQL注入,请谷歌或阅读此really good answer。针对SQL注入的解决方案是使用参数(请参阅我的代码示例)。另外一个好处是,您的SQL语句将是人类可读的,并且不易出错。

C)Open函数仅用于返回结果集的查询,例如SELECT语句。对于INSERTDELETEUPDATE语句,您需要使用ExecSQL函数。

清理代码:

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;

答案 1 :(得分:1)

请在查询行末尾用'+CID+';)');替换'+CID+');'); ; 位置错误。

答案 2 :(得分:1)

关于表格以及您尝试插入以修复代码的数据的信息不足。 T_G的答案可能是正确的,推荐参数化查询的答案很好但可能还有其他错误。我将就如何诊断您的确切问题向您提供一些建议。

首先,不要尝试通过Delphi调试SQL语句。使用专门为您的数据库设计的数据库管理工具,例如MySQL Workbench http://www.mysql.com/products/workbench/它将提供更详细的错误消息,可以帮助您找到导致错误的原因。

如果以编程方式创建SQL语句,如问题所示,将其分配给变量,以便在调试时捕获它,然后将其复制到您选择的数据库管理工具中进行调试。

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;

其次,不在SQL语句中包含列名是不好的做法。您应该像以下

一样使用SQL
INSERT INTO WEBSITE (COLUMN1, COLUMN2, COLUMN3) VALUES (1, 'ABC', 'XYZ')

或使用参数化查询

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

是的,这是更多的输入,但它可以防止假设成为错误的原因,这些数据会进入错误的列。

答案 3 :(得分:0)

也许你可以像这样使用它

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;

之后你就可以这样打电话了

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]);

我希望能帮到你。