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