禁用登录提示而不使用 TDatabase 绕过



我目前正在尝试使用 ODBC 别名连接到数据库 SQL Server。我遇到的问题是,当我使用 TQuery 对象获取信息时,它总是请求登录详细信息(不管我是否在 ODBC 创建中指定了它们(。我不介意在代码中手动设置它们,但我找不到如何做到这一点。
我发现的最常见的解决方案是使用数据库组件并完成它。然而,这有其自身的问题。由于我的数据集太大,并且数据库组件将数据集转换为悖论表,因此我不断收到"临时表资源限制"的BDE错误。如果我忽略数据库组件(这很好(,我不会收到此错误,但这给我留下了登录提示问题。有没有人找到一种方法来绕过 TQuerys 的这个,而无需交换到其他连接路径,例如 ADO?

我对 BDE 有点生疏,但如果您所说的是您在项目中没有使用 TDatabase 组件,我认为没有一种简单的方法来避免登录提示。

原因是,当您尝试在项目中打开没有 TDatabase(或 TSession(组件的 TQuery 时,应用程序中的默认 Session 对象将从 TQuery 的 OpenCursor 中调用以下例程:

{ from DBTables.Pas }
function TSession.DoOpenDatabase(const DatabaseName: string; AOwner: TComponent): TDatabase;
var
  TempDatabase: TDatabase;
begin
  Result := nil;
  LockSession;
  try
    TempDatabase := nil;
    try
      Result := DoFindDatabase(DatabaseName, AOwner);
      if Result = nil then
      begin
        TempDatabase := TDatabase.Create(Self);
        TempDatabase.DatabaseName := DatabaseName;
        TempDatabase.KeepConnection := FKeepConnections;
        TempDatabase.Temporary := True;
        Result := TempDatabase;
      end;
      Result.Open;
      Inc(Result.FRefCount);
    except
      TempDatabase.Free;
      raise;
    end;
  finally
    UnLockSession;
  end;
end;

如您所见,如果会话找不到具有正确名称的现有 TDatabase 组件,它会创建一个临时组件,并且对 Result.Open 的调用会弹出登录提示,据我所知,没有让您有机会在弹出窗口之前提供密码 + 用户名(在此过程中会话的 OnPassword 似乎没有被调用(。

显然,您需要使用调试器检查您的应用程序中是否正在发生这种情况,我的意思是正在创建一个临时 TDatabase。

如果我在下面的更新中建议不起作用,并且我迫切希望避免使用 TDatabase 组件,我会研究可能派生 TQuery 后代的可能性,并尝试覆盖其 OpenCursor 以查看是否可以卡入用户名/密码。

无论如何,正如你所说,如果我理解正确的话,你没有使用明确的 TDatabase,因为"临时表......"问题,并且看到会话无论如何都会创建一个临时的,我想在调查为什么临时不会引发"临时表"错误时可能值得您,而在您的应用程序中使用 TDatabase 组件显然会。 Idapi32.Cfg 配置问题,也许?目前,我无法帮助您,因为我无法重现您的"临时表"错误,尽管使用我的 TQuery 在 SqlServer 表上执行 SELECT 以返回 250,000+ 行。

哦,这是一点:您的表是否包含任何 BLOB? 我似乎记得有一个 Idapi 配置参数,可让您减少 BDE 用于 BLOB 的临时存储空间(也许为零,但自从我"真正"使用 BDE 以来已经有很长时间了(。

更新:我刚刚想到,由于您的查询似乎适用于动态创建 TDatabase 对象的会话,也许它也适用于您自己动态创建的 TDatabase。 我刚刚尝试了以下内容,它对我有用:

procedure TForm1.DatabaseLogin(Database: TDatabase;
  LoginParams: TStrings);
begin
  LoginParams.Add('user name=sa');
  LoginParams.Add('password=1234');  
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  ADatabase : TDatabase;
begin
  ADatabase := TDatabase.Create(Self);
  ADatabase.AliasName := 'MAT41032';
  ADatabase.DatabaseName := 'MAT41032';
  ADatabase.SessionName := 'Default';
  ADatabase.OnLogin := DatabaseLogin;
  Query1.Open;
end;

+1 一个有趣的问题,顺便说一句。

最新更新