如何从 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 中。然后取消引用 @$_
,并在 print
ing 中插入 "@$_"
,这样我们就可以在元素之间留出空间,以便清晰读出。
文献:教程perlreftut, cookbook perldsc, and reference perlref.
现在,为了以某种方式添加列名,首先阐明这样做的目的很重要。如果是查找,那么应该通过什么来查找?如果您按列名查询,那么您希望如何访问行的元素?通过索引,还是以某种方式再次通过名称?您是否也希望能够方便地迭代它?维护列的顺序?
此时我们实际上是在实现关系数据库样式的功能。
所以也许只是保持简单。 arrayref 有信息,为了显示,您可以先简单地打印列名。可以通过 printf, with details available in sprintf.
处理格式化
假设我有这样的查询:
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 中。然后取消引用 @$_
,并在 print
ing 中插入 "@$_"
,这样我们就可以在元素之间留出空间,以便清晰读出。
文献:教程perlreftut, cookbook perldsc, and reference perlref.
现在,为了以某种方式添加列名,首先阐明这样做的目的很重要。如果是查找,那么应该通过什么来查找?如果您按列名查询,那么您希望如何访问行的元素?通过索引,还是以某种方式再次通过名称?您是否也希望能够方便地迭代它?维护列的顺序?
此时我们实际上是在实现关系数据库样式的功能。
所以也许只是保持简单。 arrayref 有信息,为了显示,您可以先简单地打印列名。可以通过 printf, with details available in sprintf.
处理格式化