如何从SQL查询中获取多个列并将它们存储在perl中的二维数组中

时间:2017-07-29 19:02:37

标签: mysql arrays perl dbi dbd

假设我有一个类似的查询:

my $sql = "SELECT dev_name,
                  OID_name,
                  Obj_Val
           FROM dev_logs";

表中的值类似于

+----+------------+----------------------+---------+---------------------+
| id | dev_name   | OID_name             | Obj_Val | timeStamp           |
+----+------------+----------------------+---------+---------------------+
|  1 | iKazatseva | ubntWlStatRssi       | 29      | 2017-07-22 15:18:34 |
|  2 | iKazatseva | ubntWlStatSignal     | -67     | 2017-07-22 10:12:32 |
|  3 | iKazatseva | ubntWlStatCcq        | 91      | 2017-07-22 15:18:34 |
|  4 | iKazatseva | ubntWlStatNoiseFloor | -96     | 2017-07-27 16:45:24 |
+----+------------+----------------------+---------+---------------------+

如何将查询返回的值存储在2D数组中,如下所示?

+------------+----------------------+---------+
| dev_name   | OID_name             | Obj_Val |
+------------+----------------------+---------+
| iKazatseva | ubntWlStatRssi       | 29      |
| iKazatseva | ubntWlStatSignal     | -67     |
| iKazatseva | ubntWlStatCcq        | 91      |
| iKazatseva | ubntWlStatNoiseFloor | -96     |
+------------+----------------------+---------+

我已经尝试过一些东西,但我能得到的就是将它们绑定在一个像1d这样的数组中:

my @devLogsArr = $dbh->selectall_arrayref($sql);

my @OID_names= map {$_->[1]}
  @{$dbh->selectall_arrayref($sql)};

或将它们绑定在变量中:

$sth->bind_col(1, \$devname);
$sth->bind_col(2, \$OID);
$sth->bind_col(3, \$value);

print "$devname\t$OID\t$value\n" while $sth->fetchrow_arrayref;

my @devLogsArr;
push(@devLogsArr, (devname=> $devname, OID=> $OID, value=> $value))
while $sth->fetchrow_arrayref;

但它远非我想做的事情。我知道我可以通过查询每个列的数据库来完成,但这将是多余的。

我在这里问的是可行的吗?

提前致谢。

1 个答案:

答案 0 :(得分:3)

selectall_arrayref()会返回数组引用。见it in DBI。 因此我们可以将其用作

my $all_rows = $dbh->selectall_arrayref($sql);

将其分配给变量,标量$all_rows。要取消引用这个并创建一个数组

my @all_rows = @{ $all_rows };

其中我使用相同的名称(“all_rows”)仅显示具有相同名称的标量($)和数组(@)是不同的变量。这不是我建议的做法,因为可能导致混淆;仔细选择名字。在这种情况下,不需要{ }@$all_rows就可以了。

现在您可以打印内容

foreach my $row (@all_rows) { 
    print "@$row\n";
}

从数组中检索的每个$row本身就是一个arrayref,因此我们取消引用它(@$row)或

print "@$_\n" for @all_rows;

引用非常方便工作,因此创建具有行的实际数组可能没有多大理由;把它保存在$all_rows中。打印出来

print "@$_\n" for @$all_rows;

其中@$all_rows取消引用$all_rows并创建for迭代的列表,将每个元素放入特殊$_ variable。然后取消引用@$_,并在"@$_"中插入print,以便我们在元素之间获得空格以便清晰读出。

文献:教程perlreftut,食谱perldsc和参考perlref

现在,为了以某种方式添加列名,重要的是首先阐明这样做的目的。如果它是一个查找,那么应该通过什么来查找?如果按列名查询,那么您希望如何访问行的元素?通过索引,还是以某种方式再次通过名称?您是否希望能够方便地迭代它?保持列的oder?

此时我们实际上正在实现关系数据库样式功能。

所以也许只是保持简单。 arrayref包含信息,为了显示,您可以先打印列名。格式化可以通过printf进行处理,详情请参见sprintf