【问题标题】:Sql inserting with delphi xe3 and mysql database用delphi xe3和mysql数据库插入sql
【发布时间】:2014-04-17 13:37:43
【问题描述】:

我正在使用 Delphi Xe5 和 ZeosLib 连接到 Web 服务器上的远程数据库。

我正在使用以下代码将记录插入到表中。但每次我插入并且名称中有 (') 时,我都会收到错误消息。

错误说我的语法错误,变量中的(')与sql语句混淆。

我该如何解决这个问题。

代码:

  Data.personel.Active:=false;
  sqltext:=data.personel.SQL.Text;
  data.personel.SQL.Text:='Insert Into personel (name,surname,id_number,gender,company_name,nature_of_business,position_at_company,type_of_post,renumeration,company_size,duties,benefits,document_id,date_created,date_record_added) ' +
                          'VALUES ('''+name1+''','''+surname+''','''+idnumber+''','''+gender+''','''+companyname+''','''+natureofbusiness+''','''+positionatcompany+''','''+typeofpost+''','''+renumeration+''','''+companysize+''','''+duties+''','''+benefits+''','''+DokID+''',+'''+FormatDateTime('yyyy-mm-dd',Date_Created)+''','''+FormatDateTime('yyyy-mm-dd',Date_added)+''')';
  Data.personel.ExecSQL;

我知道我的方法不是最简洁的,但我只需要解决 (') 问题。感谢您的帮助

【问题讨论】:

  • 使用参数,你会没事的。 [如果有人发表一些我们可以链接到的一般性帖子,那就太好了;看起来这种问题每周被问两次]
  • 如果此时你不能使用参数(即如果你的动态 SQL 需要一个变量表名),那么你需要使用 QuotedStr。但实际上,尽管如果您有现有代码,这似乎更容易,但首先使用参数,因为它们有额外的好处。
  • @MatTAllwood 能否请您发布一个示例。我以前从未使用过参数或 qoutedstr?
  • 看看这些问答:100917771112479116924629

标签: mysql sql delphi


【解决方案1】:

看在上帝的份上,不要连接 SQL。它为 SQL 注入打开了大门,它会导致您现在遇到的问题。请改用参数化 SQL 语句(请参阅下面的注释):

data.personel.Active := False;
data.personel.SQL.Text := 'Insert Into personel'#13 +
     '(name, surname, id_number, gender, company_name, nature_of_business,'#13 +
     'position_at_company, type_of_post, renumeration, company_size,'#13 +
     'duties, benefits, document_id, date_created, date_record_added)'#13 +
     'values'#13 +
     '(:name, :surname, :id_number, :gender, :company_name, :nature_of_business, '#13 +
     ':position_at_company, :type_of_post, :renumeration, :company_size,'#13 +
     ':duties, :benefits, :document_id, :date_created, :date_record_added)';
data.personel.ParamByName('name').AsString := name1;
data.personel.ParamByName('surname').AsString := surname;
data.personel.ParamByName('id_number').AsString := idnumber;
data.personel.ParamByName('gender').AsString := gender;  
// repeat for remaining values 
data.personel.ExecSQL;

注意事项:

  • SQL 语句每个部分末尾的#13 是一个回车符。它使您不必担心每行开头或结尾的空格。服务器将忽略它们,因为额外的空格在 SQL 语句中是没有意义的。这与在数据库管理工具中测试查询时在每行末尾按回车键相同。

  • 我使用列名作为参数名,在它前面加上:,表示它是一个参数。它可以很容易地分辨出哪个与哪个相配 - :surname 参数与surname 列相配。

  • 如果将 SQL 语句放入它自己的查询组件中,则可以在设计时将所有 SQL 放入,而不是在运行时提供。这意味着服务器可以缓存已编译的语句,以防您在短时间内再次使用它,如果您在循环中使用它们,则可以更快地执行查询。您只需更改分配给循环中参数的值,而单独留下 SQL.Text。

  • 因为您的应用程序仅在内部使用并且不暴露于网络并不意味着您应该忽略 SQL 注入的风险。只需要一名心怀不满的员工决定报复您或您的公司并了解这种可能性 - 当他们决定在正确的编辑控件中输入您不想要的内容并删除或更改重要的数据库或表时,损坏同样严重。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2015-03-25
    • 2016-12-12
    相关资源
    最近更新 更多