Как я могу разобрать файл tnsnames.ora из delphi? - PullRequest
1 голос
/ 12 августа 2011

Как получить список имен источников данных Oracle и добавить их в комбинированный список, чтобы я мог выбрать, к какому источнику данных подключаться? Мне нужна программа для чтения содержимого файла TNS_NAMES.ora и получения имен источников данных. Я могу выполнить FileSearch, но хочу, чтобы программа сама находила файл TNS_NAMES, как это делают TOAD, PL / SQL разработчик и другие менеджеры Oracle, так как программа будет работать на разных компьютерах, а клиент Oracle может быть установлен в разные папки.

Ответы [ 2 ]

3 голосов
/ 12 августа 2011

Чтобы получить источник данных или любую другую информацию, содержащуюся в файле TNS_NAMES.ora, необходимо проанализировать этот файл.Поэтому сначала прочитайте правила синтаксиса для этого файла из здесь и здесь , а затем вы можете использовать наиболее распространенный подход для разбора этих файлов, который заключается в использовании регулярных выражений.К сожалению, RTL Delphi 2010 не включает поддержку регулярных выражений.Но вы можете использовать библиотеку PCRE ).отсюда вы можете использовать эти статьи в качестве руководства для написания своей собственной реализации delphi.

1 голос
/ 17 апреля 2015

Вы можете использовать этот код для Oracle 10. Удалите поле со списком и кнопку на форме и связать события FormCreate и button1click.

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Registry, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure ParseTNS;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  slTNSConfig : TStringList;

implementation

{$R *.dfm}

function GetTNSNamesPath : string;
var
  Reg: TRegistry;
  SubKeyNames: TStringList;
  Name: string;
begin
  Reg := TRegistry.Create;
  Try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    Reg.OpenKeyReadOnly('SOFTWARE\ORACLE');
    SubKeyNames := TStringList.Create;
    Try
      Reg.GetKeyNames(SubKeyNames);
      for Name in SubKeyNames do
// oracle 10 save path to ORACLE_HOME in registry key like this
// HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient10g_home1\ORACLE_HOME
// for oracle 8 and 9 another key
        if pos('KEY_',Name)=1 then 
        begin
          Reg.OpenKeyReadOnly(Name);
// for oracle 10 path to tnsnames.ora like this
// %ORACLE_HOME%\NETWORK\ADMIN\tnsnames.ora
// for oracle 8 and 9 another path
          Result :=Reg.ReadString('ORACLE_HOME')+'\NETWORK\ADMIN\tnsnames.ora';
        end;
    Finally
      SubKeyNames.Free;
    End;
  Finally
    Reg.Free;
  End;
end;

procedure TForm1.ParseTNS;
var
  slTemp : TStringList;
  sPath, sTemp : string;
  i : integer;
begin
  slTemp:= TStringList.Create;
  slTNSConfig:= TStringList.Create;
  try
    sPath:=GetTNSNamesPath;
    if (length(sPath)<33) or (not FileExists(sPath)) then
      messageDlg('tnsnames.ora not found.', mtError, [mbOk],0)
    else
    begin
      slTemp.LoadFromFile(sPath);    // Load tnsnames.ora
      sTemp := StringReplace(StringReplace(UpperCase(slTemp.Text),' ','',[rfReplaceAll]),')','',[rfReplaceAll]);  // delete ')' and spaces
      slTemp.Clear;
      slTemp.Delimiter:='(';        
      slTemp.DelimitedText:=sTemp;   // parse like  Name=Value
      sTemp:='';
      for i := 0 to slTemp.Count-1 do
      begin
        if pos('DESCRIPTION',slTemp[i])=1 then  // Get Name before description
        begin
          sTemp:=StringReplace(slTemp[i-1],'=','',[rfReplaceAll]);
          ComboBox1.Items.Add(sTemp);    // Fill combobox
        end;
        if length(slTemp.ValueFromIndex[i])>0 then  //Get filled Name=Value
          slTNSConfig.Add(sTemp+'_'+slTemp[i]);  // Fill TNS config like TNS_HOST=Value
      end;
      ComboBox1.Sorted:=true;
    end;
  finally
    slTemp.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ComboBox1.Text:='';
  ParseTNS;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sHost, sPort, sSID, sServiceName : string;
begin
  sHost:=slTNSConfig.Values[ComboBox1.Text+'_HOST'];
  sPort:=slTNSConfig.Values[ComboBox1.Text+'_PORT'];
  sSID:=slTNSConfig.Values[ComboBox1.Text+'_SID'];
  sServiceName:=slTNSConfig.Values[ComboBox1.Text+'_SERVICE_NAME'];
  messageDLG('sHost:'+sHost+' sPort:'+sPort+' sSID:'+sSID+' sServiceName:'+sServiceName,mtInformation,[mbOk],0);
end;

end.
...