如何从 delphi 解析 tnsnames.ora 文件?

发布于 2024-11-29 15:29:44 字数 211 浏览 1 评论 0原文

如何获取 Oracle 数据源名称列表并将它们添加到组合框,以便我可以选择要连接到的数据源?我需要该程序读取 TNS_NAMES.ora 文件的内容并获取数据源名称。我可以执行 FileSearch,但希望程序像 TOAD、PL/SQL 开发人员和其他 Oracle 管理人员一样找到 TNS_NAMES 文件本身,因为该程序将在不同的计算机上运行,​​并且 Oracle 客户端可能会安装到不同的文件夹中。

How can I get the list of Oracle data source names and add them to a combobox so that I can choose whcich datasource to connect to? I need the program to read the contents of the TNS_NAMES.ora file and get the data source names. I can do a FileSearch but want the program to find the TNS_NAMES file itself like TOAD,PL/SQL developer and other Oracle managers do, as the program will be run on different computers and Oracle client might be installed into different folders.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

洛阳烟雨空心柳 2024-12-06 15:29:44

要获取数据源或 TNS_NAMES.ora 文件中包含的任何其他信息,您必须解析该文件。因此,首先从 此处此处,以及那么你可以使用最常见的方法来解析这些文件,那就是使用正则表达式。不幸的是,Delphi 2010 RTL 不支持正则表达式。但您可以使用 PCRE 库)。从这里您可以使用这些文章作为指导来编写您自己的 Delphi 实现。

To get the datasource or any other information contained inside of the TNS_NAMES.ora file you must parse this file. So first read the Syntax Rules for this file from here and here, and then you can use the most common approach to parse these files, which is use regular expressions. Unfortunally the Delphi 2010 RTL doesn't include support for regular expressions. But you can use the PCRE library). from here you can use as guide these articles to write your own delphi implementation.

街道布景 2024-12-06 15:29:44

您可以将此代码用于 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.

You can use this code for Oracle 10. Drop combobox and button on your form and link FormCreate and button1click events.

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文