简体   繁体   English

插入SQL语法错误delphi

[英]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. SQL代码已在mysql工作台中经过测试,可以正确插入新数据。 However, with delphi i am getting an 'SQL Syntax error near [insert whole line of code here]'. 但是,使用delphi时,我在[在此处插入整行代码]附近收到“ SQL语法错误”。 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;

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. A)不要夸大函数参数,如果您有很多变量,请根据需要将它们组合到记录或类中。

B) Your SQL code is vulnerable for SQL injection. B)您的SQL代码容易受到SQL注入的攻击。 You probably never heard of SQL injection, please Google it or read this really good answer . 您可能从未听说过SQL注入,请使用Google或阅读这个非常好的答案 The solution against SQL injection is to use parameters (see my code example). 防止SQL注入的解决方案是使用参数(请参阅我的代码示例)。 An added bonus is that your SQL statement will be human readable, and less error prone. 另外一个好处是,您的SQL语句易于阅读,并且不易出错。

C) The Open function is only used in conjunction for queries that return a result set, like SELECT statements. C) Open函数仅与返回结果集的查询一起使用,例如SELECT语句。 For INSERT , DELETE and UPDATE statements, you need to use the ExecSQL function. 对于INSERTDELETEUPDATE语句,您需要使用ExecSQL函数。

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;

Please replace '+CID+';)'); 请替换为'+CID+';)'); with '+CID+');'); '+CID+');'); in the end of your query line. 在查询行的末尾。 The ; ; was in wrong place. 在错误的地方。

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. T_G的答案可能是正确的,推荐参数化查询的答案也不错,但是可能还有其他错误。 I will offer you some suggestions on how to diagnose your exact problem. 我将为您提供一些有关如何诊断确切问题的建议。

First, do not try to debug your SQL statements through Delphi. 首先,不要尝试通过Delphi调试SQL语句。 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. 使用专门为您的数据库设计的数据库管理工具,例如MySQL Workbench http://www.mysql.com/products/workbench/ 。它将提供更详细的错误消息,可以帮助您查找导致错误的原因。

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. 如果按照问题所示以编程方式创建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;

Second, it is bad practice to not include the column names in the SQL statement. 其次,不建议在SQL语句中不包括列名。 You should make your SQL like the following 您应该使您的SQL如下所示

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. 是的,它的类型更多,但是可以防止假设成为错误的原因,例如,这些数据将进入错误的列。

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. 希望对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM