2011-08-12 5 views
1

오라클 데이터 소스 이름 목록을 가져 와서 콤보 박스에 추가하여 연결할 데이터 소스를 선택할 수 있습니까? TNS_NAMES.ora 파일의 내용을 읽고 데이터 소스 이름을 얻는 프로그램이 필요합니다. 필자는 FileSearch를 수행 할 수 있지만 프로그램이 다른 컴퓨터에서 실행되고 Oracle 클라이언트가 다른 폴더에 설치 될 수 있으므로 TOAD, PL/SQL 개발자 및 기타 Oracle 관리자와 같은 TNS_NAMES 파일 자체를 찾는 프로그램이 필요합니다.델파이에서 tnsnames.ora 파일을 어떻게 파싱 할 수 있습니까?

답변

3

TNS_NAMES.ora 파일 안에 포함 된 데이터 소스 또는 기타 정보를 얻으려면이 파일을 구문 분석해야합니다. 따라서 먼저이 파일의 구문 규칙을 herehere에서 읽은 다음 가장 일반적인 방법을 사용하여 정규식을 사용하여이 파일을 구문 분석 할 수 있습니다. 불행히도 Delphi 2010 RTL에는 정규 표현식에 대한 지원이 포함되어 있지 않습니다. 하지만 PCRE library을 사용할 수 있습니다.) 여기에서 자신의 델파이 구현을 작성하기 위해이 기사를 가이드로 사용할 수 있습니다.

  • TNSNames Reader 당신은 당신의 형태와 링크 FormCreate와 Button1Click이라 이벤트에 오라클 10. 드롭 콤보 상자와 버튼이 코드를 사용할 수 있습니다
+0

고관절. 그 많은 도움이 –

+0

정규 표현식은 구문 분석을위한 매우 잘못된 도구입니다. –

1

(C#을)

  • Parsing tnsnames.ora using regex (C#을).

    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. 
    
  • +0

    특히 코드의 주석 처리가 제거 된 경우 코드 전용 답변은 일반적으로 권장되지 않습니다. 답에 몇 가지 의견이나 설명을 추가해 주시겠습니까? –

    +0

    덧글에 .. –

    +0

    죄송합니다. 나는 러시아 출신이다. –

    관련 문제