BERDAFLEX Software Systems
Главная > Delphi > Соединение с базами данных при помощи компонент ADO

Соединение с базами данных при помощи компонент ADO

История переиздания
Издание 1.0 2003.12.25 Сергей Бердачук

Продолжая тему использования компонент ADO, хочется обратить ваше внимание об удобном способе настройки соединений к БД с использованием внешних файлов, описывающих параметры соединения.

Если у вас версия ОС Windows 98, то для работы с ADO желательно предварительно скачать пакет обновления Microsoft Data Access Components, это файл mdac_typ.exe. На 95-й версии потребуется установка dcom95.exe.

В Windows системах для файлов описания ADO соединений зарезервировано расширение “udl”. Просто создаем пустой файл с данным расширением, и запускаем его. Перед нами должен появиться мастер настройки соединений, пример работы с которым показан на рисунках 1 и 2.

Рисунок 1. выбор поставщика данных

выбор поставщика данных

Рисунок 2. настройка параметров соединения

настройка параметров соединения

После завершения настройки параметров соединения, созданный нами файл можно использовать для настройки параметров соединения в компоненте TADOConnection.

Рассмотрим следующую структуру организации каталогов проекта:

Project catalog
 |
 +-bin 
 +-connections

Исполняемый файл проекта будем размещать в каталоге /bin, а файлы описания соединений с БД поместим в каталог /connections. Тогда путь к файлам соединений можно определить используя следующий код:

uses
 OLEDB, ActiveX, ADOInt, ComObj,
 StrUtils; //Библиотека компонент RX
...
сonnectionsPath:=UpperCase(IncludeTrailingBackslash(ExtractFilePath(Application.ExeName)));
сonnectionsPath:=ReplaceStr(сonnectionsPath,'\BIN\','\CONNECTIONS\');

Функция установления соединения может иметь вид:

function TDM.Login:boolean;
var
  udlList   : TStringList;
  moreFiles : boolean;
  SearchRec : TSearchRec;
  isFolder, isDotOrDotdot, isValidFile : boolean;
  fName     : String;
begin
 result:=false;
 udlList:=TStringList.Create; //Список доступных файлов, описывающих соединения с БД
 try
   udlList.Clear;
   //Сканируем каталог
   if DirectoryExists(gConnectionsPath) then
    //Добавляем backslash по необходимости
    gConnectionsPath := IncludeTrailingBackslash(gConnectionsPath);
    //сканируем дочерние каталоги
    moreFiles := (FindFirst (gConnectionsPath + '*.udl', faAnyFile, SearchRec) = 0);
    if (moreFiles) then
    try
      while (moreFiles) do
      begin
        isValidFile := true;
        //Определяем, это файл или каталог
        isFolder := (SearchRec.Attr and faDirectory <> 0);
        if (isFolder) then
        begin
          //игнорируем если . или ..
          isDotOrDotdot := (SearchRec.Name[1] = '.');
          if (isDotOrDotdot) then
            isValidFile := false;
        end;
        //добавляем файл в список
        if (isValidFile) then
          begin
            fName:=Copy(SearchRec.Name,1,Pos('.',SearchRec.Name)-1);
            udlList.Add(fName);
          end;
        //продолжаем сканирование
        moreFiles := (FindNext(SearchRec) = 0);
      end;
    finally
      FindClose(SearchRec);
    end;

   try
     //Запрос диалога выбора пароля и файла соединения с БД 
     if ShowPasswordDlg( gLogonUserName, gLogonUserPassword, gLogonDataBase, udlList) then
      try
        Screen.Cursor:=crHourGlass;
        dbConnection.Connected:=False;
        SetMainConnectionSettings(gLogonUserName, gLogonUserPassword, gLogonDataBase);
        dbConnection.Connected:=True;
        Result:=DMR.Get_DatabaseConnectStatus;
      finally
        Screen.Cursor:=crDefault;
      end;
   except
     on E: Exception do
       begin
         LogError(E.Message,['']);
         result:=false;
       end;
   end;   
 finally
   udlList.Free;
 end;
end;
. . .
procedure TDM.SetMainConnectionSettings( const aLogonUserName,
  aLogonPassword, aLogonDatabase:String);
var
  i:integer;
  tmpStr:String;
  dataInit: IDataInitialize;
  dataLinkFileName: WideString;
  innerConnStr: POleStr;
begin
  dbConnection.Connected:=false;
  tmpStr:=CT_FILENAME+IncludeTrailingBackslash(gConnectionsPath)+aLogonDatabase+'.udl';
  //Загружаем параметры соединения из файла
  if CompareText(Copy(tmpStr, 1, 10), CT_FILENAME) = 0 then
    begin
      dataInit := CreateComObject(CLSID_DataLinks) as IDataInitialize;
      dataLinkFileName := Copy(tmpStr, 11, MAX_PATH);
      if Succeeded(dataInit.LoadStringFromStorage(PWideChar(DataLinkFileName), innerConnStr)) then
        tmpStr := innerConnStr;
    end
  else
    tmpStr:='Provider=MSDASQL.1;'+'Persist Security Info=True;';
  dbConnection.DefaultDatabase:='';
  dbConnection.ConnectionString:=tmpStr;
  for i:=0 to dbConnection.Properties.Count-1 do
  begin
    if (dbConnection.Properties[i].Name='Password')
      and (String(DbConnection.Properties[i].Value)<> aLogonPassword ) then
      dbConnection.Properties[i].Set_Value(aLogonPassword)
    else
    if (dbConnection.Properties[i].Name='User ID')
      and (String(DbConnection.Properties[i].Value)<> aLogonUserName) then
      DbConnection.Properties[i].Set_Value(aLogonUserName)
    else
    if (DbConnection.Properties[i].Name='Data Source')
      and(String(DbConnection.Properties[i].Value)<> aLogonDatabase)
      and (tmpStr = 'Provider=MSDASQL.1;'+'Persist Security Info=True;') then
      dbConnection.Properties[i].Set_Value(aLogonDatabase);
  end;
end;

Дополнительную функциональность программе можно придать используя функцию корректировки соединения EditConnectionString, расположенную в модуле $(DELPHI)\Source\Property Editors\AdoConEd.pas. Например:

procedure TfrmMain.actSetConnectionStringExecute(Sender: TObject);
begin
  DM.dbConnection.Close;
  EditConnectionString(DM.dbConnection);
end;
Rambler's Top100 Рейтинг@Mail.ru