【问题标题】:delete a record from a database with a editbox msaccess delphi 7使用编辑框 msaccess delphi 7 从数据库中删除记录
【发布时间】:2013-09-05 22:33:08
【问题描述】:

我是 delphi 新手(或任何与此相关的编码),过去一周我一直在学习 SQL,但我尝试使用该代码从 Msaccess 数据库中查找和删除记录不起作用。当我运行它时它不会给出任何错误,当我单击按钮时它不会做任何事情,它会显示消息但它不会从表中删除记录。我一直在使用这个代码:

begin
ADOQuery1.SQL.Text := 'SELECT * FROM Admins WHERE Name = '''+Edtname.text+'''';
ADOQuery1.Open;
if ADOQuery1.IsEmpty then
ShowMessage('User not found')
else
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'DELETE FROM Admins WHERE Name = '''+EdtName.Text+'''';
ADOQuery1.ExecSQL;
ShowMessage('Information was Deleted');
end;
ADOquery1.Free;
end;

关于数据库的信息:

Collumns     Type
========     ====
Name         Text
Surname      Text
Dateadded    Date/time
Password     Text
Adminnumber  Number

请提供尽可能多的信息来说明为什么会发生此错误,正如我所说的,我还在学习中,提前谢谢你:)

【问题讨论】:

  • 我刚刚为您的 [其他问题] 提供了一个很长的完整答案,并(详细)解释了为什么您应该使用字符串连接来构建 SQL 语句,以及我在这里注意到的第一件事是两个使用连接的 SQL 语句。很高兴看到我浪费了我的时间。 :-(
  • 是的,对不起,但我会尝试学习构建 sql 语句的其他方法,但这是根据我的教科书启动 SQl 的最简单方法的代码,我已经让它工作了。 ..
  • 还有最糟糕的方法... 有一天,当您要编写更复杂的查询时,您会迷失在引号中。看,这是下一个today's example的SQL查询连接问题。
  • 正如我在之前的回答中提到的,从一开始就教自己正确的方法将意味着你的头痛要少得多(并且在这个过程中学到更多东西)。如果您不打算从问题的答案中学习,那么最好还是坚持看书并自己弄清楚。 :-)

标签: sql delphi


【解决方案1】:

如果您坚持使用字符串连接(尽管所有建议相反),至少消除尝试计算单引号的噪音并使用QuotedStr(再次,链接是 XE4 文档,但函数Delphi 7 中也存在)。

我在回答您的其他问题时提供的相同信息也适用于此。 Name 仍然是 MS Access 中的保留字,因此仍需要被[] 包围。每次使用时都需要它,这也是我建议您在走得太远之前更改字段名称的原因。

您发布的代码显示 ADOQuery 在最后被释放,但没有显示它正在创建。我添加了该代码以使其有意义;您需要将连接字符串替换为数据库的连接字符串。我还从ADOQuery1 更改了ADOQuery 的名称(这将与表单上任何现有ADOQuery 的默认名称冲突),因为您的代码似乎正在为这段代码创建一个新的。如果事实上您已经在表单或数据模块上使用了一个,您应该删除tryCreateConnectionString 和行finallyFree,以及下一个end,并重命名所有TempQuery 变量返回ADOQuery1

var
  NumRows: Integer;
  TempQuery: TADOQuery;
begin
  TempQry := TADOQuery.Create(nil);
  try
    TempQuery.ConnectionString := 'Use your own connection string here';

    TempQuery.SQL.Text := 'SELECT * FROM Admins WHERE [Name] = ' +
                           QuotedStr(Edtname.text);
    TempQuery.Open;
    if TempQuery.IsEmpty then
    begin
      ShowMessage('User ' + EdtName.Text + ' not found!');
      Exit;
    end;

    TempQuery.Close;
    TempQuery.SQL.Text := 'DELETE FROM Admins WHERE [Name] = ' +
                           QuotedStr(EdtName.Text);
    TempQuery.ExecSQL;
    NumRows := TempQuery.RowsAffected;
    ShowMessage(IntToStr(NumRows) + ' were deleted');
  finally
    TempQuery.Free;
  end;
end;

不过,再次强调,使用参数化查询会更好。它只增加了两行代码,并消除了SQL injection 所涉及的安全风险ExecSQL 行:

TempQuery.SQL.Text := 'SELECT * FROM Admins WHERE [Name] = :UserName';
TempQuery.Parameters.ParamByName('UserName').Value := EdtName.Text;
TempQuery.Open;

TempQuery.SQL.Text := 'DELETE FROM Admins WHERE [Name] = :UserName';
TempQuery.Parameters.ParamByName('UserName').Value := EdtName.Text;
TempQuery.ExecSQL;

【讨论】:

  • +1 提倡使用参数,也许你可以包含一个关于 SQL 注入的维基百科链接? en.wikipedia.org/wiki/SQL_injection
  • @whosrdaddy:我还将把它添加到我的previous answer 到同一张海报中,在那里我就 SQL 注入的风险进行了深入的讲座,并建议在此处或在 Google 上进行搜索(以及被忽略)。也请参阅我在此答案中的第一句话。 :-) 感谢您的链接;它省去了我寻找它的麻烦。
  • @TLama:感谢您的编辑。一定是我草率的复制/粘贴/编辑。
【解决方案2】:

您是否为 ADOQuery 设置了连接字符串? 您可以通过为 ADOQuery1.ExecSQL 分配一个整数来检查受查询影响的行数: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/ADODB_TADOQuery_ExecSQL.html

当您说正在显示消息时 - 哪个消息?有任何错误详情吗?

【讨论】:

    猜你喜欢
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2011-07-12
    • 2016-12-10
    • 2018-03-16
    相关资源
    最近更新 更多