perl DBI使用详解

使用DBI的方法:
---------------------------------------------------------------------
use DBI;
---------------------------------------------------------------------
注意:特定的DBD 级的模块不须要包括use 行,由于在与服务器进行链接时, DBI 负责激活相应的模块,好比DBD::mysql。
1、一些变量表达的经常使用意思
$drh表示驱动程序对象的句柄
$dbh表示针对一个数据库对象的句柄
$sth表示针对一个语句或者一个查询对象的句柄
$fh表示一个打开文件的句柄
$h表示一个通用的句柄,其含意有赖于上下文
$rc表示操做代码返回的布什值(真或假)
$rv表示操做代码返回的整数值
$rows表示操做代码返回的行数值
$str表示操做代码返回的字符串
@ary表示查询返回的一行值的数组(列表)
@row_ary表示从查询中返回的一个行的数组
2、关于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,其中不少参数能够省略,包括数据库名称。
3、数据库句柄方法的调用
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()方法中的相应参数具备一样的意义。
4、语句句柄方法的调用
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的缺省值分别为3五、“\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使用。
好比:
---------------------------------------------------------------------
while (my @ary = $sth -> fetchrow_array ())
{
@ary = map { defined ($_) ? $_ : "NULL" } @ary;
print join (",", @ary) . "\n";
}
---------------------------------------------------------------------
8, fetchfetchrow_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()方法在提取行时统计行数。
5、通用句柄方法
下面的方法不是专用于特定类型的句柄的。可用驱动程序、数据库或语句句柄来调用它们。
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 参数来指定应该编写的消息。
6、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权限。

7、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'};
---------------------------------------------------------------------

8、一个例子
---------------------------------------------------------------------
 
  
  1. #!/usr/bin/perl -w 
  2.  
  3. use CGI::Carp "fatalsToBrowser"
  4. use strict; 
  5. use warnings; 
  6. use DBI; 
  7. use CGI qw (:standard escapeHTML escape); 
  8.  
  9. my ($driver_name, $db_name, $db_host, $db_sock, $db_port, $db_user, $db_pswd, $dsn); 
  10. $driver_name = 'mysql'
  11. $db_name = 'mydata'
  12. $db_host = 'localhost'
  13. $db_sock = '/tmp/mysql.sock'
  14. $db_port = '3306'
  15. $db_user = 'cnangel'
  16. $db_pswd = 'cnangel'
  17. $dsn = "dbi:mysql:database=${db_name};hostname=${db_host};mysql_socket=${db_sock};port=${db_port}"
  18.  
  19. # ... set up connection to database (not shown) ... 
  20. my $dbh = DBI -> connect ($dsn, $db_user, $db_pswd, 
  21. { RaiseError => 1, PrintError => 0 }); 
  22.  
  23. # put out initial part of page 
  24. my $title = "$db_name Database Browser"
  25. print header (); 
  26. print start_html (-title => $title, -bgcolor => "white"); 
  27. print h1 ($title); 
  28.  
  29. # parameters to look for in URL 
  30. my $tbl_name = param ("tbl_name"); 
  31. my $sort_col = param ("sort_col"); 
  32.  
  33. # If $tbl_name has no value, display a clickable list of tables. 
  34. # Otherwise, display contents of the given table. $sort_col, if 
  35. set, indicates which column to sort by
  36.  
  37.  
  38. !defined ($tbl_name) ? display_table_names ($dbh, $db_name) : display_table_contents ($dbh, $tbl_name, $sort_col); 
  39.  
  40. print end_html (); 
  41.  
  42. sub display_table_names 
  43. my ($dbh, $db_name) = @_; 
  44. print p ("Select a table by clicking on its name:"); 
  45.  
  46. # retrieve reference to single-column array of table names 
  47. my $ary_ref = $dbh -> selectcol_arrayref (qq{ SHOW TABLES FROM $db_name }); 
  48.  
  49. # Construct a bullet list using the ul() (unordered list) and 
  50. # li() (list item) functions. Each item is a hyperlink that 
  51. # re-invokes the script to display a particular table
  52. my @item; 
  53. foreach my $tbl_name (@{$ary_ref}) 
  54. my $url = sprintf ("%s?tbl_name=%s", url (), escape ($tbl_name)); 
  55. my $link = a ({-href => $url}, escapeHTML ($tbl_name)); 
  56. push (@item, li ($link)); 
  57. print ul (@item); 
  58.  
  59. sub display_table_contents 
  60. my ($dbh, $tbl_name, $sort_col) = @_; 
  61. my @rows
  62. my @cells; 
  63. # if sort column not specified, use first column 
  64. $sort_col = "1" if !defined ($sort_col); 
  65.  
  66. # present a link that returns user to table list page 
  67. print p (a ({-href => url ()}, "Show Table List")); 
  68.  
  69. print p (strong ("Contents of $tbl_name table:")); 
  70.  
  71. my $sth = $dbh -> prepare (qq{ 
  72. SELECT * FROM $tbl_name ORDER BY $sort_col 
  73. LIMIT 200 
  74. }); 
  75. $sth -> execute (); 
  76.  
  77. # Use the names of the columns in the database table as the 
  78. # headings in an HTML table. Make each name a hyperlink that 
  79. # causes the script to be reinvoked to redisplay the table
  80. # sorted by the named column
  81.  
  82. foreach my $col_name (@{$sth -> {NAME}}) 
  83. my $url = sprintf ("%s?tbl_name=%s;sort_col=%s"
  84. url (), 
  85. escape ($tbl_name), 
  86. escape ($col_name)); 
  87. my $link = a ({-href => $url}, escapeHTML ($col_name)); 
  88. push (@cells, th ($link)); 
  89. push (@rows, Tr (@cells)); 
  90.  
  91. # display table rows 
  92. while (my @ary = $sth -> fetchrow_array ()) 
  93. @cells = (); 
  94. foreach my $val (@ary) 
  95. # display value if non-empty, else display non-breaking space 
  96. if (defined ($val) && $val ne ""
  97. $val = escapeHTML ($val); 
  98. else 
  99. $val = " "
  100. push (@cells, td ($val)); 
  101. push (@rows, Tr (@cells)); 
  102.  
  103. # display table with a border 
  104. print table ({-border => "1"}, @rows); 
1, AutoCommit — 是否自动提交
通常来讲自动提交不利于应用程序的性能.
$dbh->{AutoCommit} = 1;
print “AutoCommit: $dbh->{AutoCommit}\n”;
2, ChopBlanks — 取舍CHAR类型后面的空格
当你从数据库中取CHAR类型的值时, 你能够指定要不要带后面的空格, 在数据库中CHAR是定长的, 长足不足时, 后面以空格补充, 但你在写应用程序时, 可能并不想要后面的空格, 这时你能够将这个选项设为1.
$dbh->{ChopBlanks} = 1;
print “ChopBlanks: $dbh->{ChopBlanks}\n”;
3, LongTruncOK — 是否容许载断返回值
若是返回值(如Long或LOB类型)的值大于缓冲区的长度, 有两个选项, 一种是报错, 另外一种是只取缓冲区的长度的值, 丢弃后面的值. 设为True, 则不报错而只取一部份值, 设为False则报错.
$dbh->{LongTruncOk} = 1;
print “LongTruncOk: $dbh->{LongTruncOk}\n”;
4, LongReadLen — 指定Long或LOB缓冲的最长大度
在数据库中, Long或LOB类型能够存放2GB或更多的值, 在Perl应用程序去取这些值时, 必需要指定一个最大的缓冲区大小, 和LongTruncOk配合, 能够取出必定长度的值.
$dbh->{LongReadLen} = 1048576;
print “LongReadLen: $dbh->{LongReadLen}\n”;
### We're not expecting binary data of more than 512 KB...
$dbh->{LongReadLen} = 512 * 1024;
### Select the raw media data from the database
$sth = $dbh->prepare( "
SELECT mega.name, med.media_data
FROM megaliths mega, media med
WHERE mega.id = med.megaliths_id
" );
$sth->execute();
while ( ($name, $data) = $sth->fetchrow_array ) {
...
}

转载于:https://blog.51cto.com/ylive/506168html