Отключение приглашения на вход без использования обхода 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 за интересный вопрос, кстати.

Другие вопросы по тегам