在連接數據庫的時候,有時會遇到一個“ORA12514:監聽程序當前無法識別連接描述符中請求的服務”的錯誤,這個錯誤其實就是數據庫動態注冊(關於動態注冊會在稍后講解)不生效,導致監聽器無法識別客戶端連接符中提供的服務名,從而拒絕建立數據庫連接時報的錯誤信息,所以就需要對監聽器配置做修改。
在這里,還需對問題進行細化,有時候可能會發現,在剛開啟監聽器的時候會發生這個錯誤,但過了一會再進行連接就不會報錯,這其實是因為動態注冊需要時間,而剛開啟監聽器時,數據庫還未注冊到監聽器,導致報錯,這種情況不在本文討論范圍內。
listener.ora文件存放在$ORACLE_HOME/network/admin(以我的Oracle11為例就是D:\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN),這個文件存放的就是監聽器的配置,監聽器在啟動時會讀取該文件,我們先來了解一下這個文件。
該文件的大概配置如下圖
上圖中,SID_LIST_LISTENER參數就是數據庫注冊,動態注冊或是靜態注冊(注冊就是將數據庫作為一個服務注冊到監聽器。客戶端不需要知道數據庫名和實例名,只需要知道該數據庫對外提供的服務名就可以申請連接到數據庫,動態注冊就是在監聽器配置文件中不明確的聲明數據庫實例和服務名,而是在數據庫啟動時才由數據庫自動注冊到監聽器,靜態注冊就是在監聽器配置文件中明確聲明數據庫實例和服務名。),LISTENER參數就是監聽器的配置,其中,PROTOCOL參數是協議名,一般為TCP,HOST參數是地址,可以寫IP地址、服務器名、localhost、127.0.0.1,PORT參數是端口號,默認為1521。
既然是因為動態注冊引起的問題,那么最簡單的解決方法自然是由動態注冊改為靜態注冊,如下圖
紅線框內的就是靜態注冊,SID_NAME參數是數據庫實例名,GLOBAL_DBNAME參數是全局數據庫名(在配置客戶端的本地服務名時“服務名”要與全局數據庫名一致),配置好后,重啟監聽器,就可正常連接了。
修改為靜態注冊看起來雖簡單,但也有不足之處,首先,要修改為靜態注冊需對配置文件和參數較為熟悉,否則很有可能會配置錯誤,其次當參數的值有所改變時必須重新修改配置才行。
還有一種方法就是修改host參數的值,host參數可以有四種值:IP地址、服務器名、localhost、127.0.0.1,由於可取值變多了,導致了解決辦法也隨着導致出現問題的原因而多樣化了起來,各種情況都可能有不同的解決辦法,可以在這四個值之間嘗試修改,需要注意的是,當采用localhost和127.0.0.1時,客戶端的本地服務名不能使用IP地址和服務器名進行配置,否則會報“ORA12541:無監聽程序”的錯誤,還有就是修改之后要重啟監聽器。
以上的解決辦法只是我自己對這個錯誤的總結,可能尚無法解決所有的情況,歡迎進行討論。