Вы уже довольно далеко. Замечательно, что у вас уже есть the placeholders (?
). Все, что вам нужно сделать, это передать параметр as an argument to execute
. Он автоматически заполнит их в заполнителях, в том порядке, в котором они появятся в вашем запросе.
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect('dsn goes here', 'user', 'password') or die $DBI::errstr;
# stuff happens ...
my $prod_id = 1337; # or whatever
my $sql =
'SELECT
node_id
FROM
pagenodes
INNER JOIN
pageproducts
ON
pagenodes.node_id = pageproducts.nodeid
INNER JOIN
products
ON
pageproducts.prodid = products.prodid
WHERE
products.prodid = ?
LIMIT 1';
my $sth = $dbh->prepare($sql);
$sth->execute($prod_id); # no `my` here!
LIMIT
в этом случае не имеет значения. Он также будет работать в цикле.
Обратите внимание, что у вас есть my
перед линией execute
. Это неправильный синтаксис. my
используется для , объявляет переменных, но в этой строке вы вызываете метод только для уже существующего объекта дескриптора. Возвращаемое значение для метода execute
, но обычно не назначается переменной. Если возвращаемое значение истинно, execute
был успешным. Если это ложь, что-то пошло не так. Вы также можете использовать or
до check for errors.
$sth->execute or die $dbh->errstr;
Теперь, чтобы получить одно значение из базы данных, вы можете use fetchrow_array
in list context.
(my $node_id) = $sth->fetchrow_array;
Это даст вам единственный node_id
, один раз.
Если вы намерены получить только одно значение и вызывать только один раз, вы также можете сохранить несколько строк кода и use selectrow_array
instead.
(my $node_id) = $dbh->selectrow_array('SELECT node_id FROM foo WHERE prodid=? LIMIT 1', undef, $prod_id);
Опять же, контекст список имеет важное значение, потому что fetchrow_array
и selectrow_array
возвратных списков, а не ссылки на массив. Без ()
вокруг левой стороны он назначил количество результатов (из-за скалярного контекста).
Если, однако, вы хотите сделать все это в цикле для совокупности значений, это выглядит несколько иначе. В этом случае сделайте свою подготовку вне цикла и только execute
и fetchrow_array
(или любой другой метод fetchrow_*
) внутри цикла. Это сделает его значительно быстрее.
my $sth = $dbh->prepare($sql);
foreach my $prod_id (@prod_ids) {
$sth->execute($prod_id);
(my $node_id) = $sth->fetchrow_array;
print "$node_id\n";
}
Может также проверить [прекрасные слайды презентации Тим Банс на передовой DBI в OSCON] (http://www.slideshare.net/Tim.Bunce/dbi-advanced-tutorial-2007). – simbabque
Спасибо за это.Я, кажется, вытаскиваю ошибку: «Глобальный символ« $ dbh »требует явного имени пакета« Я просто смотрю на это. –
@ Liam загрузил DBI и вообще подключился к базе данных? – simbabque