解決 ASP.NET 跑在 x64 機器上無法連接 Oracle DB 的問題

分享到噗浪!

今天又解決一個十分棘手的問題,我們有個專案原本在 x86 機器上開發 ( 資料庫採用 Oracle ),最近由於主機升級到 Windows 7 (x64) 後發現程式出問題,當在 Visual Studio 中按下 F5 進行測試除錯時完全無法連接到資料庫,而且一整個很沒道理,看看我如何解決這個棘手的問題吧。

我遇到的錯誤如下:

ORA-12154: TNS: 無法解析指定的連線 ID
ORA-12154:TNS:could not resolve service name

錯誤發生點是在「建立連線」的程式碼,只要 Open Connection 就會立即出錯。

這問題首先是出在我同事的身上,他主機在一個多月前換成 Windows Server 2008 (x64),而我是最近才換到 Windows 7 (x64),問題跟他一模一樣,因此也花了好多時間研究分析,直到剛剛跟黑大討論一番後終於給我找出解法。

先說說我電腦的安裝步驟與執行環境:

  • 安裝 Oracle Database 10g Client Release 2 (10.2.0.1.0) for Microsoft Windows (32-bit)
  • 設定 TNSNAMES.ORA 設定檔 ( 100% 肯定設定沒問題 )
  • 使用 SQL Plus 可以正常連線
  • 使用 SQL Developer 可以正常連線
  • 在 Visual Studio 中可以建置(Build)專案,建置/編譯後的組件部署到測試機也都沒問題
  • 在 Visual Studio 中使用內建的 ASP.NET 開發伺服器進行測試
  • 利用 Process Explorer 查看 WebDev.WebServer.EXE 程式,載入的組件都沒問題 (正確載入)
  • 利用 Prcoess Monitor 查看 WebDev.WebServer.EXE 程式,載入的 Oracle Client 相關參數檔路徑也都正確無誤

想破頭無法解決時,黑大建議我用最簡單的方式測試資料庫連線 (如下範例),雖然我自己已經測試數十遍了,但我還是不鐵齒,聽話的再測一次 ( 魔鬼總在細節裡 ):

using (OracleConnection cn = new OracleConnection(
    "Data Source=MyName;" +
    "Persist Security Info=True;" + 
    "User ID=user;" +
    "Password=pass"))
{
    cn.Open(); // 在此發生【 ORA-12154: TNS: 無法解析指定的連線 ID 】的錯誤
}

這時我才想到將 TNSNAME 的完整定義移到這裡試試看,請看如下範例:

using (OracleConnection cn = new OracleConnection(
    "Data Source=" +
    "  (DESCRIPTION =" +
    "    (ADDRESS_LIST =" +
    "      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.245)(PORT = 1521))" +
    "    )" +
    "    (CONNECT_DATA =" +
    "      (SERVICE_NAME = MyName)" +
    "    )" +
    "  )" +
    ";Persist Security Info=True;User ID=user;Password=pass"))
{
    cn.Open(); // 在此時發生【 ORA-6413: 連線未被開啟 】的錯誤
}

這就神奇啦,錯誤訊息竟然不一樣,,中英文錯誤訊息如下:

ORA-6413: 連線未被開啟
ORA-06413: Connection not open

多一條錯誤訊息就多一條線索,對追 Code 絕對有幫助。 ( 好像在玩偵探遊戲一樣 ^^ )

這時就被我搜出一篇文章 ORA-06413: Connection not open. 答案就在其中,原來錯誤發生的原因原來是我的 ASP.NET 開發伺服器 ( WebDev.WebServer.EXE ) 執行檔的路徑有特殊字元導致:

C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.EXE

就是這該死的 (x86) 出現在路徑中,導致我的 ASP.NET 怎樣都無法連線到程式,為了驗證確定就是這問題,我試著利用 Process Explorer 找出 WebDev.WebServer.EXE 的啟動參數:

 利用 Process Explorer 找出 WebDev.WebServer.EXE 的啟動參數

並重新透過 cmd.exe (命令提示字元) 啟動 WebDev.WebServer.EXE,這時故意用「短目錄」啟動 ASP.NET 開發伺服器,如下指令:

"C:\PROGRA~2\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.EX
E"  /port:5970 /path:"D:\XXXX\XXX\Website" /vpath:"/"

神奇的事這就樣發生,Oracle 資料庫竟然真的連上了!!

我的解決之道

  1. 改用 Windows 7 內建的 IIS7 進行網站執行與偵錯,不用 ASP.NET 開發伺服器了。Windows 7 內建的 IIS7 可新增多個網站,管理上也頗方便,不像 Windows XP 只能新增一個網站
  2. 改用 Visual Studio 巨集啟動 ASP.NET 開發伺服器偵錯,細節可參考我的另一篇文章:啟動 ASP.NET 偵錯模式的另一種比按下 F5 還快的方式

本次除錯心得

  • 不要鐵齒,越覺得不可能發生的地方越有可能是破案的核心關鍵!
  • 找個人聊聊你所遇到的錯誤,在互動、對話的過程中也許會想到一些你不曾想到的地方。
  • 「程式除錯」不但要有「經驗」更要有「創意」,當你擁有更多的「生活體驗」(程設的生活),相對的創意也就越多。
  • 熟悉多種除錯工具,並在工具間交互比對、驗證錯誤,一定可以看出一些端倪,但不要只是會「用」工具而已,而是要熟悉工具「背後的原理」,這樣才有助於你思考問題的本質問題背後的問題

相關連結

  

此文章由 will 發表於 2009/8/31 下午 04:48:53

永久連結 | 評論 (5) | 此文章的RSSRSS comment feed |

分類: ASP.NET | Oracle | Visual Studio

標籤: , , ,

評論

八月 31. 2009 17:22

ronald

本篇被其他人搜尋的關鍵字是...「無法解析指定的連線 ID」

能精準的破案真的是太屌了!!

ronald 台灣

三月 29. 2010 15:23

alex

大大您好~
個人也遇到一個奇怪的類似問題,暫時還沒有解決。

我們有一個極小的網站,使用ASP.net開發,以前在Windows 7 x86 的IIS上跑得很好,後來換了Windows 7 x64悲劇就發生了,這個網站從此不讓使用者登入(Login後會自動轉址回首頁)。因為程式不是我們開發的,暫時還沒有從程式的角度看問題。我們已經設定允許這個web application跑32位元,依舊無法解決問題。這系統是使用Acccess資料庫,讀取資料是正常的,因為無法登入,所以無法測試寫入是否正常。但是NTFS上的設定已經正確的設定為該application pool的虛擬用戶,並賦予讀寫權限。

我以前自己有相關的經驗,就是用.net開發的程式,在x86跑得很好,在x64就不能跑!後來才查出來,"64位元程式無法呼叫32位元程式!",我不確定我的觀念是否正確,這是觀察到的結果,逼得我只要有呼叫COM元件的程式,一慮設定為限制CPU x86執行。

alex 台灣

三月 29. 2010 18:21

Will 保哥

alex: 呼叫 COM 的程式除非該 COM 元件支援 x64 否則你的 .NET 應用程式就必須以 x86 來跑才行!

Will 保哥 台灣

三月 30. 2010 13:47

jing

will大
  我現在遇到的問題跟您提的很像,不過我是連結teradata使用odbc
  同樣無法連結資料庫,路徑中也有x86的字樣
  不過我有點看不太懂您的解決方法..(抱歉 我接觸還不久 >"<)

  想請問您,除了使用Process Explorer 還有什麼方法可以找啟動參數嗎??

jing 台灣

五月 6. 2010 13:50

kevin.wu

我的环境和楼主您的一样,使用IIS7部署同样连接不上。MSN:wuliangbo@gmail.com

kevin.wu 中華人民共和國

新增評論


( 您輸入的Email不會顯示於網站上 )

  Country flag

biuquote
  • 評論
  • 線上預覽
Loading