Многократное использование? на DBI готовятся

Существует ли способ снова использовать? используемый на 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 передается выполнению вместо три. Существует ли способ сделать это в реальной жизни?

8
задан User1 5 July 2010 в 16:22
поделиться

3 ответа

Это зависит от вашего DBD. Например, используя DBD :: Pg со стилем заполнителей $ 1 или DBD :: Oracle с именованными заполнителями и bind_param , вы можете делать именно то, что вам нравится. Но использовать стиль заполнителей общего назначения ? , который работает в масштабе DBI, невозможно.

7
ответ дан 5 December 2019 в 10:39
поделиться

Если вы используете библиотеку для генерации SQL-запросов, например, SQL::Abstract или полноценный ORM, такой как DBIx::Class, вам не придется беспокоиться о подобных вещах.

В качестве альтернативы вы можете сделать нечто подобное с помощью нескольких строк кода:

my $sql = 'INSERT INTO ...blah blah... VALUES (' . (join(', ', ('?') x scalar(@insert_elements))) . ')';
4
ответ дан 5 December 2019 в 10:39
поделиться

@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 раз.

3
ответ дан 5 December 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: