用 sqlplus 程序通过 test.testserver.com 网络服务名测试,如sqlplus system/manager@test.testserver.com。
关于为什们在网络服务名后面加 db_domain 参数,需要了解 sql*plus 连接数据库的原理,我在后面解决12154常见故障中给出了详细的说明。
如果上面的招数还不奏效的话,只好用一下乾坤大挪移了。
将客户端的网络服务名部分
test.testserver.com = (DESCRIPTION= (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com) ) ) |
拷贝到服务器的 tnsnames.ora 文件中。然后再服务器端用 sqlplus system/manager@test.testserver.com 连接到数据库。
如果能连接成功,说明你的客户端与服务器端的网络有问题。
如果连接不成功,用前面的部分检查网络服务名部分部分是否正确,如果确信网络服务名部分正确而且所有的客户端都连不上数据库则可能为系统 TCP/IP 或 Oracle 系统有问题,建议重新安装数据库。
常见故障解决办法:
TNS-12154 (ORA-12154):TNS:could not resolve service name
该错误表示用于连接的网络服务名在 tnsnames.ora 文件中不存在,如上面的 tnsnames.ora 中的网络服务名只有test,假如用户在连接时用 sqlplus system/manager@test1 则就会给出TNS-12154错误。
要注意的是,有时即使在 tnsnames.ora 文件中有相应的网络服务名,可是用该网络服务名连接时还会出错,出现这种情况的典型配置如下(在客户端的机器上):
sqlnet.ora 文件:
NAMES.DIRECTORY_PATH = (TNSNAMES, ….) NAMES.DEFAULT_DOMAIN = server.com tnsnames.ora 文件: test = (DESCRIPTION= (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com) ) ) |
sql*plus 运行基本机理:
在用户输入 sqlplus system/manager@test 后,sqlplus 程序会自动到 sqlnet.ora 文件中找 NAMES.DEFAULT_DOMAIN 参数,假如该参数存在,则将该参数中的值取出,加到网络服务名的后面,即此例中你的输入由 sqlplus system/manager@test 自动变为 sqlplus system/manager@test.server.com ,然后再到 tnsnames.ora 文件中找 test.server.com 网络服务名,这当然找不到了,因为该文件中只有 test 网络服务名,所以报错。解决的办法就是将 sqlnet.ora 文件中的 NAMES.DEFAULT_DOMAIN 参数注释掉即可,如 #NAMES.DEFAULT_DOMAIN = server.com。假如 NAMES.DEFAULT_DOMAIN 参数不存在,则 sqlplus 程序会直接到 tnsnames.ora 文件中找 test 网络服务名,然后取出其中的 host,port,tcp,service_name,利用这些信息将连接请求发送到正确的数据库服务器上。
另外原则上 tnsnames.ora 中的配置不区分大小写,但是我的确遇到区分大小写的情况,所以最好将使用的网络服务与 tnsnames.ora 中配置的完全一样。
ORA-12514: TNS:listener could not resolve SERVICE_NAME given in connect Descriptor.
该错误表示能在 tnsnames.ora 中找到网络服务名,但是在 tnsnames.ora 中指定的 SERVICE_NAME 与服务器端的 SERVICE_NAME 不一致。解决的办法是修改 tnsnames.ora 中的 SERVICE_NAME。
易混淆术语介绍: Db_name:对一个数据库(Oracle database)的唯一标识,该数据库为第一章讲到的 Oracle database。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由 Db_name 和 Db_domain 两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将 Db_name 和 Db_domain 两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为 Global_name,即它扩展了 Db_name。Db_name 参数只能由字母、数字、’_’、’#’、’$’组成,而且最多8个字符。
Db_domain:定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。当然为了管理方便,可以将其等于互联网的域。
Global_name:对一个数据库(Oracle database)的唯一标识,Oracle建议用此种方法命名数据库。该值是在创建数据库时决定的,缺省值为 Db_name. Db_domain。在以后对参数文件中 Db_name 与 Db_domain 参数的任何修改不影响 Global_name 的值,如果要修改 Global_name,只能用 ALTER DATABASE RENAME GLOBAL_NAME TO <db_name.db_domain> 命令进行修改,然后修改相应参数。
Service_name:该参数是 Oracle8i 新引进的。在8i以前,我们用 SID 来表示标识数据库的一个实例,但是在 Oracle 的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了 Service_name 参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为 Db_name. Db_domain,即等于 Global_name。一个数据库可以对应多个 Service_name,以便实现更灵活的配置。该参数与 SID 没有直接关系,即不必 Service name 必须与 SID 一样。
Net service name:网络服务名,又可以称为数据库别名(database alias)。是客户端程序访问数据库时所需要,屏蔽了客户端如何连接到服务器端的细节,实现了数据库的位置透明的特性。
查看本文来源