Perl 教學
This tutorial is copyrighted and provided as is. You are welcomed to use it for non-commercial purpose.Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼
看其他教材
目錄
- 前言
- 安裝
- 一些簡單的 Perl 程式
- Perl 與 Form
- 函數與字串處理
- 表單處理
- 檔案處理
- Server-Side Includes
- 資料庫查詢 (ODBC)
- 資料庫查詢 (DBI)
- 我還想更瞭解 Perl, 有哪些書可以參考?
檔案處理:
範例: 學生成績查詢- 檔案格式: 檔案的第一列包含各欄位的標題如代碼, 第一個作業, 期末考 等。
第二裂開始為實際資料。 在本例中, 我們規定學生代碼必為一連續字, 例如:
代碼 作業一(50) 作業二(50) 作業三(75) 專題 期中考(128) 成績 ABC 25 30 45 75 74 70 Kevin_C 30 40 45 70 103 79 Tina 40 25 60 80 105 85 totoro 30 30 57 85 95 83 wei-jen 30 25 62 70 85 74
- 表單格式: 完整原始碼
Grades - Perl 檔案函數: 打開檔案並計算欄位數。
#!/usr/local/bin/perl require 'req.pl'; require 'forms-lib.pl'; # open a file called "sa4a.txt" and assign it # a filehandler called INP. # if file cannot open, execute die(). open(INP, "sa4a.txt") || die("Cannot open sa4a.txt.\n"); @recs = <INP>; # get the first record $record = $recs[0]; # get rid of consecutive whitespaces # \s: whitespace, +: one or more. @fields = split(/\s+/, $record); $num_field = @fields; # a way of printing what we got. #print "Record is @fields.\n"; #print "Number of field is $num_field.\n"; &Header("Grades"); # print table header print "$record\n"; # read data till the end of the file for($row=1; $row < @recs; $row++) { $record = $recs[$row]; print "$record\n"; } &Footer;
- 寫資料到檔案:
#!/usr/bin/perl $a1 = "Eric"; $a2 = 80; $a3 = 75; # ">sa4a.txt" 產生輸出檔 # ">>sa4a.txt" 產生附加式的輸出檔 open(OUTP, ">sa4a.txt") || die "Cannot open file\n"; print OUTP "$a1 $a2 $a3\n"; close OUTP;
Server-Side Includes
常常看到計數器嗎﹖ 想想看,我們似乎可以將已經拜訪的次數放在一個檔案中, 而每一次有訪客到的時候,便執行一個簡單的 CGI 程式來更改檔案內的數字。 可是我們所學的都需要經過 form 的元件才能執行,我們要如何才能使得 訪客一到這個網頁就能自動執行這個計數器呢﹖ 請參考 SSIs。資料庫查詢 (ODBC)
Perl 也提供與各種資料庫 (如 mSQL, Oracle, Sybase, Xbase 等) 的連結。 在本例中, 我們僅討論如何利用 ODBC 的方式與資料庫連結。 (ODBC 僅適用於 Win32 的系統. 其他 的連結方法,再下例中有進一步的說明.) 連結 ODBC 資料庫的方式有兩種方法。 在以下 的說明中, 我們使用的是一個 Microsoft Access 的資料庫 -- samples.mdb。 這個資料庫中包含一個 Table, 其名稱為 Product。 Product 有四個欄位 (ID, Name, Price, Qty)。 請於下載後, 利用 ODBC 將其設定為 Samples. 其過程為:「開始」 --> 「設定」 --> 「控制台」 --> 「ODBC」 --> 「系統資料來源名稱」 --> 「新增」 --> 「Microsoft Access Driver (*.mdb)」 --> 「完成」在 "資料來源名稱" 欄, 輸入 Samples, 並 「選擇」 samples.mdb 後按 OK。
- 幾個簡單的 SQL 範例:
- 新增 (insert): 將一筆資料加入 Product.
insert into Product values ('5','燒錄器', 15000, 10)
- 查詢 (select):
- 查詢全部資料:
select * from Product
- 查詢名稱為'燒錄器'的相關資料:
select * from Product where Name='燒錄器'
- 查詢名稱為'燒錄器'的目前存量:
select Name, Qty from Product where Name='燒錄器'
- 查詢單價低於 2500 元的產品:
select * from Product where Price < 2500
- 查詢單價介於 300 與 10000 元間的產品:
select * from Product where Price >= 300 and Price < 10000
- 查詢全部資料:
- 更改 (update): 將燒錄器的存量改為 20.
update Product set Qty=20 where Name='燒錄器'
- 刪除 (delete): 刪除燒錄器的產品資料
delete from Product where Name='燒錄器'
- 新增 (insert): 將一筆資料加入 Product.
- 你可使用 Win32::OLE。 原始碼如下:
use Win32::OLE; # setup the names of DSN and Table. $DSN = "Samples"; $Table = "Product"; # Connect and open the database $Conn = new Win32::OLE "ADODB.Connection"; $Conn->Open("DSN=$DSN;UID=;PWD="); #$Conn->Open("$DSN", "", ""); #$Conn->Open("$DSN"); # The followings don't work well. #$Conn->Open("DSN=Samples;UID=;PWD=") || die "Cannot connect"; #$Conn or die "Cannot connect"; # Execute the SQL statement $RS = $Conn->Execute("SELECT * FROM $Table"); if(!$RS) { $Errors = $Conn->Errors(); print "Errors:\n"; foreach $error (keys %$Errors) { print $error->{Description}, "\n"; } die; } # Retrieving records from Table. while ( !$RS->EOF ) { my($ID, $Name, $Price, $Qty) = ( $RS->Fields('ID')->value, $RS->Fields('Name')->value, $RS->Fields('Price')->value, $RS->Fields('Qty')->value ); print $ID, " : ", $Name, " : ", $Price, " : ", $Qty, "\n"; $RS->MoveNext; } # Close the connection. $RS->Close; $Conn->Close;
- 若你使用 Win32::ODBC, 原始碼如下:
use Win32::ODBC; # set Data Source Name $DSN = "Samples"; # Open connection to DSN if (!($O = new Win32::ODBC($DSN))){ print "Failure. \n\n"; exit(); } # set Table name $Table = Product; # Get the content of the table. if (! $O->Sql("SELECT * FROM $Table")) { # print out the field names. @FieldNames = $O->FieldNames(); $Cols = $#FieldNames + 1; for ($iTemp = 0; $iTemp < $Cols; $iTemp++){ $FmH2 .= "$FieldNames[$iTemp] "; } chop $FmH2; print "$FmH2\n"; # Fetch the next rowset while($O->FetchRow()){ undef %Data; %Data = $O->DataHash(); print $Data{'ID'}, " ", $Data{'Name'}, " ", $Data{'Price'}, " ", $Data{'Qty'}, "\n"; } } # Close Connection. $O->Close();
資料庫查詢 (DBI)
在前例中, 作者曾提及 Perl 可與各種資料庫連結。 其中, DBI 是一類似 ODBC 的介面。 只要安裝適當的資料庫驅動程式 (DBD), Perl 便可經由它使用相同的 function calls 與許多資料庫連結。 (DBI 也有 ODBC 的驅動程式, 這裡提供了一個範例。) 如果想對 DBI 作更進一步的了解,請於安裝 DBI 的電腦上執行 perldoc DBI 已獲得更詳細的說明。若你需要經過 ODBC 來連結 資料庫(如 MS SQL Server),你可以使用 perldoc DBD::ODBC 獲得更詳細的說明。 在本例中, 我們以 mSQL 為例。 作者假設你可存取任一 mSQL 資料庫。 我們使用的是一個名為 db_test 的資料庫, 它位於 penguin.im.cyut.edu.tw。 這個資料庫中包含一個 Table, 其名稱為 Product。 Product 有四個欄位 (ID, Name, Price, Qty)。 原始碼如下:#!/usr/bin/perl use DBI; # initialize datasourcename. for details, perldoc DBD::mSQL. # to connect to a DB server on another host such as sun20, #$dsn = 'db_test:sun20'; $dsn = 'db_test'; # 1. to connect to other DB such as Oracle, all you need to # do is to replace "mSQL" with "Oracle". (assume that # Oracle driver has been installed.) # # 2. to connect to MS Access, simply change DSN to 'dbi:ODBC:Samples' # $dbh = DBI->connect("dbi:mSQL:$dsn", "", "") || die "Can't connect to $data_source: $DBI::errstr"; $sth = $dbh->prepare("SELECT * FROM Product") || die "Can't prepare statement: $DBI::errstr"; $rc = $sth->execute || die "Can't execute statement: $DBI::errstr"; print "Query will return $sth->{NUM_OF_FIELDS} fields.\n\n"; print "Field names: @{ $sth->{NAME} }\n"; while (($ID, $Name, $Price, $Qty) = $sth->fetchrow_array) { print "$ID, $Name, $Price, $Qty\n"; } # check for problems which may have terminated the fetch early die $sth->errstr if $sth->err; $sth->finish;另外, 你也可以安裝 mSQL 專用的模組 (如 Msql), 使用以下程式 也可以達到上述範例的結果。 欲知 Msql 的細節, 請執行 perldoc Msql。 [註: 安裝 Msql 模組前, 需先安裝 DBI]
#!/usr/bin/perl use Msql; # Connect to DB, db_test, located at the local host. # mSQL is also available on sun20.im.cyut.edu.tw. Therefore, you # can also connect to db_test on sun20 by # $db = Msql->connect("sun20","db_test") or # die "Cannot connect to db_test on sun20."; # When using with CGI, it is a perfect example of 3-tier architecture. # $db = Msql->connect("","db_test") or die "Cannot connect to db_test"; # you can insert a row #$db->query("insert into Product values('11', '數據機', 5000, 10)"); # or you can delete what you just inserted #$db->query("delete from Product where ID='11'"); # submit the query. $sth = $db->query("select * from Product") or die "Cannot Quety."; # obtain various info about this table. print "Number of rows: ", $sth->numrows, "\n"; print "Number of columns: ", $sth->numfields, "\n"; print "\n"; # obtain field names @fnames = $sth->name; @ftypes = $sth->type; for($i=0; $i<$sth->numfields; $i++) { print $fnames[$i], " is of type ", $ftypes[$i], "\n"; } print "\n"; # fetch records from the table # # Case 1: fetch a row at a time. #while(@arr = $sth->fetchrow) #{ # # print out field values of each row. # foreach $arr (@arr) # { # print $arr, " "; # } # print "\n"; #} # # Case 2: fetch entire row, including field names, into a hash while(%hash = $sth->fetchhash) { print $hash{'ID'}, " ", $hash{'Name'}, " ", $hash{'Price'}, " ", $hash{'Qty'}, "\n"; }
我還想更瞭解 Perl, 有哪些書可以參考?
除了一開始推薦的 The Developer COM 的線上書外, 一般公認的好書有:- Larry Wall, Tom Christiansen, and Randal Schwartz, Prorgamming Perl, 2nd edition, O'Reilly & Associates, 1996.
- Randal Schwartz, Learning Perl, 2nd edition, O'Reilly & Associates, 1997. (Unix Systems)
- Randal Schwartz, Erik Olson, and Tom Christiansen, Learning Perl on Win32 Systems, O'Reilly & Associates, 1997. (Win32 Systems) [松崗代理]
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
沒有留言:
張貼留言