52

我正在开发一个非常简单的应用程序,我打算用它来解决我在几台机器上遇到的问题,但在我还没走到那一步之前,我遇到了一些问题,包括 cpu 架构差异和 Oracle 数据库库。

我在目录中列出了一个数据库tnsnames.ora服务器C:\oracle\11g\network\admin。如果我 tnsping 此服务器,我会得到所需的响应。如果我使用 Oracle.DataAccess.Client 编写我的 C# 程序以使用以下代码连接到该服务器,它就可以工作。

string connectionString = "Data Source=DSDSDS;User Id=UNUNUN;Password=PWPWPW;";
DataTable dataTable = new DataTable();

using (var connection = new OracleConnection(connectionString)) {
    connection.Open();
    using (var command = new OracleCommand()) {
        command.Connection = connection;
        command.CommandText = sql;
        command.CommandType = CommandType.Text;
        using (var oda = new OracleDataAdapter(command)) {
            oda.Fill(dataTable);
        }
    }
}

但是 Oracle.DataAccess 依赖于它运行的系统的体系结构。我看到还有另一个库 Oracle.ManagedDataAccess 是架构独立的。当我使用这个库时,它不再能够连接到服务器。一个ORA-12545: Network Transport: Unable to resolve connect hostname被抛出。

为什么会这样?这两个库之间有什么不同,因为根据我迄今为止阅读的内容,这应该不是问题。

额外的信息:

  • %ORACLE_HOME% 和 %TNS_ADMIN% 未定义(请记住 tnsping 和 Oracle.DataAccess 有效)
  • PATH 已C:\oracle\11g\BIN定义。
  • 我的机器只有一个tnsnames.ora文件

如果我将 tnsnames.ora 移动到与我的 .exe 文件相同的位置,它就可以工作。为什么Oracle.DataAccess 可以在C:\oracle\11g\network\admin目录中找到tnsnames.ora 而Oracle.ManagedAccess 找不到?

4

8 回答 8

66

在 ODP.NET 托管驱动程序中解析 TNS 名称的优先顺序如下(参见此处):

  1. .NET 配置文件部分下的“dataSources”部分中的数据源别名。
  2. tnsnames.ora 文件中的数据源别名,位于 .NET 配置文件中“TNS_ADMIN”指定的位置。
  3. 与 .exe 位于同一目录中的 tnsnames.ora 文件中的数据源别名。
  4. tnsnames.ora 文件中存在于 %TNS_ADMIN% 的数据源别名(其中 %TNS_ADMIN% 是环境变量设置)。
  5. %ORACLE_HOME%\network\admin 中的 tnsnames.ora 文件中的数据源别名(其中 %ORACLE_HOME% 是环境变量设置)。

我相信您的示例适用于 Oracle.DataAccess 但不适用于 Oracle.ManagedDataAccess 的原因是后者不支持基于 Windows 注册表的配置(请参阅文档) - ODP.NET 安装设置了 ORACLE_HOME 注册表项(HLKM\SOFTWARE\Oracle \Key_NAME\ORACLE_HOME),它只被非托管部分识别。

于 2013-11-18T14:41:15.420 回答
17

尝试将 tnsnames.ora 的路径添加到配置文件中:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <oracle.manageddataaccess.client>
    <version number="4.112.3.60">
      <settings>
        <setting name="TNS_ADMIN" value="C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\" />
      </settings>
    </version>
  </oracle.manageddataaccess.client>
</configuration>
于 2013-08-06T07:05:54.970 回答
7

为了避免不知道在哪里寻找 TNSNAMES.ORA 的所有 Oracle 混乱(我增加了多个 Oracle 版本和 32/64 位的混淆),您可以将现有 TNSNAMES.ORA 中的设置复制到您自己的配置中文件并将其用于您的连接。
假设您对 TNSNAMES.ORA 中的“DSDSDS”引用感到满意,该引用映射到以下内容:

DSDSDS=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(端口=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)))

您可以在第一个 '=' 之后获取文本,并在使用 'DSDSDS' 的任何地方使用它,并且无需查找 TNSNAMES.ORA 即可知道如何连接。
现在您的连接字符串将如下所示:
string connectionString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=DSDSDSHost)(Port=4521)))(CONNECT_DATA=(SERVICE_NAME=DSDSDSService)));User Id=UNUNUN;Password=PWPWPW;";

于 2016-10-05T16:02:42.667 回答
3

一旦我在连接字符串中找到它正在寻找的格式,它就可以像 Oracle.ManagedDataAccess 一样正常工作。无需单独处理任何事情。

DATA SOURCE=DSDSDS:1521/ORCL;
于 2015-09-30T15:18:15.310 回答
1

我有类似的问题......为了解决这个问题,我所做的是卸载 ODP。Net 并重新安装在与 oracle 服务器相同的目录中......使用服务器选项您会注意到大多数产品已经安装(在 12c 数据库安装时),因此只需选择其他功能并最终完成安装。 ...

请注意,只有当您在同一台机器上(即在您的笔记本电脑上)安装了 12c 时,此解决方法才有效............

如果您的数据库位于笔记本电脑以外的服务器计算机上,请选择客户端选项而不是服务器,然后在您的 app.config 中包含 TNS_ADMIN 并且不要忘记指定版本...

因为我的安装是在我的笔记本电脑上所以我的 App.config 如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
</configuration>


 /////////the below code is a sample from oracle company////////////////


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Oracle.ManagedDataAccess.Client;

///copy these lines in a button click event 
    string constr = "User Id=system; Password=manager; Data Source=orcl;";
// Click here and then press F9 to insert a breakpoint
        DbProviderFactory factory =
    DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client");
            using (DbConnection conn = factory.CreateConnection())
            {
                conn.ConnectionString = constr;
                try
                {
                    conn.Open();
                    OracleCommand cmd = (OracleCommand)factory.CreateCommand();
                    cmd.Connection = (OracleConnection)conn;

//to gain access to ROWIDs of the table
//cmd.AddRowid = true;
                    cmd.CommandText = "select * from all_users";

                    OracleDataReader reader = cmd.ExecuteReader();

                    int visFC = reader.VisibleFieldCount; //Results in 2
                    int hidFC = reader.HiddenFieldCount;  // Results in 1

                    MessageBox.Show(" Visible field count: " + visFC);

                    MessageBox.Show(" Hidden field count: " + hidFC);


                    reader.Dispose();
                    cmd.Dispose();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                      MessageBox.Show(ex.StackTrace);
                }
            }
于 2014-03-22T16:02:58.023 回答
0

晚会“有点”晚了,但真正的答案是 - 如果您使用Oracle.ManagedDataAccessODP.NET 提供程序,您应该忘记诸如network\admin, Oracle client,Oracle_Home等之类的东西。

这是你需要的

  1. 下载并安装适用于 VS或ODAC的 Oracle Developer Tools。注意 - 开发工具将为您安装 ODAC。这将在. 使用完整的开发工具,小于 60MbC:\Program Files (x86)
  2. 在您的项目中,您将安装带有相应版本的 ODP.net (Oracle.ManagedDataAccess.dll)的 Nuget 包,您将参考该包
  3. 此时,您有 2 个连接选项。

    • datasourcea) 在以下格式设置的连接字符串中

      DataSource=ServerName:Port/SID . . .或者DataSource=IP:Port/SID . . .

    • b) 创建tnsnames.ora文件(只是它将与以前的经验不同)。有条目:

      AAA = (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = ServerNameOrIP)(PORT = 1521))
      (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = SIDNAME)))

      并将此文件放入运行应用程序的 bin 文件夹中。现在您可以使用您的连接名称进行连接 -DataSource=AAA . . .因此,即使您有tnsnames.ora,但在 ODP.net管理下它的工作方式有点不同 - 您创建本地 TNS 文件。现在,很容易管理它。

总而言之 - 使用托管,无需繁重的 Oracle 客户端,Oracle_home或了解 Oracle 安装文件夹的深度。一切都可以在您的 .net 应用程序结构中完成。

于 2019-04-18T16:37:47.643 回答
0

就我而言,上面所说的一切都很好,但我仍然收到了ORA-12545: Network Transport: Unable to resolve connect hostname

我尝试 ping Oracle 机器,发现我看不到它并将其添加到主机文件中。然后我收到另一条错误消息ORA-12541: TNS:no listener。经过调查,我意识到从不同的机器上 ping 相同的主机名得到不同的 IP 地址(我不知道为什么),我更改了主机文件中的 IP 地址,100% 解决了问题。

我很费心写我的经验,因为它看起来很明显,但是虽然我确定问题出在上述设置中,但我完全忘记检查我是否真的可以看到远程数据库机器。当你不知道发生了什么时,请记住它......

这些链接对我帮助很大:

http://www.moreajays.com/2013/03/ora-12545-connect-failed-because-target.html http://www.orafaq.com/wiki/ORA-12541

于 2019-02-18T12:39:32.070 回答
-2

我收到了同样的错误信息。为了解决这个问题,我只是用Oracle.ManagedDataAccess旧的程序集替换了程序Oracle.DataAccess集。如果您需要在新装配中找到新功能,此解决方案可能不起作用。就我而言,我有更多优先级更高的问题,然后尝试配置新Oracle程序集。

于 2015-06-12T15:18:18.433 回答