Delphi 在不使用TDatabase旁路的情况下禁用登录提示

Delphi 在不使用TDatabase旁路的情况下禁用登录提示,delphi,odbc,delphi-5,bde,tquery,Delphi,Odbc,Delphi 5,Bde,Tquery,我当前正在尝试使用SQL Server的ODBC别名连接到数据库。我遇到的问题是,当我使用TQuery对象获取信息时,它总是请求登录详细信息(不管我是否在ODBC创建中指定了登录详细信息)。我不介意在代码中手动设置它们,但我找不到如何进行设置。 我发现的最常见的解决方案是使用数据库组件并进行检查。然而,这也有其自身的问题。由于我的数据集太大,而且数据库组件将数据集转换为Paradox表,所以我不断得到一个BDE错误“临时表资源限制”。 如果忽略数据库组件(这很好),则不会出现此错误,但这会导致登

我当前正在尝试使用SQL Server的ODBC别名连接到数据库。我遇到的问题是,当我使用TQuery对象获取信息时,它总是请求登录详细信息(不管我是否在ODBC创建中指定了登录详细信息)。我不介意在代码中手动设置它们,但我找不到如何进行设置。
我发现的最常见的解决方案是使用数据库组件并进行检查。然而,这也有其自身的问题。由于我的数据集太大,而且数据库组件将数据集转换为Paradox表,所以我不断得到一个BDE错误“临时表资源限制”。
如果忽略数据库组件(这很好),则不会出现此错误,但这会导致登录提示问题。有没有人找到一种方法可以绕过TQuerys而不切换到其他连接路径,如ADO?

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

原因是,当您尝试在项目中不使用TDatabase(或TSession)组件的情况下打开TQuery时,应用程序中的默认会话对象将从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表上进行选择以返回250000多行

哦,这是一个要点:您的表是否包含任何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对于一个有趣的问题,顺便说一句。

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

原因是,当您尝试在项目中不使用TDatabase(或TSession)组件的情况下打开TQuery时,应用程序中的默认会话对象将从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表上进行选择以返回250000多行

哦,这是一个要点:您的表是否包含任何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对于一个有趣的问题,顺便说一句。

为什么要避免ADO?设置TAdoQuery从Sql Server获取数据最多需要2分钟,而且您将永远摆脱BDE。听起来您似乎正处于BDE的边缘……我承认我有一个问题