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

How to fetch multiple columns from SQL query and store them in 2d array in perl

假设我有这样的查询:

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

其中 table 的值类似于

+----+------------+----------------------+---------+---------------------+
| 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 |
+----+------------+----------------------+---------+---------------------+

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

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

我已经尝试了一些东西,但我所能得到的就是将它们绑定在一维数组中,例如:

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;

但这与我想做的相去甚远。我知道我可以通过为每个单独的列查询数据库来完成,但这将是多余的。

我这里问的可行吗?

提前致谢。

selectall_arrayref() returns 一个 数组引用 。参见 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 本身就是一个数组引用,因此我们取消引用它 (@$row),或者

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

引用对工作来说非常方便,因此可能没有太多理由创建包含行的实际数组;只需将其保存在 $all_rows 中即可。打印出来

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

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

文献:教程perlreftut, cookbook perldsc, and reference perlref.


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

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

所以也许只是保持简单。 arrayref 有信息,为了显示,您可以先简单地打印列名。可以通过 printf, with details available in sprintf.

处理格式化