PerlDBI

2026/1/15 17:33:14

当然,在以这种方式使用一列变量时,必须保证查询按正确的次序选择列。DBI 不关心SELECT 语句指定列的次序,所以正确地分配变量是您的职责。在提取行时,使用一种称为参数约束的技术,也可以使列值自动分配给单独的变量。

fetchrow_arrayref( ) 类似于fetchrow_array( ),但不返回包含当前行的列值的数组,而是返回这个数组的引用,在没有乘余行时,返回un d e f。如下使用:

通过数组引用$ary_ref 访问数组元素。这类似于引用指针,所以使用了$ary_ref->[$i] 而不是$ a r y [ $ i ]。要想引用整个数组,就要使用@{$ary_ref} 结构。

fetchow_arrayef( ) 不适合在列表中提取变量。例如,下面的循环不起作用:

实际上,只要fetchrow_arrayref( ) 提取一行,这个循环就能正确地运行。但是在没有更多的行时, fetchrow_arrayref( ) 返回un d e f,并且@{undef} 不合法(它有些像在C 程序中试图废弃一个NULL 指针)。

提取行的第三个方法fetchrow_hashref( ),如下使用:

对fetchrow_hashref( ) 的每个调用都返回一个按列名索引的行值散列的引用,在没有更多的行时,返回un d e f。在此情况下,列值不按特定的次序出现; Perl 散列的成员是无序的。然而,散列元素是按列名索引的,所以$hashref 提供了一个单独的变量,可通过它按名称访问任何列值。这使得能按任意需要的次序来提取值(或者它们中的任何子集),而且不必知道SELECT 查询检索的列的次序。例如,如果想访问名称和电子邮件域,可以如下进行:

如果希望将一行值传递给某个函数而又不需要这个函数知道SELECT 语句中指定列的次序时,fetchrow_hashref( ) 是非常有用的。既然如此,可以调用fetchrow_hashref( ) 来检索行,并且编写一个使用列名访问来自行散列值的函数。

如果使用fetchrow_hashref( ),请记住下列警告:

如果性能很重要,则fetchrow_hashref( ) 并不是最好的选择,因为它没有fetchrow_array( ) 或fetchrow_arrayref( ) 的效率高。

作为散列键值使用的列名具有与SELECT 语句中写出时相同的字符。在MySQL中,列名不区分大小写,所以此查询也是这样,不管以大写字母还是小写字母给出列名,查询结果都是一样的。但是Perl 散列索引名是区分大小写的,这可能会带来一些问题。为了避免潜在的大小写不匹配问题,可通过传递NAME_lc 或NAME_uc 属性,告知fetchrow_hashref( ) 强迫列名为大写或小写:

散列对每个唯一的列名含有一个元素。如果正在执行从多个具有重叠名称的表中返回列的连接,则不能访问所有的列值。例如,如果发布下面的查询, fetchrow_hashref( )将返回只有一个元素的散列: SELECT a.name FROM a,b WHERE a.name=b.name 2. 确定查询返回的行数

如何知道SELECT 或类似于SELECT 的查询返回的行数?一种方法是,当提取它们时,计算这些行的数量。实际上,这是知道SELECT 查询返回多少行的唯一方便的方法。使用MySQL驱动程序,可以在调用execute( ) 后利用语句句柄调用rows( ) 方法,但是这对其他数据库引擎并不方便。而且即使就MySQL来说,如果已经设置了mysql_use_result 属性,rows( ) 也不能返回正确的结果,直到提取了所有行(有关的详细信息,请参阅附录G)。所以只能如提取行一样对它们进行计数。 3. 提取单行的结果

如果结果集只含单个行,则不需要运行循环来获得结果。假设要编写得出历史同盟成员当前数量的脚本count _ member s。完成查询的代码如下所示:

SELECT 语句只返回一行,所以不需要循环;我们只调用fetchrow_array( ) 一次。另外,因为我们只选择一列,所以甚至不需要将返回值分配给数组。当在标量环境中(单个值而不是所期望的一列)调用fetchrow_array( ) 时,它返回这个行的第一列,如果没有更多的有效行,则返回un d e f。

另一种期望最多有一个记录的查询是一个含有LIMIT 1来约束返回的行数的查询。其一般的用法是返回特定列含有最大或最小值的行。例如,下面的查询给出最近出生的总统姓名和出生日期:

必须无提取循环的其他类型的查询利用MAX( ) 或MIN( ) 来选择单个值。但是在所有这些情况下,获得单个行结果的一种更容易的方法就是使用数据库句柄方法selectrow_array( ),它结合了prepare( )、execute( ) 并在单个调用中提取行。它返回一个数组(而不是一个引用),如果出现错误,则返回一个空数组。前一例子可利用selectrow_array( ) 编写如下:

4. 处理完整的结果集

在使用提取循环时, DBI 不提供在结果集中随意查找的方法,或以任何次序而不是以循环返回的次序来处理行。同样,提取行以后,如果没有保存,前一行会丢失。这种做法并不一定合适以下情况: 以非连续的次序处理行。考虑一种情况,想以历史同盟的president 表中列出的美国总统为主体,进行一些测验。如果希望每次测验时都以不同的次序提出问题,则可以从president 表中选择所有行。然后,可能以任意的次序提取行来改变与所问问题有关的总统的次序。要想任意地提取一行,就必须同时访问所有的行。

只使用返回行的子集,对其进行随机选择。例如,当问及总统出生地时,要想出现多个选择的问题,则可以随便地提取一行来选择总统(正确的答案),然后再从取来干扰的选择中提取若干其他行。 即使确实以连续的次序去处理,也想紧紧抓住整个结果集。如果想经过这些行进行多个传递,这可能是必需的。例如,在统计计算中,可能先浏览一遍结果集,来估计数据的一些通用数字属性,然后再次检查这些行,来实现更加明确的分析。

可以用几个不同的方式作为一个整体访问结果集。可以完成这个常见的提取循环,并在提取它时保存每一行,可以使用一次返回整个结果集的方法。无论哪种方法都以在结果集中包括一行一行的矩阵作为结束,和选择的列一样多。可以以任何次序任意多次地处理矩阵的 元素。下面的讨论说明这两种方法。

使用提取循环来捕获结果集的一种方法是使用fetchrow_array( ) 并保存对这些行引用的数组。除了保存所有的行,然后显示矩阵举例说明了如何确定矩阵中的行数和列数,及如何访问矩阵的个别成员以外,下面的代码和dump_members 中提取和显示的循环作用是一样的。

在确定矩阵的维数时,必须首先确定行数,因为无论这个矩阵是否为空,都可能计算列数。如果$rows 为0,则这个矩阵为空,并且$cols 也为0。否则,列数可能作为行数组中的元素数量来计算,用语法@{$matrix[$i]} 来整体访问行$ i。

在前述的样例中, 我们提取每一行, 然后保存对它的引用。可以设想调用fetchrow_arrayref( ) 而不是直接地检索行引用可能更有效率:

它不能正常工作,因为fetchrow_arrayref( ) 重新使用了引用指向的数组。结果矩阵是一个引用的数组,数组中的每个元素都指向相同行—最后检索的行。因此,如果想一次提取一行,则要使用fetchrow_array( ) 而不是fetchrow_arrayref( )。

另一个选择是使用提取循环,可以使用返回整个结果集的DBI 方法中的一个。例如,

fetchall_arrayref( ) 返回对引用数组的引用,数组的每个元素都指向结果集中某行。这非常简单,但很有效,这个返回值是对矩阵的引用。要想使用fetchall_arrayref( ),则调用prepare( )和execute( ),然后如下检索结果:


PerlDBI.doc 将本文的Word文档下载到电脑
搜索更多关于: PerlDBI 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219