Отключение приглашения на вход без использования обхода TDatabase
В настоящее время я пытаюсь подключиться к базе данных, используя псевдоним ODBC для SQL Server. Проблема, с которой я сталкиваюсь, заключается в том, что когда я использую свой объект TQuery для получения информации, он всегда запрашивает данные для входа в систему (не важно, указал ли я их при создании ODBC). Я не против вручную установить их в коде, но я не могу найти, как это сделать.
Наиболее распространенное решение, которое я нашел, - это использовать компонент базы данных и пройти через это. Однако это имеет свои проблемы. Из-за того, что мой набор данных настолько большой, что компонент базы данных преобразует набор данных в таблицу Paradox, я продолжаю получать ошибку BDE "Временный предел ресурсов таблицы". Я не получаю эту ошибку, если игнорирую компонент базы данных (что нормально), однако это оставляет меня с проблемой приглашения на вход в систему. Кто-нибудь нашел способ обойти это для TQuerys, не переключаясь на другие пути подключения, такие как ADO?
1 ответ
Я немного устал от BDE, но я не думаю, что есть простой способ избежать приглашения на вход в систему, если вы говорите, что вы не используете компонент TDatabase в своем проекте.
Причина в том, что когда вы пытаетесь открыть свой TQuery без компонента TDatabase (или TSession) в вашем проекте, объект Session по умолчанию в вашем приложении будет вызывать следующую процедуру изнутри OpenCursor вашего TQuery:
{ 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, я бы рассмотрел возможность получения потомка TQuery и попытки переопределить его OpenCursor, чтобы увидеть, могу ли я заклинивать. в имени пользователя / пароле.
В любом случае, если вы правильно поняли, что, как вы говорите, вы не используете явную базу данных TDatabase, из-за проблемы с "Временной таблицей..." и видите, что сеанс в любом случае создаст временную, я предполагаю, что это может быть Стоит разобраться, почему временная не вызывает ошибку "Временная таблица", в то время как использование компонента TDatabase в вашем приложении очевидно. Может, проблема с конфигурацией Idapi32.Cfg? На данный момент я не могу помочь вам с этим, потому что я не могу воспроизвести вашу ошибку "Временная таблица", несмотря на то, что я использовал свой TQuery для выполнения SELECT в таблице SqlServer для возврата более 250000 строк.
О, в этом суть: есть ли в вашей таблице какие-либо BLOB-объекты? Кажется, я помню, что есть параметр конфигурации Idapi, который позволяет вам сократить пространство временного хранения, которое BDE использует для больших двоичных объектов (возможно, до нуля, но с тех пор, как я использовал BDE "по-настоящему"), прошло много времени.
Обновление: мне только что пришла в голову мысль, что поскольку ваш запрос, кажется, работает с Session, динамически создающим объект 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 за интересный вопрос, кстати.