问题:JDBC连接Oracle出现问题:ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
解决过程
本人在本机上使用JDBC连接服务器上的Oracle数据库,总是出现错误。在网上搜索原因以为是需要安装Oracle,修改 listener.ora文件,但是Navicat是可以连接的啊。断点调试,DriverManager.getConnection()的参数url是jdbc:oracle:thin:@127.0.0.1:1521:**
,“**”位置是数据库名称呢还是SID名称呢?网上说是数据库名称,可是自己传的也是数据库名,依然会出错,什么原因呢?
错误提示SID未知,DriverManager.getConnection()连接数据库时并没有传入这个参数,但是Navicat在连接数据库时是需要这个参数的,没有用过Oracle的我对这个参数很有疑问。于是把“**”处换成SID名称还真就可以成功连接了。
至于SID和数据库名什么区别呢?
SID即INSTANCE_NAME是用来唯一标示实例的。实例是操作系统中访问数据库所需要的一系列的进程和内存的集合,是数据库对外连接使用。数据库是文件。一个实例只能对应一个数据库,一个数据库可以对应多个实例。
拓展
1、JDBC连接ORACLE的方法有三种:
格式一:jdbc:oracle:thin:@//<host>:<port>/<service_name>
格式二:jdbc:oracle:thin:@<host>:<port>:<SID>
格式三:jdbc:oracle:thin:@<TNSName>
SERVICE_NAME是oracle8i新引进的。是因为后来一个数据库可以由多个实例对应,SID已经无法满足需要,所以提出SERVICE_NAME概念。
2、完整的JDBC连接Oracle示例:
/**
* “添加外部Jar”,选择“\ojdbc6_g.jar”
* JDBC连接Oracle数据库的示例代码
*/
public void testOracle()
{
Connection con = null;// 创建一个数据库连接
PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
ResultSet result = null;// 创建一个结果集对象
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
String url = "jdbc:oracle:" + "thin:@127.0.0.1:1521:XE";// 127.0.0.1是本机地址,XE是Oracle的SID
String user = "root";// 用户名,系统默认的账户名
String password = "123";// 你安装时选设置的密码
con = DriverManager.getConnection(url, user, password);// 获取连接
if(con!=null){
System.out.println("连接成功!");
}
String sql = "select * from worker where name=?";// 预编译语句,“?”代表参数
pre = con.prepareStatement(sql);// 实例化预编译语句
pre.setString(1, "高工");// 设置参数,前面的1表示参数的索引,而不是表中列名的索引
result = pre.executeQuery();// 执行查询,注意括号中不需要再加参数
while (result.next())
// 当结果集不为空时
System.out.println("工号:" + result.getInt("id") + "姓名:"
+ result.getString("name"));
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
// 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
// 注意关闭的顺序,最后使用的最先关闭
if (result != null)
result.close();
if (pre != null)
pre.close();
if (con != null)
con.close();
System.out.println("数据库连接已关闭!");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}