境準備到連接測試)
簡介本資源為Delphi與CBuilder開發(fā)者準備的ODACOracle Data Access ComponentsOracle連接控件組件庫面向需要在Windows桌面應用中高效訪問Oracle數(shù)據(jù)庫的中高級開發(fā)者。ODAC由Devart開發(fā)核心組件TOracleConnection負責建立與管理物理連接并支持連接池配套的TOracleQuery、TOracleTable、TOracleTransaction、TOracleProcedure與TOracleFunction可覆蓋查詢、數(shù)據(jù)表操作、事務控制及存儲過程調(diào)用同時兼容VCL與FireMonkey數(shù)據(jù)綁定、異步執(zhí)行和LOB、RAC、物化視圖等Oracle特性。壓縮包共1807個文件約9.7MB以pas源碼、dcu編譯單元、dfm窗體、dpk與bpl包文件為主另含dpr、cpp、sql、bat等示例與構(gòu)建腳本便于直接編譯集成。目前已有467人學習下載適合希望減少底層API依賴、快速搭建Oracle數(shù)據(jù)訪問層的開發(fā)者參考使用。1. 從一次連接超時說起Delphi ODAC 控件到底該怎么裝上周幫一個做 ERP 的老哥排查問題他的 Delphi 程序連 Oracle 一直報 ORA-12170 超時折騰了一下午最后發(fā)現(xiàn)是 ODAC 版本和 Oracle 客戶端位數(shù)對不上。這種坑我見過太多次了。Delphi 連 Oracle繞不開 ODAC 這套控件它比 BDE 穩(wěn)定、比 dbExpress 省心但安裝配置環(huán)節(jié)的坑一點不少。這篇文章面向的是正在用 Delphi 開發(fā)、需要連 Oracle 數(shù)據(jù)庫的開發(fā)者不管你是剛接觸 ODAC 的新手還是想從舊版本遷移的老手下面這套安裝流程和參數(shù)配置都能直接抄作業(yè)。我會把版本選擇、環(huán)境準備、安裝步驟、參數(shù)配置、驗證方法、常見報錯處理全部走一遍盡量讓你少走彎路。2. 裝之前先把環(huán)境理清楚ODAC 版本與 Delphi 的對應關系2.1 確認你的 Delphi 版本和 ODAC 版本匹配ODAC 不是裝一個版本就能通吃所有 Delphi 的。Devart 官方對每個 Delphi 版本都有對應的 ODAC 安裝包裝錯了要么裝不上要么裝上了 IDE 里看不到控件面板。我一般會先確認三件事Delphi 的具體版本號比如 Delphi 10.4 Sydney、Delphi 11 Alexandria、操作系統(tǒng)是 32 位還是 64 位、Oracle 客戶端裝的是哪個版本。下面這張表是我整理過的常見對應關系方便你快速定位Delphi 版本推薦 ODAC 版本對應 Oracle 客戶端Delphi 7ODAC 9.xOracle 11g 32位Delphi 2007ODAC 10.xOracle 11g 32位Delphi XE2ODAC 10.xOracle 11g/12c 32位Delphi 10.2 TokyoODAC 11.xOracle 12c 32位/64位Delphi 10.4 SydneyODAC 12.xOracle 19c 32位/64位Delphi 11 AlexandriaODAC 12.xOracle 19c/21c 32位/64位注意Delphi 7 到 Delphi 2007 之間跨度很大ODAC 9.x 和 10.x 的安裝方式也有區(qū)別老版本 Delphi 建議用 ODAC 9.x 的最后一個穩(wěn)定版。2.2 檢查 Oracle 客戶端是否就緒ODAC 本身不包含 Oracle 客戶端它依賴你機器上已經(jīng)裝好的 Oracle Instant Client 或者完整版客戶端。我一般會先檢查這幾個點第一看PATH環(huán)境變量里有沒有 Oracle 客戶端的bin目錄。沒有的話ODAC 運行時會找不到oci.dll直接報「無法加載 OCI 動態(tài)庫」。第二確認TNS_ADMIN環(huán)境變量指向的目錄下有tnsnames.ora文件。這個文件里配置了數(shù)據(jù)庫的連接描述符ODAC 靠它來解析連接字符串。第三如果你用的是 64 位 DelphiOracle 客戶端也必須是 64 位32 位 Delphi 配 32 位客戶端?;煊帽胤囘@是血淚經(jīng)驗。# 檢查 PATH 中是否包含 Oracle 客戶端路徑 echo %PATH% | findstr /i oracle # 檢查 TNS_ADMIN 是否設置 echo %TNS_ADMIN% # 查看 tnsnames.ora 內(nèi)容示例 type %TNS_ADMIN%\tnsnames.ora上面這幾條命令在 Windows 命令行里執(zhí)行能快速確認環(huán)境變量和配置文件是否到位。PATH里沒有 Oracle 路徑的話手動把instantclient_19_xx目錄加進去重啟命令行再試。2.3 下載 ODAC 安裝包的注意事項ODAC 的安裝包分兩種一種是帶源碼的完整版一種是不帶源碼的編譯版。如果你只是用控件不帶源碼的版本就夠了體積小、安裝快。但如果你需要調(diào)試進 ODAC 內(nèi)部或者要改它的源碼適配特殊需求那就得下完整版。下載的時候注意看安裝包文件名里的版本號和 Delphi 版本標識。比如odac1200d24pro.exe這種命名1200是 ODAC 版本d24代表 Delphi 10.4。下錯了裝不上別問我是怎么知道的。3. 安裝 ODAC 控件從運行安裝程序到 IDE 里看到控件面板3.1 運行安裝程序并選擇正確的 Delphi 版本雙擊安裝包之后第一步是選 Delphi 版本。這里有個細節(jié)如果你機器上裝了多個 Delphi 版本安裝程序會全部列出來你只需要勾選你要用的那個。勾多了會往每個 IDE 里都注冊一遍控件啟動速度會變慢。安裝路徑我一般不改默認裝在C:\Program Files (x86)\Devart\ODAC for Delphi XXXX下面。改路徑的話后面配置 Library Path 的時候容易忘反而麻煩。安裝過程中會問你要不要裝 Demo 項目建議勾上。Demo 里有現(xiàn)成的連接示例后面驗證的時候可以直接拿來改。3.2 配置 Delphi 的 Library Path裝完之后Delphi 的 Library Path 里必須加上 ODAC 的Lib和Bin目錄否則編譯的時候找不到單元文件。具體路徑取決于你的 Delphi 版本和 ODAC 安裝位置一般是C:\Program Files (x86)\Devart\ODAC for Delphi 11\Lib C:\Program Files (x86)\Devart\ODAC for Delphi 11\Bin在 Delphi 里依次點Tools→Options→Language→Delphi→Library在Library Path里把上面兩個路徑加進去。加完之后點OK保存重啟 Delphi 讓配置生效。// 在 uses 里加上 ODAC 的單元 uses Ora, OraCall, OraError, DBAccess, MemDS; // 一個最簡單的連接示例 procedure TForm1.ConnectOracle; var OraSession: TOraSession; begin OraSession : TOraSession.Create(nil); try OraSession.Server : 192.168.1.100:1521/orcl; OraSession.Username : scott; OraSession.Password : tiger; OraSession.Connect; ShowMessage(連接成功); except on E: Exception do ShowMessage(連接失敗 E.Message); end; end;上面這段代碼是最基礎的連接測試。Server屬性支持兩種寫法一種是IP:端口/服務名另一種是直接用tnsnames.ora里配置的別名。Username和Password就是數(shù)據(jù)庫賬號密碼。Connect方法會實際發(fā)起連接如果失敗會拋異常用try...except捕獲一下就能看到具體錯誤。3.3 注冊控件到 IDE 面板有些 ODAC 版本安裝完之后不會自動把控件注冊到 IDE 的控件面板上需要手動操作。打開 Delphi點Component→Install Packages然后Add找到 ODAC 安裝目錄下的.bpl文件比如OdacVcl.bpl或者dclodac.bpl加進去之后點OK。注冊成功后在 IDE 的控件面板上應該能看到ODAC或者Devart標簽頁里面有一堆TOraSession、TOraQuery、TOraTable之類的控件。拖一個到 Form 上如果能正常顯示說明安裝沒問題。提示如果控件面板里找不到 ODAC 標簽先檢查.bpl文件有沒有加對再檢查 Delphi 是不是以管理員權限運行的。權限不夠的話注冊會靜默失敗。4. 配置連接參數(shù)Server、Username、Password 和 Pooling 怎么填4.1 連接字符串的三種寫法ODAC 的Server屬性支持三種寫法我一般根據(jù)場景選第一種是IP:端口/服務名比如192.168.1.100:1521/orcl。這種寫法最直接不需要配tnsnames.ora適合臨時連測試庫。第二種是tnsnames.ora里的別名比如ORCL。這種寫法需要TNS_ADMIN指向的目錄下有對應的配置適合正式環(huán)境換庫的時候只改配置文件就行。第三種是完整連接描述符比如(DESCRIPTION(ADDRESS(PROTOCOLTCP)(HOST192.168.1.100)(PORT1521))(CONNECT_DATA(SERVICE_NAMEorcl)))。這種寫法最靈活但寫起來最長一般用在程序動態(tài)拼接連接串的場景。// 寫法一IP 端口 服務名 OraSession.Server : 192.168.1.100:1521/orcl; // 寫法二tnsnames.ora 別名 OraSession.Server : ORCL; // 寫法三完整描述符 OraSession.Server : (DESCRIPTION(ADDRESS(PROTOCOLTCP)(HOST192.168.1.100)(PORT1521))(CONNECT_DATA(SERVICE_NAMEorcl)));三種寫法效果一樣選哪種看你的部署習慣。我一般正式環(huán)境用別名測試環(huán)境用 IP 直連省得改配置文件。4.2 連接池參數(shù)怎么調(diào)ODAC 自帶連接池TOraSession的Pooling屬性設為True就開啟了。連接池能顯著減少頻繁建立連接的開銷但參數(shù)配不好反而會出問題。關鍵參數(shù)有兩個Pooling和MaxPoolSize。Pooling控制是否啟用連接池MaxPoolSize控制池里最多保持多少個連接。我一般把MaxPoolSize設成 10 到 20 之間具體看并發(fā)量。設太大了浪費數(shù)據(jù)庫資源設太小了并發(fā)一高就排隊。OraSession.Options.Pooling : True; OraSession.Options.MaxPoolSize : 15; OraSession.Options.ConnectionTimeout : 30;ConnectionTimeout是連接超時時間單位秒。網(wǎng)絡不穩(wěn)定的時候可以適當調(diào)大但別超過 60 秒不然用戶等太久會以為程序卡死了。4.3 字符集和日期格式的坑Oracle 的字符集和 Delphi 的字符串編碼有時候會對不上導致中文亂碼。我一般會在連接之后先執(zhí)行一條ALTER SESSION語句把日期格式和字符集顯式設一下OraSession.ExecSQL(ALTER SESSION SET NLS_DATE_FORMAT YYYY-MM-DD HH24:MI:SS); OraSession.ExecSQL(ALTER SESSION SET NLS_LANGUAGE SIMPLIFIED CHINESE);日期格式不設的話Oracle 默認是DD-MON-RRDelphi 里用TDateTime字段的時候會解析出錯。字符集的問題更隱蔽有時候查詢出來是亂碼有時候插入進去是亂碼統(tǒng)一設一下能省很多排查時間。5. 避坑與排查ODAC 安裝配置中最容易翻車的五個點5.1 報「無法加載 OCI 動態(tài)庫」現(xiàn)象程序啟動或者連接的時候彈窗報錯提示找不到oci.dll或者加載失敗。原因Oracle 客戶端的bin目錄不在PATH里或者位數(shù)不匹配。32 位程序加載 64 位oci.dll必失敗反過來也一樣。解決確認 Delphi 編譯目標位數(shù)和 Oracle 客戶端位數(shù)一致然后把客戶端bin目錄加到系統(tǒng)PATH的最前面重啟 Delphi 再試。5.2 安裝完 IDE 里看不到 ODAC 控件現(xiàn)象裝完 ODAC打開 Delphi 發(fā)現(xiàn)控件面板上沒有 ODAC 標簽頁。原因安裝程序沒有自動注冊.bpl或者注冊的時候 Delphi 沒有以管理員權限運行。解決手動Component→Install Packages→Add找到 ODAC 目錄下的dclodac*.bpl加進去。加的時候注意選對版本Delphi 11 和 Delphi 10.4 的.bpl不通用。5.3 連接超時但網(wǎng)絡是通的現(xiàn)象ping數(shù)據(jù)庫服務器能通telnet端口也通但 ODAC 連接就是超時。原因tnsnames.ora里配的SERVICE_NAME和數(shù)據(jù)庫實際的服務名不一致或者TNS_ADMIN指向了錯誤的目錄。解決用tnsping命令測試一下別名能不能解析不能解析就檢查tnsnames.ora的路徑和內(nèi)容。tnsping通了但 ODAC 還超時的話檢查一下Server屬性是不是寫成了SID而不是SERVICE_NAME。5.4 查詢中文顯示亂碼現(xiàn)象數(shù)據(jù)庫里存的中文用 ODAC 查出來是問號或者亂碼。原因客戶端字符集和數(shù)據(jù)庫字符集不一致或者 Delphi 的TStringField編碼設置不對。解決在連接之后執(zhí)行ALTER SESSION SET NLS_LANGUAGE和NLS_TERRITORY把客戶端環(huán)境設成和數(shù)據(jù)庫一致。Delphi 這邊檢查一下TOraQuery的Options.CharSet屬性設成csUTF8或者跟數(shù)據(jù)庫一致的字符集。5.5 連接池耗盡導致程序卡死現(xiàn)象程序運行一段時間后所有數(shù)據(jù)庫操作都卡住重啟程序才能恢復。原因連接池里的連接沒有正確釋放TOraQuery用完沒Close或者TOraSession沒Disconnect。解決確保每個TOraQuery用完都Close每個TOraSession在程序退出或者模塊卸載的時候Disconnect。連接池的MaxPoolSize別設太大設成實際并發(fā)量的 1.5 倍左右就夠了。6. 裝完怎么驗證一個最小可跑的連接測試裝完 ODAC、配好環(huán)境之后別急著往項目里集成先跑一個最小測試確認整條鏈路是通的。我一般會新建一個空白 VCL 項目拖一個TOraSession、一個TOraQuery、一個TDataSource、一個TDBGrid然后寫下面這段代碼procedure TForm1.FormCreate(Sender: TObject); begin OraSession.Server : 192.168.1.100:1521/orcl; OraSession.Username : scott; OraSession.Password : tiger; OraSession.Options.Pooling : True; OraSession.Options.MaxPoolSize : 10; try OraSession.Connect; OraQuery.Session : OraSession; OraQuery.SQL.Text : SELECT * FROM EMP WHERE ROWNUM 10; OraQuery.Open; DataSource.DataSet : OraQuery; DBGrid.DataSource : DataSource; Caption : 連接成功共 IntToStr(OraQuery.RecordCount) 條記錄; except on E: Exception do Caption : 連接失敗 E.Message; end; end;這段代碼做了幾件事設置連接參數(shù)、開啟連接池、連接數(shù)據(jù)庫、執(zhí)行一條查詢、把結(jié)果綁定到DBGrid上顯示。如果窗體標題顯示「連接成功共 10 條記錄」說明 ODAC 安裝、Oracle 客戶端配置、連接參數(shù)、查詢執(zhí)行整條鏈路都沒問題。如果報錯根據(jù)錯誤信息對照第 5 章的排查清單逐條檢查。我一般會先看oci.dll加載有沒有問題再看tnsnames.ora解析對不對最后看賬號密碼和服務名。驗證通過之后還有一個小技巧把TOraSession的Options.Direct屬性設為True試試能不能繞過 Oracle 客戶端直連。ODAC 的直接模式不需要裝 Oracle 客戶端部署的時候能省不少事。但直接模式對某些 Oracle 特性支持不全正式環(huán)境用之前先確認一下你的功能有沒有踩到限制。從那以后我每次裝完 ODAC都會先跑一遍這個最小測試確認沒問題再往項目里集成。希望幫到你。本文還有配套的精品資源點擊獲取