ORA-12514 TNS:监听器当前不知道连接描述符中请求的服务

我们有一个本地运行的应用程序,我们遇到了以下错误:

ORA-12514: TNS:监听器当前不知道所请求的服务 在连接描述符

我已经测试了使用TNSPing正确解决的连接 我尝试SQLPlus尝试连接,失败了,错误与上面相同。我对SQLPlus使用了这个语法:

sqlplus username/password@addressname[or host name]

我们已核实:

  • 服务器上的TNS Listener正在运行。
  • 服务器上的Oracle本身正在运行。

我们不知道这个环境有任何改变。 还有什么可以测试的吗?< / p >

1863067 次浏览

检查数据库是否启动。登录到服务器,将ORACLE_SID环境变量设置为您的数据库SID,并作为本地连接运行SQL*Plus。

当应用程序为每个数据库交互建立新连接或连接未正确关闭时,可能会发生此错误。监视和确认这一点的免费工具之一是Oracle Sql developer(尽管这不是您可以用来监视DB会话的唯一工具)。

你可以从oracle网站Sql开发人员下载这个工具

下面是如何监控你的会话的截图。(如果您在看到ORA-12514错误时看到应用程序用户堆积了许多会话,那么这很好地表明您可能有连接池问题)。

enter image description here

我遇到了这个问题,修复是确保在tnsnames.oraSERVICE_NAME是数据库中的有效服务名称。要找出有效的服务名称,您可以在oracle中使用以下查询:

select value from v$parameter where name='service_names'

一旦我将tnsnames.ora更新为:

TEST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = *<validhost>*)(PORT = *<validport>*))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = *<servicenamefromDB>*)
)
)

然后我就跑:

sqlplus user@TEST
< p >成功! 监听器基本上是在告诉你,不管你使用的是什么service_name,根据DB,都不是一个有效的服务。< / p >

(*我从Win7客户端工作站运行sqlplus到远程DB,责怪dba;) *)

我在Windows server 2008 R2Oracle 11 g有这个问题

进入网络管理器>监听>从组合框中选择数据库服务>“全局数据库名称”必须与“SID”相同,“Oracle主目录”必须正确。

如果你没有任何数据库服务的条目,创建一个并设置正确的全局数据库,sid和oracle home。

我知道这是一个老问题,但仍然没有答案。我花了一天的时间研究,但我找到了最简单的解决方案,至少在我的情况下(Windows 2008 R2上的Oracle 11.2),我想分享。

如果直接查看该错误,则表明侦听器不识别服务名称。但是它把服务名保存在哪里呢?在%ORACLE_HOME%\NETWORK\ADMIN\listener.ora

“SID_LIST”就是一个sid和服务名的列表,它们以一种可以复制或查找的格式配对。

我添加了问题服务名称,然后在Windows“服务”控制面板中,我对Oracle侦听器服务进行了“重新启动”。现在一切都好了。


例如,你的听众。Ora文件最初可能是这样的:

# listener.ora Network Configuration File: C:\app\oracle_user\product\12.1.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.


SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = C:\app\oracle_user\product\12.1.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:C:\app\oracle_user\product\12.1.0\dbhome_1\bin\oraclr12.dll")
)
)


LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)

... 为了让它识别orcl的服务名,你可以将其更改为:

# listener.ora Network Configuration File: C:\app\oracle_user\product\12.1.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.


SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = C:\app\oracle_user\product\12.1.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:C:\app\oracle_user\product\12.1.0\dbhome_1\bin\oraclr12.dll")
)
(SID_DESC =
(GLOBAL_DBNAME = orcl)
(ORACLE_HOME = C:\app\oracle_user\product\12.1.0\dbhome_1)
(SID_NAME = orcl)
)
)


LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)

在我的例子中,数据库已经耗尽了磁盘空间。这导致它没有反应。一旦我解决了这个问题,一切都恢复正常了。

我也遇到过同样的问题,花了3天时间才把它挖出来。

发生这种情况是因为您错误的TNS服务条目。

首先检查是否能够使用sql > sqlplus sys@orastand as sysdba从主数据库连接到备用数据库(orastand是一个备用数据库)。

如果您无法连接,那么这是与服务的问题。更正主端TNS文件中服务名称的填写。

用同样的方法检查备用数据库。如果需要,也可以在这里进行更改。

确保log_archive_dest_2参数具有正确的服务名称。

我解决了这个问题在我的linux环境更新我的机器的IP在/etc/hosts文件。

您可以验证您的网络IP (inet end.):

$ifconfig

查看您的IP是否与/etc/hosts文件匹配:

$cat /etc/hosts

如果需要,编辑/etc/hosts文件:

$sudo gedit /etc/hosts

再见。

我也有同样的问题。对我来说,就是写作

sqlplus myusername/mypassword@localhost

这样做使它连接到默认的服务名,我猜。

从服务启动OracleServiceXXX。我在Windows系统下使用msc。

对于那些可能在虚拟机中运行Oracle的人(比如我),我看到这个问题是因为我的虚拟机内存不足,这似乎阻止了OracleDB正确启动/运行。增加我的虚拟机内存和重新启动修复了这个问题。

对我来说很简单,我只需要在“Windows服务”中手动启动服务。MSC在CMD trompt)。 我的服务名称是:OracleServiceXXXXX。< / p >

对我来说,这是由于使用动态ipaddress安装造成的。我用一个静态ipaddress重新安装了Oracle,然后一切都好了

这真的应该是对Brad Rippe[1]的回答的一个评论,但是,唉,没有足够的代表性。这个回答让我走了90%的路。在我的例子中,数据库的安装和配置将条目放在tnsnames中。ora文件用于我正在运行的数据库。首先,我能够通过设置环境变量(Windows)连接到数据库:

set ORACLE_SID=mydatabase
set ORACLE_HOME=C:\Oracle\product\11.2.0\dbhome_1

然后连接使用

sqlplus / as sysdba

接下来,运行Brad Rippe回答的命令:

select value from v$parameter where name='service_names';

说明名字并不完全匹配。使用Oracle的数据库配置助手创建的条目最初是:

MYDATABASE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = mylaptop.mydomain.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = mydatabase.mydomain.com)
)
)

查询中的服务名称只是mydatabase而不是mydatabase.mydomain.com。我编辑了tnsnames。Ora文件只有基本名称,没有域名部分,所以它们看起来像这样:

MYDATABASE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = mylaptop.mydomain.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = mydatabase)
)
)
我重新启动了TNS监听器服务(我经常从管理员命令窗口[或Windows Powershell]使用lsnrctl stoplsnrctl start而不是服务控制面板,但两者都有效。)在那之后,我能够与人沟通。 [1]: https://stackoverflow.com/users/979521/brad-rippe < / p >

这里有很多答案,但这里有一个工作示例的代码,你可以立即复制、粘贴和测试:

对我来说,在指定正确的SERVICE_NAME后,错误12514得到了解决。 你会在服务器上的tnsnames.ora文件中发现它带有3个预定义的服务名称(其中一个是“XE”)
  1. 我安装了Oracle Express数据库OracleXE112,它已经附带了一些预安装的演示表。
  2. 当您启动安装程序时,系统会要求您输入密码。我输入了“xxx”作为密码。(不用于生产)
  3. 我的服务器运行在机器192.168.1.158上
  4. 在服务器上,必须显式地允许访问Windows防火墙中的TNSLSNR.exe进程。该进程监听端口1521。
  5. 选项一: For c#(。NET2或. net4),你可以下载ODAC11,从中你必须添加Oracle.DataAccess.dll到你的项目。此外,此DLL依赖于:OraOps11w.dll, oci.dll, oraociei11.dll (130MB!), msvcr80.dll。 这些DLL必须与EXE在同一目录中,或者必须在:HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.112.4.0\DllPath中指定DLL路径。在64位机器上,追加写入HKLM\SOFTWARE\Wow6432Node\Oracle\...
  6. 如果你已经下载了ODAC12,你需要Oracle.DataAccess.dll, OraOps12w.dll, oci.dll, oraociei12.dll (160MB!), oraon .dll, msvcr100.dll。注册表路径为HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.121.2.0\DllPath
  7. 选择C:如果你不想要超过100 MB的巨大DLL,你应该下载ODP.NET_Managed12.x.x.x.xxxxx.zip,在其中你会发现Oracle.ManagedDataAccess.dll只有4 MB,是一个纯托管DLL,它可以在32位和64位进程中工作,不依赖于其他DLL,不需要任何注册表项。
  8. 以下c#代码适用于我,无需在服务器端进行任何配置(只是默认安装):
using Oracle.DataAccess.Client;
or
using Oracle.ManagedDataAccess.Client;


....


string oradb = "Data Source=(DESCRIPTION="
+ "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.158)(PORT=1521)))"
+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)));"
+ "User Id=SYSTEM;Password=xxx;";


using (OracleConnection conn = new OracleConnection(oradb))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand())
{
cmd.Connection  = conn;
cmd.CommandText = "select TABLESPACE_NAME from DBA_DATA_FILES";


using (OracleDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
listBox.Items.Add(dr["TABLESPACE_NAME"]);
}
}
}
}

如果SERVICE_NAME=XE是错误的,你会得到错误12514。SERVICE_NAME是可选的。你也可以把它放在一边。

在我的情况下,错误是由于监听器没有注册db的服务。我通过注册服务解决了这个问题。例子:

我在tnsnames.ora中的描述符:

LOCALDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = LOCALDB)
)
)

因此,我继续手动在listener.ora中注册服务:

SID_LIST_LISTENER =
(SID_DESC =
(GLOBAL_DBNAME = LOCALDB)
(ORACLE_HOME = C:\Oracle\product\11.2.0\dbhome_1)
(SID_NAME = LOCALDB)
)

最后,通过命令重新启动监听器:

> lsnrctl stop
> lsnrctl start

完成了!

我得到了同样的错误,因为指定的远程SID是错误的:

 > sqlplus $DATASOURCE_USERNAME/$DATASOURCE_PASSWORD@$DB_SERVER_URL/$REMOTE_SID

我查询了系统数据库:

Select * from global_name;

找到了我的远程SID(“XE”)。

这样我就可以毫无问题地连接了。

我已经实现了下面的解决方法来解决这个问题。

  1. 已使用命令提示符设置ORACLE_HOME (右键单击cmd.exe,并以系统管理员身份运行).

  2. .exe
  3. 用于以下命令

    set oracle_home="path to the oracle home" < / p >

  4. 进入所有程序——> Oracle -ora home1——> 配置迁移工具——> Net Manager——> Listener

  5. 在下拉框中选择“数据库服务”。 全局数据库名和SID都设置为相同(在我的例子中是ORCL)。 设置Oracle主目录

Oracle Net Manager窗口示例从Oracle文档: Oracle Net Manager example < / p >

  1. 单击File并保存网络配置。

重启虚拟机对我有用

我的问题解决了,用“服务名称”和正确的主机替换URL中的“sid”。

tnslsnr是up,但数据库是down。

对于oracle新手来说,当连接被接受时,数据库可能会关闭是不明显的。

我必须手动启动数据库

su - oracle
export ORACLE_SID=XE
sqlplus sys as sysdba

然后在sql console中

startup

在我的情况下,我启动失败,但得到了另一个错误消息,并发现了一个问题的来源-我必须改变主机名,然后数据库自动启动再次发挥作用。

问题是我的连接字符串url包含数据库名称而不是SID。 将数据库名称替换为oracle数据库连接SID即可解决此问题

要知道你的oracle SID,你可以浏览tnsnames.ora文件。

XE是实际的SID,所以这是我的tomcat连接字符串现在看起来的样子:

    <Resource
name="jdbc/my_db_conn"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@//127.0.0.1:1521/XE"
username="test_user"
password="test" />

我的服务器版本是“Oracle 11.2 Express”,但解决方案应该也适用于其他版本。

在我的例子中,tnsnames.ora文件中缺少SERVICE_NAME周围的圆括号。

<DBNAME> =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL=TCP)(HOST = nupark-cnvr-ora )(PORT=1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = <DBNAME> ***CLOSING ROUND BRACKET WAS MISSING HERE***
)
)


LISTENER_<DBNAME> =


(ADDRESS = (PROTOCOL = TCP)(HOST = nupark-cnvr-ora)(PORT = 1521))

对于使用spring-boot和jdbc进行连接的用户。 在应用程序中编写jdbcUrl时必须小心。< / p >属性

与SID在数据库连接- source.datasource.jdbcUrl = jdbc:oracle:thin:@[HOST][:PORT]:SID < / p >

服务名称在db连接 globe.datasource.jdbcUrl = jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE < / p >

这对我很有用:)

我有一个案例,我使用DBMS,我必须完成一个数据库连接表单。

我把SID放入数据库字段,在下拉框中,在字段旁边,我有“服务名称”值而不是“SID”值。
(通常我不使用Oracle数据库,所以我没有意识到差异)

这就是我得到错误消息的原因。

问题可能在于不正确的URL。

例如,我正在使用Oracle数据库(在VM内部)与Spring框架,并有这个问题。

在我的申请中。属性文件:

spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/orcl12c

但是db版本是不同的:

spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/orclcdb
正确的URL可以在tnsnames.ora文件中找到(这个文件可以在Oracle服务器中找到,所以如果你使用VM,你应该在你的主机VM中寻找这个文件)。 例如,对于VirtualBox中的Oracle,查看该文件的命令是:

nano /u01/app/oracle/product/version/db_1/network/admin/tnsnames.ora
在我的Linux环境的例子中,ORACLE_HOME/bin的oracle文件在"红色的"中突出显示;不同权限的颜色如下:
enter image description here < / p >

我修改了这个文件的权限如下:

1)停止Oracle ->sudo systemctl stop oracle.service
2)修改oracle文件在ORACLE_HOME/bin目录下的权限为“Sudo chmod 777 oracle"
3)启动Oracle ->sudo systemctl start oracle.service

然后在这个更改之后,我使用lsnrctl状态检查侦听器的状态。在这里,我可以看到db实例成功加载。

然而,我只能使用sqldeveloper连接,使用sqlplus命令行,我得到ORA-12547: TNS Lost Contact错误。因此,这可以快速解决方案使用sqldeveloper。

注意:修改权限前备份oracle文件。

对于Dbeaver用户:尝试选择"SID"而不是“服务名称”;在连接设置中。

我只需要替换我的连接字符串

来自:

jdbc:oracle:thin:@localhost:1521:xe

:

jdbc:oracle:thin:@localhost:1521:orcl