- 在使用eclipse编译器,编写java的jdbc连接Oracle数据库的时候经常会出现连接异常的情况,出现错误为
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
- 大致意思是监听器无法找到描述的SID,奇怪的是这个时候我使用cmd或者是sqlplus却可以正常连接数据库,而且反复确认过我的驱动类,连接路径,用户名和密码都没有问题,可是使用java程序连接的时候就会出现这个问题
- 以下是我的jdbc源码
package mao.shu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class OracleLJDBC {
//定义oracle数据库的加载程序类
private static final String DRIVER_ORACLE="oracle.jdbc.driver.OracleDriver";
//定义jdbc的连接地址
private static final String DBURL_ORACLE="jdbc:oracle:thin:@localhost:1521:mldn";
//定义oracle数据库的用户名
private static final String USER = "scott";
//定义连接用户的密码
private static final String PASSWORD="tiger";
public static void main(String args[])throws Exception{
//加载数据库驱动程序类
Class.forName(DRIVER_ORACLE);
//通过DriverManager类得到数据库连接对象
Connection conn = DriverManager.getConnection(DBURL_ORACLE, USER, PASSWORD);
//定义sql查询语句
String sql =" SELECT empno,ename,job "
+" FROM( "
+" SELECT empno,ename,job,ROWNUM rn FROM emp WHERE ROWNUM <= ? "
+" )temp "
+"WHERE temp.rn > ?";
PreparedStatement psd = conn.prepareStatement(sql);
int currentPage = 1;
int linesize = 5;
psd.setInt(1, currentPage*linesize);
psd.setInt(2, (currentPage-1)*linesize);
ResultSet rest = psd.executeQuery();
while(rest.next()){
System.out.println(rest.getInt(1)+" "+rest.getString(2)+" "+rest.getString(3));
}
//关闭数据库连接
conn.close();
}
}
- 出现的异常
解决方法
- 后来通过百度,查看别人的经验后得知,原来sqlplus连接的时候使用的是service_name,而程序连接的时候使用的是sid_name.
- 之所以会出现以上的错误,是因为程序找不到所给的sid名称,而要控制这个sid名称需要修改Oracle安装目录下的listener.ora文件配置
- 我的listener.ora文件目录是:D:\Datebase\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora
- 使用记事本打开后listener.ora文件内容如下
# listener.ora Network Configuration File: D:\Datebase\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = D:\Datebase\Oracle\product\11.2.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:D:\Datebase\Oracle\product\11.2.0\dbhome_1\bin\oraclr11.dll")
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
)
ADR_BASE_LISTENER = D:\Datebase\Oracle
- 可以发现在SID_LIST中没有我在程序中使用的sid名称,所以需要我们添加上去,在SID_LIST内容中添加一下内容(每个人的Oracle_home和不一样,要注意()分割)
(SID_DESC =
(GLOBAL_DBNAME = mldn)
(ORACLE_HOME = D:\Datebase\Oracle\product\11.2.0\dbhome_1)
(SID_NAME = mldn)
)
- 修改后的listener.ora文件内容
# listener.ora Network Configuration File: D:\Datebase\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = D:\Datebase\Oracle\product\11.2.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:D:\Datebase\Oracle\product\11.2.0\dbhome_1\bin\oraclr11.dll")
)
(SID_DESC =
(GLOBAL_DBNAME = mldn)
(ORACLE_HOME = D:\Datebase\Oracle\product\11.2.0\dbhome_1)
(SID_NAME = mldn)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
)
ADR_BASE_LISTENER = D:\Datebase\Oracle
-
修改之后,需要重新启动Oracle的监听服务
-
再重新运行一遍程序
Oracle的jdbc其他连接格式
- jdbc连接Oracle一共有三种格式
格式一:jdbc:oracle:thin:@//<host>:<port>/<service_name>
格式二:jdbc:oracle:thin:@<host>:<port>:<SID>
格式三:jdbc:oracle:thin:@<TNSName>
- 之前我都是使用第二种方式连接的,其实Oracle在Oracle8之后推出了service_name就是为了简化客户端连接的问题,我们完全可以使用第一种格式进行连接会更加的方便
- 所以我的url格式应该改为
jdbc:oracle:thin:@localhost:1521/mldn
如何查看Oracle中的service_name
- 使用Oracle的匿名用户sysdba登录sqlplus
- 使用以下命令可以查看
show parameter service;
- 在Oracle的安装目录之下 \product\11.2.0\dbhome_1\NETWORK\ADMIN\ 查看tnsnames.ora文件中可以查看
- tasnames.ora文件内容
# tnsnames.ora Network Configuration File: D:\Datebase\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.
MLDN =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.104)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = mldn)
)
)
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
如何查看Oracle的sid
- 使用Oracle中的匿名用户 sysdba,而后使用以下sql语句可以查看现在Oracle中的sid
select name from V$database;
- 查看Oracle的实例名称
select instance_name from V$instance;