Существует ли способ снова использовать? используемый на DBI готовят оператор. Рассмотрите следующий код:
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?),C(?)");
$sth->execute($a,$a,$a);
Было бы очень хорошо вместо этого использовать что-то вроде этого:
#I'm making this up as something I hope exists
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?:1),C(?:1)");
$sth->execute($a);
Заметьте это только один $a
передается выполнению вместо три. Существует ли способ сделать это в реальной жизни?
Это зависит от вашего DBD. Например, используя DBD :: Pg со стилем заполнителей $ 1
или DBD :: Oracle с именованными заполнителями и bind_param
, вы можете делать именно то, что вам нравится. Но использовать стиль заполнителей общего назначения ?
, который работает в масштабе DBI, невозможно.
Если вы используете библиотеку для генерации SQL-запросов, например, SQL::Abstract или полноценный ORM, такой как DBIx::Class, вам не придется беспокоиться о подобных вещах.
В качестве альтернативы вы можете сделать нечто подобное с помощью нескольких строк кода:
my $sql = 'INSERT INTO ...blah blah... VALUES (' . (join(', ', ('?') x scalar(@insert_elements))) . ')';
@hobbs ' ответ правильный - заполнители DBI по умолчанию не могут этого сделать. @ Ether ответ правильный - абстракция SQL может сделать это несложным.
Однако обычно требуется привязать каждое отдельное параметризованное значение только один раз .В вашем примере использование скалярной производной таблицы делает предоставленное пользователем значение доступным по имени для остальной части запроса:
my $sth = $dbh->prepare(<<'__eosql');
INSERT INTO mytable(a,b,c)
SELECT x, B(x), C(x) FROM (SELECT ? AS x) subq
-- Subquery may vary from DB to DB:
-- "FROM (SELECT ? AS x FROM DUAL) subq"
-- "FROM (SELECT ? FROM rdb$database) subq(x)"
-- "FROM (VALUES (?)) subq(x)"
-- etc.
__eosql
for $v (@values) {
$sth->execute($v);
}
Обычно это постепенно более "эффективное соединение", чем альтернатива, поскольку пользователь -поставленный параметр обычно передается только один раз вместо N раз.