Oracle使用JDBC連線資料庫異常處理
阿新 • • 發佈:2018-12-22
- 在使用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;