DBI模組方法簡介(轉)

aaqwsh發表於2011-01-16

使用DBI的方法:
-----------------------------------------------------------------------------------
use DBI;
-----------------------------------------------------------------------------------
注意:特定的DBD 級的模組不需要包括use 行,因為在與伺服器進行連線時, DBI 負責啟用相應的模組,比如DBD::mysql。

一、一些變數表達的常用意思
$drh表示驅動程式物件的控制程式碼
$dbh表示針對一個資料庫物件的控制程式碼
$sth表示針對一個語句或者一個查詢物件的控制程式碼
$fh表示一個開啟檔案的控制程式碼
$h表示一個通用的控制程式碼,其含意有賴於上下文
$rc表示操作程式碼返回的布什值(真或假)
$rv表示操作程式碼返回的整數值
$rows表示操作程式碼返回的行數值
$str表示操作程式碼返回的字串
@ary表示查詢返回的一行值的陣列(列表)
@row_ary表示從查詢中返回的一個行的陣列

二、關於DBI的一些驅動物件方法:
查詢子類函式:DBI->available_drivers
比如:-----------------------------------------------------------------------------------
foreach(DBI->available_drivers){print;}
-----------------------------------------------------------------------------------
結果:DBI::mysql
資料來源函式:DBI->data_sources
比如:-----------------------------------------------------------------------------------
foreach(DBI->data_sources){print;}
-----------------------------------------------------------------------------------
結果:對於大多數正確的驅動子類來說,返回值一般為空,對於不能連線、使用者名稱或密碼為空的驅動子類,返回值不為空
資料庫方法呼叫:DBI -> install_driver
比如:
-----------------------------------------------------------------------------------
my $drh = DBI -> install_driver("mysql");
-----------------------------------------------------------------------------------
結果:提供驅動子類的控制程式碼,可以使用$drh -> func ("createdb", $db_name, $db_host, $username, $password, "admin");來建立資料庫
資料庫連線:DBI -> connect
比如:-----------------------------------------------------------------------------------
my $dsn = "dbi:mysql:database=${db_name};hostname=${db_host};mysql_socket=${db_sock};port=${db_port};mysql_compression=1;mysql_read_default_file=$ENV{HOME}/.my.cnf;mysql_read_default_group=client";
my %attr = ( PrintError => 0, RaiseError => 0);
my $dbh = DBI -> connect ($dsn, $user_name, $password, [,\%attr]);
-----------------------------------------------------------------------------------
結果:返回值是針對一個資料庫的控制程式碼,提供資料庫連線功能,關閉連線使用$dbh -> disconnect,其中很多引數可以省略,包括資料庫名稱。

三、資料庫控制程式碼方法的呼叫
1,do方法:
my $rows = $dbh -> do ($query[, \%attr[, @bind_values]]);
語法解釋:準備並執行$query表示的查詢。返回值為受影響的行數—如果不知道行數,則返回-1,如果出現錯誤,則返回undef。
如果受影響的行數為0,則返回值為字串“0E0”,作為數值它與0等價,但在判斷時它為真。
一般用於非SELECT查詢,不檢索行的語句,如DELETE、INSERT、REPLACE或UPDATE,主要使用do()。
如果對SELECT語句使用它,則不會獲得返回的語句控制程式碼,也不能提取任何行。
當語句包括佔位符(在此查詢字串內部由‘?’字母表示)時,使用@bind_values。
@bind_values為給佔位符賦值的值的列表。它必須和佔位符有一樣多的值。如果只指定賦值
的值,但沒有指定屬性,則將undef作為\%attr引數的值來傳遞。
與prepare和execute結合使用的功能基本相同。

2,ping方法:
my $rc = $dbh -> ping ();
語法解釋:檢查與伺服器的連線是否仍然有效,並相應返回真或假。

3,prepare方法:
my $sth = $dbh -> prepare ($query[, \%attr]);
語法解釋:為以後的執行所準備的由$query表示的查詢,並返回一個語句控制程式碼。返回的控制程式碼可用於execute(),以便執行該查詢。

4,quote方法:
my $str = $dbh -> quote ($value[, $data_type]);
語法解釋:處理字串以實現SQL語句中特定字元的引用和轉義,以便在執行這條語句時,該字串不引起語法錯誤。
例如,“‘I \’m happy’”(沒有雙引號)返回字串“I ’m happy”。
如果$value為undef,則它返回字串“NULL”(沒有引號)。
一般來說,$data_type引數不是必需的,因為MySQL將查詢中指定為字串的值自動地轉換為其他型別。
可以將$data_type指定為特殊型別值的提示————例如,DBI::SQL_INTEGER指出$value表示一個整數。
不要使用具有打算利用佔位符插入到查詢中的值的quote()。DBI會自動引用這樣的值。

5,selectall_arrayref方法
my $ary_ref = $dbh -> selectall_arrayref ($query[, \%attr[, @bind_values]]);
語法解釋:執行由$query指定的查詢,並結合prepare()、execute()和fetchall_arrayref()返回結果。如果出現錯誤,則返回undef。
如果$query引數是以前準備的語句,則省略prepare()步驟。
@bind_values引數和do()方法中的該引數具有同樣的意義。
比如:
-----------------------------------------------------------------------------------
# fetch all rows into a reference to an array of references
my $matrix_ref = $dbh -> selectall_arrayref ($query);
# determine dimensions of matrix
my $rows = (!defined ($matrix_ref) ? 0 : scalar (@{$matrix_ref}));
my $cols = ($rows == 0 ? 0 : scalar (@{$matrix_ref->[0]}));
for (my $i = 0; $i < $rows; $i ++) # print each row
{
my $delim = "";
for (my $j = 0; $j < $cols; $j ++)
{
$matrix_ref -> [$i][$j] = "" if !defined ($matrix_ref -> [$i][$j]); # NULL?
print $delim . $matrix_ref -> [$i][$j];
$delim = ",";
}
print "\n";
}
-----------------------------------------------------------------------------------

6,selectcol_arrayref方法
my @ary_ref = $dbh -> selectcol_arrayref ($query[, \%attr[, @bind_values]]);
語法解釋:執行由$query指定的查詢,並通過組合prepare()和execute()返回結果的第一列。返回結果作為對含有每行第一列的陣列的引用。如果出現錯誤,則返回undef。
如果$query引數是以前準備的語句,則省略prepare()步驟。
@bind_values引數和do()方法中的該引數具有同樣的意義。

7,selectrow_array方法
my @row_ary = $dbh -> selectrow_array ($query[, \%attr[, @bind_values]]);
語法解釋:執行由$query指定的查詢,並結合prepare()、execute()和fetchall_arrayref()返回結果的第一行。
如果引數$query是以前準備的語句,則省略prepare()步驟。
如果在列表的上下文中呼叫時,selectrow_array()返回代表行值的陣列,或者,如果出現錯誤,則返回空陣列。在標量的上下文中,selectrow_array()返回這個陣列的第一個元素的值(行的第一列)。如果出現錯誤,則返回undef。
@bind_values引數和do()方法中的相應引數具有同樣的意義。

四、語句控制程式碼方法的呼叫
1,bind_col方法
my $rc = $sth -> bind_col($col_num, \$var_to_bind);
將SELECT查詢的給定列與Perl變數相聯絡,將它作為引用傳遞。$col_num的範圍為1到查詢選擇的列數。每次提取行時,這個變數用列值自動更新。
bind_col()應該在execute()之前及prepare()之後呼叫。
如果列號範圍不在1到查詢選擇的列數之間,則bind_col()返回假。

2,bind_columns方法
my $rc = $sth -> bind_columns (\$var_to_bind1, \$var_to_bind2, ...);
將一系列變數與由準備好的SELECT 語句返回的列相聯絡,請參閱bind_col()方法的說明。
如果引用的數量與查詢選擇的列數不匹配,則bind_columns() 返回假。

3,bind_param方法
my $rv = $sth -> bind_param ($n, $value[, \%attr]);
my $rv = $sth -> bind_param ($n, $value[, $bind_type]);
在一個語句中,將值與佔位符‘?’相聯絡。應該在execute()之前及prepare()之後呼叫它。
$n指定了佔位符的數量,應該限定$value值,而且該值範圍應該為1到佔位符的數量。為了限定NULL值,可傳遞undef。
引數\%attr或者$bind_type可作為要聯絡的值的型別提示。

4,dump_results方法
my $rows = $sth -> dump_results ([$maxlen[, $line_sep[, $field_sep[, $fh]]]]);
從語句控制程式碼$sth 中提取所有的行,通過呼叫實用函式DBI::neat_list()將他們格式化,並將他們列印到給定的檔案控制程式碼中。返回提取的行數
$maxlen、$line_sep、$field_sep和$fh的預設值分別為35、“\n”、“,”和STDOUT。

5,execute方法:
my $rows = $sth -> execute ([@bind_values]);
執行準備好的語句。如果該語句執行成功,則返回真,如果發生錯誤,則返回undef。
引數@bind_values與do()方法中的有相同的意義。

6,fetchall_arrayref方法:
my $tbl_ary_ref = $sth -> fetchall_arrayref ([$slice_array_ref]);
從語句控制程式碼$sth 中提取所有行,並返回陣列的引用,這個陣列包含提取的每行的一個引用。陣列中每個引用的意義取決於所傳遞的引數。沒有引數或者只有陣列部分引用引數,則$tbl_ary_ref 的每個元素都是包括結果集的一行值的陣列引用。對於雜湊部分的引用引數,$tbl_ary_ref 的每個元素就是對包含結果集的一行值的雜湊引用。

7,fetchrow_array方法:
my @ary_ref = $sth -> fetchrow_array ();
當在一個列表的範圍中呼叫時,fetchrow_array()返回包含結果集下一行列值的陣列,如果不再有行或者發生錯誤,則fetchrow_array()返回一個空陣列。在標量上下文中,fetchrow_array()返回陣列第一個元素的值(那就是說,行的第一列),如果不再有行或者發生錯誤,則fetchrow_array()返回undef。
通過檢查$sth->err(),可以將結果集正常結束與出現錯誤區分開來。零值表明已經無錯誤地到達了結果集的末尾。
一般與while使用。
比如:
-------------------------------------------------------------------

-----------------------------------------------------------------------------------

8,fetch或fetchrow_arrayref方法
my @ary_ref = $sth -> fetchrow_arrayref ();
返回一個包括結果集的下一行列值的陣列引用。如果不再有行或者發生錯誤,則返回undef。
通過檢查$sth->err(),可以將結果集正常結束與出現錯誤區分開來。零值表明已經無錯誤地到達了結果集的末尾。
一般與while使用。
比如:
-----------------------------------------------------------------------------------
my @matrix = (); # array of array references
while (my @ary = $sth -> fetchrow_array ()) # fetch each row
{
push (@matrix, [ @ary ]); # save reference to just-fetched row
}
# determine dimensions of matrix
my $rows = scalar (@matrix);
my $cols = ($rows == 0 ? 0 : scalar (@{$matrix[0]}));
for (my $i = 0; $i < $rows; $i++) # print each row
{
my $delim = "";
for (my $j = 0; $j < $cols; $j++)
{
$matrix[$i][$j] = "" if !defined ($matrix[$i][$j]); # NULL value?
print $delim . $matrix[$i][$j];
$delim = ",";
}
print "\n";
}
-----------------------------------------------------------------------------------

9,fetchrow_hashref方法
my $hash_ref = $sth -> fetchrow_hashref ([$name]);
返回包括結果集的下一行列值的雜湊引用。如果不再有行或者發生錯誤,則返回undef。雜湊是索引值是列名稱,雜湊的元素是列值。
對於雜湊的關鍵值,指定變數$name說明使用的語句控制程式碼屬性。預設值為“NAME”。這可能導致查詢中的列名稱不區分大小寫的問題,但是雜湊鍵是區分大小寫的。要強迫雜湊鍵為大寫字母或者小寫字母,可以指定“NAME_lc”或“NAME_uc”的$name值。
通過檢查$sth->err(),可以將結果集正常結束與出現錯誤區分開來。零值表明已經無錯誤地到達了結果集的末尾。
一般與while使用。
比如:
-----------------------------------------------------------------------------------
while (my $hash_ref = $sth -> fetchrow_hashref ())
{
my $delim = "";
foreach my $key (keys (%{$hash_ref}))
{
$hash_ref -> {$key} = "" if !defined ($hash_ref->{$key}); # NULL value?
print $delim . $hash_ref -> {$key};
$delim = ",";
}
print "\n";
}
-----------------------------------------------------------------------------------

10,finish方法
my $rc = $sth -> finish();
釋放有關語句控制程式碼的任何資源。通常不必顯式地呼叫這個方法,但是如果只提取部分結果集,則呼叫finish()使DBI瞭解已經提取了資料。呼叫finish()可能使語句屬性無效,最好在呼叫execute()之後立即訪問它們。

11,rows方法
my $rv = $sth -> rows();
返回與$sth相關的語句所作用的行數,如果發生錯誤,則返回-1。使用這個方法主要用於不返回行的語句。對於SELECT語句,不能依賴rows()方法在提取行時統計行數。

五、通用控制程式碼方法
下面的方法不是專用於特定型別的控制程式碼的。可用驅動程式、資料庫或語句控制程式碼來呼叫它們。
1,$h -> err()
返回最近呼叫的驅動程式操作的數字錯誤程式碼。0表示沒有錯誤。
2,$h -> errstr()
返回最近呼叫的驅動程式操作的字串錯誤訊息。空字串表示沒有錯誤。
3,DBI -> trace($trace_level[, $trace_filename]);
$h -> trace($trace_level[, $trace_filename]);
設定跟蹤級別。跟蹤提供有關DBI操作的資訊。跟蹤級別的範圍從0(關閉)到9(最多資訊)。通過作為DBI類方法或獨立的控制程式碼呼叫跟蹤,跟蹤可以啟用指令碼內部的所有DBI操作:
DBI->trace(2);開啟指令碼跟蹤
$sth->trace(2);開啟控制程式碼跟蹤
通過設定DBI_TRACE環境變數,也可以對執行的所有DBI指令碼在全域性級別啟用跟蹤。預設時,跟蹤輸出到STDERR.。提供的$filename引數可以直接將結果輸出到不同的檔案。將輸出新增到這個檔案的任何已有內容後面。
每個跟蹤呼叫導致來自所有跟蹤的控制程式碼中的輸出進入相同的檔案。如果檔案已命名,則所有跟蹤就輸出到那個檔案。如果沒有命名的檔案,則所有跟蹤輸出到STDERR。
4,DBI -> trace_msg($str[, $min_level])
$h -> trace_msg($str[, $min_level])
如果跟蹤這個控制程式碼或如果在DBI級啟用跟蹤,則編寫這個跟蹤輸出的訊息。如果啟用DBI級的跟蹤,則trace_msg()可以作為DBI->trace_msg()來呼叫,編寫訊息。只有在跟蹤級別至少為這個級別時,才可以提供$min_level 引數來指定應該編寫的訊息。

六、MySQL 的特定管理方法
DBI 作為直接訪問驅動程式的手段所供的func() 函式方法
-----------------------------------------------------------------------------------
$rc = $drh -> func("createdb", $dbname, [host, user, password,], 'admin');
$rc = $drh -> func("dropdb", $dbname, [host, user, password,], 'admin');
$rc = $drh -> func("shutdown", [host, user, password,], 'admin');
$rc = $drh -> func("reload", [host, user, password,], 'admin');
-----------------------------------------------------------------------------------
or
-----------------------------------------------------------------------------------
$rc = $dbh -> func("createdb", $dbname, 'admin');
$rc = $dbh -> func("dropdb", $dbname, 'admin');
$rc = $dbh -> func("shutdown", 'admin');
$rc = $dbh -> func("reload", 'admin');
-----------------------------------------------------------------------------------
通過驅動程式控制程式碼或通過資料庫控制程式碼訪問func()方法。驅動程式控制程式碼與開啟的連線無關,所以,如果以這種方式訪問func(),則必須提供允許這個方法建立連線的主機名稱、使用者名稱稱和口令的引數。如果用資料庫控制程式碼訪問func(),則不需要那些引數。如果需要,可以像下面這樣獲得驅動程式控制程式碼:
my $drh = DBI -> install_driver(“mysql”);#(“mysql”mustbelowercase)
createdb建立由$db_name指定的資料庫。要這樣做,必須對該資料庫擁有CREAT許可權。
dropdb刪除由$db_name指定的資料庫。要這樣做,必須對該資料庫擁有DROP許可權。當心,如果刪除了一個資料庫,則它將會消失,且再也不能恢復。
shutdown關閉伺服器。必須具有SHUTDOWN許可權。
reload告訴伺服器重新載入授權表。如果直接使用DELETE、INSERT或UPDATE而不是使用GRANT或REVOKE來修改這個授權表的內容,則這是必需的。要使用reload,必須具有RELOAD許可權。


七、DBI 環境變數
DBI考慮了幾個環境變數,如表G-3所示。除了DBI_TRACE之外,所有變數都由connect()方法使用。DBI_TRACE由trace()方法使用。
DBI_DRIVER:DBI級的驅動程式名(MySQL的“mysql”)
DBI_DSN:資料來源名
DBI_PASS:口令
DBI_TRACE:跟蹤級別和/或跟蹤輸出檔案
DBI_USER:使用者名稱稱
-----------------------------------------------------------------------------------
$errno = $dbh->{'mysql_errno'};
$error = $dbh->{'mysql_error};
$info = $dbh->{'mysql_hostinfo'};
$info = $dbh->{'mysql_info'};
$insertid = $dbh->{'mysql_insertid'};
$info = $dbh->{'mysql_protoinfo'};
$info = $dbh->{'mysql_serverinfo'};
$info = $dbh->{'mysql_stat'};
$threadId = $dbh->{'mysql_thread_id'};
-----------------------------------------------------------------------------------

八、一個例子
-----------------------------------------------------------------------------------
#!/usr/bin/perl -w

use CGI::Carp "fatalsToBrowser";
use strict;
use warnings;
use DBI;
use CGI qw (:standard escapeHTML escape);

my ($driver_name, $db_name, $db_host, $db_sock, $db_port, $db_user, $db_pswd, $dsn);
$driver_name = 'mysql';
$db_name = 'mydata';
$db_host = 'localhost';
$db_sock = '/tmp/mysql.sock';
$db_port = '3306';
$db_user = 'cnangel';
$db_pswd = 'cnangel';
$dsn = "dbi:mysql:database=${db_name};hostname=${db_host};mysql_socket=${db_sock};port=${db_port}";

# ... set up connection to database (not shown) ...
my $dbh = DBI -> connect ($dsn, $db_user, $db_pswd,
{ RaiseError => 1, PrintError => 0 });

# put out initial part of page
my $title = "$db_name Database Browser";
print header ();
print start_html (-title => $title, -bgcolor => "white");
print h1 ($title);

# parameters to look for in URL
my $tbl_name = param ("tbl_name");
my $sort_col = param ("sort_col");

# If $tbl_name has no value, display a clickable list of tables.
# Otherwise, display contents of the given table. $sort_col, if
# set, indicates which column to sort by.


!defined ($tbl_name) ? display_table_names ($dbh, $db_name) : display_table_contents ($dbh, $tbl_name, $sort_col);

print end_html ();

sub display_table_names
{
my ($dbh, $db_name) = @_;
print p ("Select a table by clicking on its name:");

# retrieve reference to single-column array of table names
my $ary_ref = $dbh -> selectcol_arrayref (qq{ SHOW TABLES FROM $db_name });

# Construct a bullet list using the ul() (unordered list) and
# li() (list item) functions. Each item is a hyperlink that
# re-invokes the script. to display a particular table.
my @item;
foreach my $tbl_name (@{$ary_ref})
{
my $url = sprintf ("%s?tbl_name=%s", url (), escape ($tbl_name));
my $link = a ({-href => $url}, escapeHTML ($tbl_name));
push (@item, li ($link));

R>}
print ul (@item);
}

sub display_table_contents
{
my ($dbh, $tbl_name, $sort_col) = @_;
my @rows;
my @cells;
# if sort column not specified, use first column
$sort_col = "1" if !defined ($sort_col);

# present a link that returns user to table list page
print p (a ({-href => url ()}, "Show Table List"));

print p (strong ("Contents of $tbl_name table:"));

my $sth = $dbh -> prepare (qq{
SELECT * FROM $tbl_name ORDER BY $sort_col
LIMIT 200
});
$sth -> execute ();

# Use the names of the columns in the database table as the
# headings in an HTML table. Make each name a hyperlink that
# causes the script. to be reinvoked to redisplay the table,
# sorted by the named column.

foreach my $col_name (@{$sth -> {NAME}})
{
my $url = sprintf ("%s?tbl_name=%s;sort_col=%s",
url (),
escape ($tbl_name),
escape ($col_name));
my $link = a ({-href => $url}, escapeHTML ($col_name));
push (@cells, th ($link));
}
push (@rows, Tr (@cells));

# display table rows
while (my @ary = $sth -> fetchrow_array ())
{
@cells = ();
foreach my $val (@ary)
{
# display value if non-empty, else display non-breaking space
if (defined ($val) && $val ne "")
{
$val = escapeHTML ($val);
}
else
{
$val = " ";
}
push (@cells, td ($val));
}
push (@rows, Tr (@cells));
}

# display table with a border
print table ({-border => "1"}, @rows);
}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/758322/viewspace-683945/,如需轉載,請註明出處,否則將追究法律責任。