Как получить несколько столбцов из запроса SQL и сохранить их в 2d массиве в perl
Предположим, у меня есть запрос вроде:
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 |
+----+------------+----------------------+---------+---------------------+
Как я могу сохранить значения, возвращаемые запросом, в двумерном массиве, как показано ниже?:
+------------+----------------------+---------+
| 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 ответ
selectall_arrayref()
возвращает ссылку на массив. Смотрите это в 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
перебирает, помещая каждый элемент в специальную переменную $_. Это тогда разыменовывается @$_
и интерполировал "@$_"
в print
Таким образом, мы получаем пробелы между элементами для четкого чтения.
Литература: учебник perlreftut, поваренная книга perldsc и справочник perlref.
Теперь, чтобы каким-то образом добавить к этому имена столбцов, важно сначала сформулировать цель этого. Если это для поиска, то что нужно искать чем? Если вы делаете запрос по имени столбца, то как вы хотите иметь доступ к элементам строки? По индексу или опять по имени как-нибудь? Хотите ли вы иметь возможность удобно проходить через него? Поддерживать одер столбцов?
На данный момент мы практически реализуем функциональность стиля реляционной базы данных.
Так что, возможно, просто будь проще. У arrayref есть информация, и для отображения вы можете сначала напечатать имена столбцов. О форматировании можно позаботиться через printf, подробности доступны в sprintf.