前言 接手前輩的項目,沒有接觸、安裝、使用過perl和DBD::Oracle,也沒有相關的文檔記錄,茫茫然不知所措~~。一開始發現這個問題,就想著迅速解決,就直接在google上搜報錯信息,搜索的過程中發現 如果不搞清楚前因後果我連解決方案都‘看不見’‘看不懂’。 所以還是要補充這方面的知識,再思考 ...
前言
接手前輩的項目,沒有接觸、安裝、使用過perl和DBD::Oracle,也沒有相關的文檔記錄,茫茫然不知所措~~。一開始發現這個問題,就想著迅速解決,就直接在google上搜報錯信息,搜索的過程中發現 如果不搞清楚前因後果我連解決方案都‘看不見’‘看不懂’。 所以還是要補充這方面的知識,再思考解決方案。以下內容就是我一邊學習一邊解決問題的過程,如果不足,請各位大佬指出。報錯
install_driver(Oracle) failed: Can't locate DBD/Oracle.pm in @INC (@INC contains:/home/as_user/PMS/Data-Update /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at (eval 12) line 3. Perhaps the DBD::Oracle perl module hasn't been fully installed, or perhaps the capitalisation of 'Oracle' isn't right. Available drivers: DBM, ExampleP, File, Gofer, Pg, Proxy, SQLite, Sponge, mysql. at /home/as_user/PMS/Data-Update/SolexaDown.pl line 19
DBI相關知識
參考:菜鳥教程DBI相關
在perl中使用DBI的方法
1 #!/usr/bin/perl 2 use DBI; #perl引入DBI模塊 3 my $dbh = DBI->connect("dbi:Oracle:host=$host;sid=$sid", $user, $passwd); #DBI根據輸入的驅動程式對象的句柄調用對應的數據模塊,返回一個資料庫對象的句柄
這個時候我的腦海裡出現了兩個問題
1.代碼中使用use,那use怎麼知道DBI所在的目錄,在哪裡設置了,和@INC有什麼關係???
2.DBI如何激活DBD::Oracle,尋找的路徑是什麼,在哪裡,怎麼設置,和@INC有什麼關係???
上述問題可能會在配置DBI,DBD::Oracle中找到答案,所以我就先查詢學習了配置過程
安裝DBI
perl DBI官網: https://dbi.perl.org/ ,在官網中可以跳轉到下載路徑 https://metacpan.org/release/DBI
配置方法DBD::Oracle
要點
1. DBD::Oracle模塊不是Oracle官方開發的,由Pythian Group公司開發,網址為https://metacpan.org/pod/DBD::Oracle,下載該模塊的地址https://metacpan.org/release/MJEVANS/DBD-Oracle-1.75_2 。當然可以去CPAN(Comprehensive Perl Archive Network,Perl模塊聚集庫https://www.cpan.org/)下載
2. 先裝DBI,再裝DBD模塊,在安裝DBD::Oracle中,如果裝在沒有Oracle Database的主機上,則需要安裝Oracle Instant Client來進行遠程資料庫連接
3.在安裝教程中,指出要配置Orcale_HOME目錄,我們可以在根目錄下輸入vi .bashrc命令,即可看到Oracle_HOME的配置信息
在安裝DBD::Oracle過程中,設置Oracle_HOME變數這一步似乎與我的問題2有關(但沒有清晰的關聯),但和問題1一點關係都沒有,這時候就懷疑perl中有設置相應的參數,仔細查看執行腳本的開頭,發現有使用到FindBin,想著不瞭解那就去學習一下。幸運的是,在學習的過程中解決了我的報錯。
perl的FindBin模塊(一定要看參考的網址,很有幫助)
要點1:
假定腳本路徑在/home/as_user/PMS/testt.pl,在目錄/home/as_user/PMS下運行該腳本
即$bin表示路徑/home/as_user/PMS,$Script表示testt.pl
要點2:
use 是在預設的@INC裡面去尋找對應的模塊,一旦模塊不在@INC中,那麼use是不能引入的。同時use引入的名稱不需要尾碼名,預設同時也只能找.PM文件
要點3:
參考:查看Perl模塊安裝路徑
@INC是perl的一個特殊列表標量,存儲著當前版本的Perl模塊的路徑。編譯腳本時,Perl會根據@INC存儲的路徑去查詢用戶所調用的模塊,可以用命令‘perl -V’來查看具體模塊的目錄,也同樣可以用BEGIN代碼塊對@INC進行操作。其中.表示腳本的當前目錄。
總結
在學習了‘配置DBD::Oracle方法’ 以及‘perl的FindBin模塊’的相關知識後,再回到報錯,報錯說在@INC路徑下Can't locate DBD/Oracle.pm,既然找不到,那麼我們要在執行腳本中設置DBD/Oracle.pm的路徑。設置的方法是使用 FindBin模塊。
舉個例子:執行腳本SolexaDown.pl的目錄為 /home/as_user/PMS/Data-Update,在這個目錄下的/lib目錄下存在 DBD/Oracle.pm,即存在路徑 /home/as_user/PMS/Data-Update/DBD/Oracle.pm。那麼我在olexaDown.pl腳本的開頭,應該寫上
use FindBin '$Bin'; use lib "$Bin/lib";
這樣一來,perl執行SolexaDown.pl腳本時就能找到DBD/Oracle.pm了。報錯解決了~~
關於問題
use查找引用的模塊 和 DBI激活對應的DBD 都是通過 @INC下的路徑去查找的,之所以說DBI激活對應的DBD也是通過@INC的依據:我發現DBI有個available_drivers方法,perl DBI手冊上有寫到 "該方法通過@INC中的目錄搜索所有的DBD::*模塊返回一個所有可用驅動器的列表。預設情況下,如果某些驅動器被先前目錄中其他相同名字的驅動器覆蓋,將會返回一個警告,可以通過設置$quiet為true屏蔽",這啟發了我,再根據DBI的源碼,我發現了實際的代碼 grep { -d "$_/auto/DBD/$driver" } @INC。我懶的仔細看源碼,$_具體指哪些就沒深究,有興趣的可以仔細研究一下,DBI源碼是用perl寫的。設置@INC的方法在鏈接 查看Perl模塊安裝路徑中可以找到,我就不列舉了。