FireDac 连接问题

Posted

技术标签:

【中文标题】FireDac 连接问题【英文标题】:FireDac connection issue 【发布时间】:2015-08-14 09:32:14 【问题描述】:

我在这里使用了一个示例:

establishing connection

这样做了:

procedure TDataModule2.DataModuleCreate(Sender: TObject);
begin
with FDGUIxLoginDialog1.VisibleItems do begin
  Clear;
  Add('Server=Strežnik');
  Add('User_name=Uporabnik');
  Add('Password=Geslo');
  Add('Database=Baza');
end;
try
FDConnection1.Connected := True;
except
  on E: EAbort do
  application.terminate;   // user pressed Cancel button in Login dialog

  on E:EFDDBEngineException do
    case E.Kind of
    ekUserPwdInvalid: ; // user name or password are incorrect
    //ekUserPwdExpired: ; // user password is expired
    ekServerGone: ;     // DBMS is not accessible due to some reason
    else
                 // other issues
    end;
end;
end;

但是,在登录对话框中点击取消后,应用程序不会终止,而是显示我的主表单。我应该怎么做才能纠正这个?

另外,在这种情况下,如果密码错误,我该如何闪烁消息?

Firedac 正在连接到 SQL Server。

ps

即使这样也行不通:

.....
except
  on E: EFDDBEngineException do
  if E.Kind = ekUserPwdInvalid then
      begin
        ShowMessage('A user name or a password are invalid');
        Abort;
      end;

【问题讨论】:

您是否将相关单元/组件添加到数据模块中? (SQLServer 驱动程序和等待光标?) 这只会在点击对话框上的取消按钮产生异常时起作用。你应该调试它来检查。即使发生了,如果异常不是 EAbort 或 EFDDBEngineException 而是其他一些异常,在这种情况下什么都不会发生 我不确定您期望在这里发生什么。您正在寻找的EAbort 异常只会在如果在数据库组件最初尝试建立连接的确切时刻引发异常。如果您希望应用程序在他们点击取消按钮时终止,那么您必须单独实现。再往下,抛出EAbort 不会导致应用程序本身终止——你必须在某个地方捕捉到它并用它做一些事情(如果这是一种停止应用程序的明智方法,它可能不是) 使用“on E: EFDException do if E.FDCode = er_FD_ClntDbLoginAborted then Application.Terminate”而不是“on E: EAbort ...” 【参考方案1】:

应用程序通常通过关闭其主窗体来退出。 您永远不应该通过发出异常来让应用程序退出;这是不好的形式。

EAbort 不是登录对话框发出的异常。其实正常情况下te login dialog不会发出任何异常。 如果用户按下 Cancel 则连接将无法 ehm.. 连接,您可以测试一下。Here's a list of all the errors TFDConnection can generate.

以下代码应该可以工作:

type
  TAction = (aSuccess, aGiveup, aWrongPassword, aPasswordExpired);

procedure TDataModule2.DataModuleCreate(Sender: TObject);
var
  VI: TStrings; 
  WhatToDo: TAction;
begin
  WhatToDo:= aSuccess;
  VI:= FDGUIxLoginDialog1.VisibleItems; 
  VI.Clear;
  VI.Add('Server=Strežnik');
  VI.Add('User_name=Uporabnik');
  VI.Add('Password=Geslo');
  VI.Add('Database=Baza');
  try
    FDConnection1.Connected := True;
  except
    on E:EFDDBEngineException do case E.Kind of
      ekUserPwdInvalid: WhatToDo:= aWrongPassword;
      ekUserPwdExpired: WhatToDo:= aPasswordExpired;
      else WhatToDo:= aGiveUp;
    end; case
  end;
  if Not(FDConnection1.Connected) then WhatToDo:= aGiveUp;
  case Action of
    aWrongPassword: begin
      ShowMessage('You've entered a wrong username or password please try again');
      DataModuleCreate(Sender);
      Action:= aSuccess;
    end;
    aPasswordExpired: ShowMessage('You password has expired, please request a new one from the PHB');
  end;
  if Action <> aSuccess then Application.Terminate;
end;

关于编码风格的评论 不要使用with。 With 是邪恶的,而是使用临时变量并使用它来引用嵌套变量。

在不发出错误的情况下终止错误真的很愚蠢。 没有任何用户会乐于在没有任何解释的情况下让应用程序死在他们身上。

您永远不应因错误的密码或用户名而终止。 至少让用户更改重试 3 或 4 次。 如果他不正确,则发出“错误的用户名或密码”错误消息并退出。 永远不要告诉用户哪个(用户名或密码)是错误的,攻击者可以使用它来生成用户名列表。

【讨论】:

以上是关于FireDac 连接问题的主要内容,如果未能解决你的问题,请参考以下文章

(FireDAC) 连接定义

Delphi - FireDAC的连接配置

Delphi:FireDac 连接阻止应用程序

firedac连接linux的oracle

如何找到用于 FireDac 连接的 MS Access 版本和/或 dll 名称?

Delphi XE FireDac 连接池