delphi有ExecSQL成功或失败

Sde*_*ean 3 sql delphi ms-access

您好我有这个功能来使用TUniQuery更新我的Access数据库:

var
  Res:Boolean;
begin
Res:=false;
  try
  with MyQuery do
  begin
    Active := false;
    SQL.Clear;
    SQL.Add('Update MYTABLE');
    SQL.Add('set username='+QuotedStr(NewUserName));
    SQL.Add(',password='+QuotedStr(NewPassword));
    SQL.Add('where username='+QuotedStr(ACurrentUserName));
    ExecSQL;
    Res:=true;
  end;
  except
  Res:=False;
  end ;
  Result:=Res;
end;
Run Code Online (Sandbox Code Playgroud)

使用Try ...除了足够知道"ExecSQL"成功或失败时?

或者还有其他更好的方法吗?

谢谢

jac*_*ate 9

如果没有引发异常,您可能需要考虑更新成功.这意味着数据库响应并解析并执行您的语句而不会出现语法错误.

在像所示的语句,你可能还需要确保准确一行进行了更新,因为我认为这是你的意图.

要检查这一点,您可以使用ExecSQL方法的结果,该方法返回受语句执行影响的行数.因此,您可以将代码更改为:

begin
  with MyQuery do
  begin
    Active := false;
    SQL.Clear;
    SQL.Add('Update MYTABLE');
    SQL.Add('set username='+QuotedStr(NewUserName));
    SQL.Add(',password='+QuotedStr(NewPassword));
    SQL.Add('where username='+QuotedStr(ACurrentUserName));
    Result := ExecSQL = 1; //exactly 1 row updated
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我还更改了无条件异常处理程序,因为它可能不是吃任何异常的正确站点,并且还删除了本地变量来存储Result,因为这确实不是必需的.

阅读完添加的文字并重新思考您的问题后:

使用Try ...除了足够知道"ExecSQL"成功或失败时?

你真的必须改变你对异常处理的想法并从这个例程返回一个布尔值.例外是作为一个关于如何解决程序中的异常和错误情况的全新概念引入的,但是你正在杀死这个全新的(和更好的恕我直言)方法,并采用旧的方式返回一个表示成功或失败的值.

特别是一个try/exception吃掉任何异常的块是一种不好的做法,因为你会杀死可能由于太多原因而引发的异常:内存不足,网络问题,如连接丢失到数据库等等.

您必须重新考虑您的方法,并在您的应用程序的适当级别处理这些异常或错误条件.

我的建议是:

  • 这从一个功能改变为一个过程,新合同是:它只返回如果succeded,否则将引发异常.
  • 如果发生异常,请让它飞出例程并在其他地方处理这种情况
  • 如果没有更新确切的1行,则引发您自己的异常
  • 更改查询以使用参数(避免sql注入)

例程可能如下所示:

procedure TMySecurityManager.ChangeUserNameAndPassword();
begin
  MyQuery.SQL.Text := 'Update MYTABLE'
              + '   set username = :NewUserName'
              + '       , password = :NewPassword'
              + ' where username = :username';
  MyQuery.Params.ParamByName('NewUserName').AsString := NewUserName;
  MyQuery.Params.ParamByName('NewPassword').AsString := NewPassword;
  MyQuery.Params.ParamByName('username').AsString := ACurrentUserName;
  if MyQuery.ExecSQL <> 1 then
      raise EUpdateFailed.Create('A internal error occurred while updating the username and password');
  //EUpdateFailed is a hypotetical exception class you defined.
end;
Run Code Online (Sandbox Code Playgroud)