【问题标题】:Can't connect to Oracle from a windows service (error: ORA-12154: TNS:could not resolve service name (12154) )无法从 Windows 服务连接到 Oracle(错误:ORA-12154: TNS:could not resolve service name (12154))
【发布时间】:2011-08-26 14:22:55
【问题描述】:

最新更新(2011 年 11 月 2 日上午 9 点) 我尝试从服务运行 tnsping 并且它有效! 但是,当我尝试连接时,我仍然收到错误 12154。我现在完全糊涂了,我无法理解 tnsping 是如何正常工作的,但是连接无法解析服务名称。

由于某种原因,当我从 Windows 服务(在计时器事件上)运行以下代码时,我收到错误:ORA-12154: TNS:could not resolve service name (12154)

当我从 Windows 窗体应用程序运行完全相同的代码时,它连接得很好。服务和应用都在我的账号下运行,所以账号权限没有区别。
我对为什么服务失败感到困惑,有人可以解释一下吗?

string connectionString =     ";DSN=o1;UID=SCOTT;PWD=TIGER;DBQ=ORCL;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=F;BAM=IfAllSuccessful;MTS=F;MDI=F;CSR=F;FWC=F;PFC=10;TLO=0;";
        OdbcConnection cnn;
        cnn = new OdbcConnection(connectionString);
        try
        {
            cnn.Open();
            myEventLog.WriteEntry("Connection SUCCEEDED!!!");
            cnn.Close();
        }
        catch (Exception ex)
        {
            string mes = "Connection FAILED!!!" + ex.Message;
            myEventLog.WriteEntry(mes);
        }

更新:

1) 我已尝试使用系统和用户 dsn,两者的行为相同

2)我在系统环境变量中添加了一个TNS_ADMIN,使sue可以找到tnsnames.ora文件。这并没有改变行为。

新更新(2011 年 11 月 1 日):

1) 很多建议都涉及将 Oracle 服务器的 IP 地址放在连接字符串中以绕过 tnsnames.ora 文件。不幸的是,该应用程序必须使用用户设置的 oracle 连接,因此我们没有任何此类信息。我只需要使用 DSN。我必须使用 Oracle DSN 从 Windows 服务连接。

新更新(2011 年 11 月 2 日): 1) 看起来服务正在成功读取 tnsnames.ora 文件。我运行了进程监视器并得到了这些行:

7:52:54.4365217 AM  OracleService.exe   4624    CreateFile          C:\oracle\ora92\network\Names\sdns.ora  NAME NOT FOUND  Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: n/a
7:52:54.4368466 AM  OracleService.exe   4624    CreateFile  C:\Windows\SysWOW64\tnsnames.ora    NAME NOT FOUND  Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a
7:52:54.4371203 AM  OracleService.exe   4624    CreateFile  C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
7:52:54.4372693 AM  OracleService.exe   4624    QueryBasicInformationFile   C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS CreationTime: 01/11/2011 3:10:08 PM, LastAccessTime: 01/11/2011 3:10:08 PM, LastWriteTime: 01/11/2011 3:10:42 PM, ChangeTime: 01/11/2011 3:18:44 PM, FileAttributes: A
7:52:54.4372866 AM  OracleService.exe   4624    CloseFile   C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS 
7:52:54.4375418 AM  OracleService.exe   4624    CreateFile  C:\oracle\ora92\network\ADMIN   SUCCESS Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
7:52:54.4375857 AM  OracleService.exe   4624    QueryDirectory  C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS Filter: tnsnames.ora, 1: tnsnames.ora
7:52:54.4376192 AM  OracleService.exe   4624    CloseFile   C:\oracle\ora92\network\ADMIN   SUCCESS 
7:52:54.4377770 AM  OracleService.exe   4624    CreateFile  C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: n/a, OpenResult: Opened
7:52:54.4379306 AM  OracleService.exe   4624    ReadFile    C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS Offset: 0, Length: 337, Priority: Normal
7:52:54.4380061 AM  OracleService.exe   4624    ReadFile    C:\oracle\ora92\network\ADMIN\tnsnames.ora  END OF FILE Offset: 337, Length: 4,096
7:52:54.4380276 AM  OracleService.exe   4624    CloseFile   C:\oracle\ora92\network\ADMIN\tnsnames.ora  SUCCESS 
7:52:54.4385823 AM  OracleService.exe   4624    CreateFile  C:\oracle\ora92\network\ADMIN\ldap.ora  NAME NOT FOUND  Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a

那么有没有人知道为什么在读取 tnsnames.ora 文件后它可能会失败?谢谢

【问题讨论】:

  • 因为它在您运行时可以工作,所以我假设您的 tnsnames.ora 配置正确。您要连接的 ODBC DSN 是设置为系统 DNS 还是用户 DSN?
  • 我已经尝试过系统和用户 dsn,两者的行为相同。
  • 你用的是哪个版本的windows?
  • 我在 Windows 7 上,但据我所知,它发生在所有当前版本的 Windows 上

标签: oracle windows-services


【解决方案1】:

您在相应对话框中定义的环境变量不适用于 Windows 服务。您可以尝试的一件事是扩展您的连接字符串,如post 中所述。来自同一帖子的其他建议可能适用。

【讨论】:

  • 感谢您的意见。很抱歉,但我不太了解 Oracle 或连接字符串,所以我尝试了您链接中建议的内容,但是当我将连接字符串更改为:Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP) )(HOST=192.168.121.200)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));用户ID=SCOTT;密码=TIGER;我收到错误:[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified and I get it in both the app and the service,所以我做错了什么,但我不知道是什么。谢谢
  • 您是否尝试过我链接的问题中的其他建议? @crb 的答案似乎与您的问题有关。
  • 嗨,尼古拉,谢谢!至少到目前为止我已经取得了一点进展。我还没有看到 crb 的建议,现在我运行了进程监视器,发现令人惊讶的是该服务似乎正在查找并读取正确的 tnsnames.ora 文件。因此,该服务肯定存在应用程序没有的其他问题。我将发布来自进程监视器的相关 linces,显示该服务已成功读取 tnsnames.ora 文件。谢谢
  • 我也有同样的问题.. 我无法扩展我的连接字符串stackoverflow.com/questions/53889794/…
【解决方案2】:

它可能找不到 tnsnames.ora 文件。确保在启动服务时设置相同的环境变量。

【讨论】:

  • 感谢您的意见。只是为了检查并确保我将 TNS_ADMIN 环境变量添加到系统变量并将其指向 orahome 目录并重新启动服务。据我所知,这应该确保服务可以找到 tnsnames.ora 文件,但我仍然得到同样的错误。
  • 我也有同样的问题。我更新了我的 TNS_ADMIN 环境变量,并确保那里有 tnsnames.ora 文件。 stackoverflow.com/questions/53889794/…
【解决方案3】:

确保服务帐户有权读取 tnsnames.ora 文件。 同样在 sqlnet.ora 中尝试从 SQLNET.AUTHENTICATION_SERVICES 中删除 NTS(如果存在)。

如果您仍在苦苦挣扎,请尝试使用 ezconnect 一起绕过 tns 名称 例如://ip.of.server/sid

http://www.orafaq.com/wiki/EZCONNECT

【讨论】:

  • 我已经尝试过 ezconnect,但无论是应用程序还是服务都无法让它工作,所以我必须更好地理解它。但是,即使它有效,我也无法使用它,因为这是用户定义的 oracle 连接,所以我只需要连接一个 dsn。
  • 我假设 DSN=o1 是您计算机上定义的 odbc 连接。当您在“TNS 服务名称”中编辑 odbc 连接时,用 //ip.addr/SID 替换您当前拥有的任何内容,其中 ip.addr 是您的 oracle 机器的 ip,SID 是 oracle 实例的 SID 或数据库名称。跨度>
  • 还要确保您的 sqlnet.ora 文件中包含以下内容/跨度>
【解决方案4】:

John C:我觉得有几件事很奇怪。希望我没有误解您的回复。

在其中一个回复的连接字符串中,您收到有关缺少驱动程序的错误。要解决此问题,您将不得不提及提供程序/驱动程序,因为您使用的是 OdbcConnection 而不是 OracleConnection。大多数人会使用的 OracleConnection 将隐式指向驱动程序。我假设您需要为跨数据库工作提供服务,因此需要 OdbcConnection。 website 提供了很多连接字符串的示例,我认为您应该找到适合的内容。

建议你试试

驱动程序={Microsoft ODBC for Oracle};CONNECTSTRING=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=server)(PORT=7001))(CONNECT_DATA=(SERVICE_NAME=myDb)));Uid=myUsername;Pwd=myPassword;

另一件事是您的 TNS_ADMIN 变量指向的位置。您提到您指向 OraHome。我只是想确认您将变量指向 OraHome 中的 NETWORK \ ADMIN 文件夹。我相信您必须指向文件所在的文件夹。

最后,我建议您尝试从原始帖子中的连接字符串中取出一些参数。它将减少可能影响结果的变量,使其更易于调试。并将为用户配置的环境变量作为系统环境变量。也许您的 winforms 应用程序工作的原因是因为为用户定义了一个变量。我怀疑windows服务可能只使用系统变量。

驱动程序={Oracle 中 OraHome92};Server=myServerAddress;Dbq=myDataBase;Uid=myUsername;Pwd=myPassword;

【讨论】:

  • 谢谢 akhliss,我已尝试简化连接字符串,但仍然无法正常工作。我不会花太多时间直接尝试包含服务器 ip 的连接字符串,因为这对我们的应用程序没有帮助,因为我们不知道服务器 ip(请参阅问题的更新)。感谢您的努力,并欢迎您提出任何其他建议。
【解决方案5】:

好的,我将在这里回答我自己的问题,只是为了将最终解决方案与导致我提出的有用建议区分开来。 Nicola 引用的帖子(我仔细阅读后)原来有答案。我的服务是从 Program Files(x86) 运行的,并且 oracle 驱动程序无法处理调用应用程序路径中的 ( )。
我将我的服务移至 D:\ServiceTest 并且工作正常。 我现在的问题是,我认为我们的应用程序无法从 Program Files (x86) 中移出。
谢谢大家的帮助,我感谢大家的意见,但我将不得不向 Nicola 提供赏金,因为他将我指向包含答案的帖子。 再次感谢您的所有帮助

【讨论】:

    【解决方案6】:

    验证 TNS 名称定义在 tnsnames.ora 中的名称前没有空格

    【讨论】:

      【解决方案7】:

      我已经解决了这个问题。

      我的数据库密码中有一个“@”字符。在我更改密码并删除该字符后,问题已解决,导出操作已成功完成。

      This link 有助于解决问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-15
        • 2021-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        • 1970-01-01
        相关资源
        最近更新 更多