a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > Perl > 正文

Perl--DBI模塊入門(一)

2019-11-06 08:22:15
字體:
來源:轉載
供稿:網友

無論是寫腳本還是做CGI,如何使用Perl來訪問數據庫就是很有用的一個知識。

各種語言和開發環境訪問數據庫有各種不同的方式,比如可以用C和數據庫提供的API接口來進行訪問,也可以用JDBC、ODBC、ADO等封裝好的統一接口來進行訪問。Perl訪問數據庫最常用的包是DBI,可以在www.cpan.org找到。另外還需要安裝對應數據庫的驅動包,例如DBD::MySQL、DBD::Oracle、DBD::Sybase或者DBD::ODBC等。具體的安裝方法請參考上期文章,在此就不贅述了。

下文以常見的MySQL為例,說說如何實現對數據庫的操作。

1 基本流程

習慣在Windows下開發數據庫、熟悉ADO、ADO.NET的朋友,一定對ADOConnection/ADODataSet/ADOTable等類耳熟能詳。DBI的接口與之類似,但在操作方法上又有不同,對ADO熟悉的朋友不妨比較一下異同。一般來說,數據庫操作由以下幾個步驟組成一個常見的流程:

1. 建立一個數據庫連接

2. 通過建立的數據庫連接,執行SQL語句

3. 執行SQL后獲取返回的數據集

4. 在數據集中對記錄進行處理,一般是一個循環的過程

5. 處理完畢,關閉數據庫連接,釋放資源

下面是按照上述的流程,在Perl中訪問MySQL的一段代碼,以這段代碼為例,詳細說明DBI的使用方法。

#!/usr/bin/perl -wuse strict;use DBI;my $dbh = DBI->connect("DBI:mysql:test:192.168.1.2", 'root', 'passWord');my $sth = $dbh->PRepare("SELECT * FROM test1");$sth->execute();while ( my @row = $sth->fetchrow_array() ){       print join('/t', @row)."/n";}$sth->finish();$dbh->disconnect();

注意代碼中的灰色部分就是要特別關注的數據庫訪問接口,這里展現的只是一部分,下面將會依次說明每一個步驟,以及其它的操作在Perl中是如何實現的。

1.1 連接數據庫

my $dbh = DBI->connect("DBI:mysql:test:192.168.1.2", 'root', 'password');

調用DBI的方法DBI->connect來建立一個數據庫的連接,如果連接成功則返回一個數據庫連接句柄,之后執行SQL等操作都要把這個連接句柄作為一個操作參數。在connect調用中,首先要提供一個數據庫連接串。這個連接串用冒號分為了幾個部分,請看下表

小節說明
DBI接口類型
mysql數據庫類型
test數據庫名稱
192.168.1.2數據庫主機地址

在前面例子中的連接串中,DBI表示這是DBI接口的一個連接串;mysql表示要連接的數據庫是MySQL數據庫(如果要連接Oracle數據庫,這里則是oracle),不同的數據庫有不同的連接串定義,可以參考DBI對應的訪問驅動的說明;test指明了連接到數據庫主機上的數據庫名稱;192.168.1.2就是MySQL服務器的ip地址。這里要注意的是,連接串中的數據庫類型mysql必須小寫。如果省略了主機名,則缺省為localhost。connect方法的后面兩個參數是連接數據庫主機的用戶名和密碼,這個可是不可缺少的 J

如果在連接過程中出現任何錯誤,則connect的返回值都會是undef(和C語言中的NULL是一回事)。這里為了簡化而略去了錯誤檢查,實際做項目的時候應當對這些錯誤和返回值的進行檢查。

1.2 執行SQL語句

my $sth = $dbh->prepare("SELECT * FROM test1");$sth->execute();$dbh->do(“UPDATE test1 SET time=now()”);

連接上了數據庫,獲得了數據庫連接句柄,就可以利用這個句柄來對數據庫進行操作了。要執行一條SQL語句,為了提高性能,DBI分兩個步驟來做。先把SQL語句通過prepare方法提交到數據庫,數據庫為該語句分配執行資源,之后調用execute方法通知數據庫執行該SQL語句。注意prepare方法是通過數據庫連接句柄調用的,如果成功則返回一個該SQL的句柄,之后通過該SQL語句句柄調用execute執行SQL。 一般來說execute執行的都是返回數據的語句(例如SELECT語句)。反之如果執行INSERT、UPDATE、DELETE、CREATE TABLE等不需要返回數據的語句,則有一個更方便、快速的方法 $dbh->do(SQL語句),可以省去prepare的步驟。do方法返回的是受該SQL影響的記錄數量。

1.2.1 技巧:對SQL進行排版

常寫大段SQL的朋友可能會對于SQL中的引號很頭痛,每每都因為引號的問題搞的SQL語句亂成一團分辨不清。還記得上篇文章講過的QQ嗎?這里正是它的好用處。由于qq中的字符串同雙引號” ”內的字符串一樣會對變量進行解釋,同時qq還可以換行。因此使用它來對SQL進行排版是非常好的一個選擇,例如像這樣的一條SQL語句:

my $res_Operator = $dbhandle->prepare( qq{       SELECT o_customerid, COUNT(*) AS totalMsgNum FROM mm4fcdrs       WHERE (m_date>'$begindate') AND (m_date<'enddate')        GROUP BY o_customerid });

根本無需考慮引號的問題,可以和正常情況一樣的寫SQL,是不是方便了很多?

1.2.2 通過SQL語句中的參數優化查詢執行效率

在執行大量INSERT之類的語句的時候,反復向數據庫服務器提交同樣結構的一個SQL語句,在這種情況下可以利用prepare和SQL參數來優化執行效率:

1.先使用prepare提交一個SQL模板給數據庫服務器,把其中值的部分用參數占位符代替。 2.使用prepare讓服務器為該SQL準備了執行資源后,調用execute并在該方法中傳入參數實際的值執行SQL。 3.之后可以反復調用execute,不需要服務器重新prepare

假設要執行這樣的一個系列的SQL

INSERT INTO test1 VALUES (NULL, ‘a’, ‘2005-04-01’)... ...INSERT INTO test1 VALUES (NULL, ‘z’, ‘2005-04-01’)

其中第二個字段的值是從a到z的字母。那么可以這樣來優化執行效率:

my $sth = $dbh->prepare( qq{    INSERT INTO test1 VALUES (NULL, ?, ‘2005-04-01’)} );for my $value('a'..'z')  {    $sth->execute($value);}

其中的問號就是前面說的參數占位符了,它的意思就是告訴在準備執行資源的服務器:這個SQL的這個位置會有一個值,但是現在還不知道,等下執行的時候再告訴你。 prepare了之后,用一個循環產生a-z的字符給變量$value,然后將$value在execute方法中作為一個參數傳入,服務器那里會自動用傳入的值替換前面的"?"。需要提醒的是,傳入的參數個數一定要和SQL中的占位符的數量一樣。

1.3 讀取記錄

熟悉ADO的朋友一定知道里面有一個DataReader對象,DBI中讀取數據的方法和它非常的相似。簡單來說,就是單向、流式的讀取數據,也就是每次只能向后讀一條數據直到沒有數據可以讀取。

文章開頭的例子中,用了 $sth->fetchrow_array() 方法來讀取數據。其實DBI讀取數據還有幾種常見的方法,這幾個方法是類似的,所不同的是返回記錄的形式。

1.3.1 fetchrow_array

返回一個由字段的值組成的數組。該數組的第1個元素就是當前記錄第1個字段的值。

while ( my @row = $sth->fetchrow_array() )  {    print "$row[0], $row[1], $row[2]/n";}

或者這樣,不過要注意字段對應的順序

while ( my ($id, $name, $time) = $sth->fetchrow_array() )  {    print "$id, $name, $time/n";}

1.3.2 fetchrow_arrayref

返回由字段的值組成的數組的引用。同fetchrow_array的區別很明顯,fetchrow_arrayref返回的數組的引用。

while ( my $row_ref = $sth->fetchrow_arrayref() ) {    for (my $i = 0; $i < @{$row_ref}; $i++)       {        print "$row_ref->[$i]/t";    }    print "/n";}

這里要注意的是,如果要取字段的個數,需要把這個引用轉成數組的形式獲得@{$row_ref} 。獲取數組元素的值的時候,因為$row_ref是引用,因此需要使用->操作符。

1.3.3 fetchrow_hashref

返回一個由”字段名-字段值”這樣的”鍵-值”對組成的HASH表。關鍵的不同就是,只有這個方法可以通過一個字段名獲得它的值,而不必關心這個字段是第幾個字段。而前者只能依靠索引來訪問值。不過缺點就是,效率要比前面兩個差一些。

while ( my $record = $sth->fetchrow_hashref() ) {    for my $field( keys %{$record} ) {        print "$field: $record->{$field}/t";    }    print "/n";}

這里需要復習一下HASH表的操作方法。keys操作符獲取HASH的鍵(key)的數組,$record->{$field}獲得HASH表中$field對應的值。注意這里同樣是引用,因此要用->操作符。

使用上面三個方法可以基本解決問題了。此外,還有兩個方法fetchall_arrayrefselectall_arrayref可以直接通過SQL一次性獲取整個數據集,不過使用上稍微復雜一些,要涉及到 perl的scalar 操作符,這里就不贅述了。有興趣的讀者可以參考DBI的相關資料。

最后是收尾工作。

1.4 結束一個SQL會話

$sth->finish();

1.5 斷開數據庫連接

$dbh->disconnect();

很簡單明了,就不贅述了。

Perl中利用DBI訪問數據庫的接口基本上就是這些了,還有一些高級的內容留給有興趣的讀者自己發掘研究了。可能有些讀者會感覺沒有ADO、ADO.NET操作起來方便,但是在腳本的環境下能夠如此方便的操作數據庫,比起用C接口來說已經方便很多了。也許在看完這片文章之后的不久,可以在cpan上發現你的Module和全世界的Perl程序員一起分享呢。

2 參考資源

《Programming the Perl DBI》 O’Reily
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 日本欧美久久久久 | 久久精品欧美一区二区三区不卡 | 免费在线黄色av | 亚洲精品国产综合区久久久久久久 | 久久视频精品 | 荡女妇边被c边呻吟视频 | 亚洲自拍偷拍av | 久久综合狠狠综合久久 | 毛片免费在线观看 | 国产特黄一级 | 精品亚洲永久免费精品 | 精品国自产在线观看 | 国产精品视频一区二区三区 | 日本黄色片在线观看 | 亚洲精品视频一区 | 国产女人免费看a级丨片 | 国产美女精品 | 日本免费黄色网 | 精品久久99 | 亚洲www啪成人一区二区 | 亚洲 国产 另类 精品 专区 | 久久国产精品视频 | 四虎影视最新网址 | 欧美在线一二三区 | 精品久久久久久久人人人人传媒 | 国产精品久久久久久久久久久久久久 | aaa级片| 亚洲a网| 日韩精品亚洲一区 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 黑人巨大精品欧美一区二区一视频 | 日日摸日日碰夜夜爽不卡dvd | 伊人网址 | gav成人免费播放视频 | 日本视频在线 | 成人中文视频 | 日韩精品在线看 | 亚洲午夜视频在线观看 | 精品久久久久久久久久久久久久 | 国产欧美精选 | 欧美成人一区二免费视频软件 |