2010-01-03 2 views
6

Кажется, что это может быть невозможно, но эй, я мог бы также спросить, я мог ошибаться. Интересно, есть ли в любом случае для perl для обновления нескольких строк с использованием одного вызова MySQL, я использую DBI.Perl: обновить несколько строк с одним вызовом MySQL

Любая помощь или обратная связь были бы очень признательны, это возможно в MSSQL через ASP и ASP.net, поэтому было интересно, возможно ли также и через perl на MySQL.

Благодарим вас за отзыв!

+0

в вашем примере, нет никаких причин, чтобы не объединить эти два обновления в один; можете ли вы привести пример, похожий на обновления, которые вам действительно нужны? – ysth

ответ

14

Прежде всего, вы абсолютно не должны интерполировать переменные непосредственно в ваши строки SQL. Это оставляет открытой возможность инъекций SQL-инъекций. Даже если эти переменные не поступают с пользовательского ввода, это оставляет открытой возможность опасных ошибок, которые могут испортить ваши данные.

DBD-драйвер MySQL поддерживает несколько операторов, хотя по умолчанию он отключен как функция безопасности. См. mysql_multi_statements в разделе Class Methods в документации DBD :: mysql.

Но гораздо лучшее решение, которое одновременно решает обе проблемы и является более переносимым, заключается в использовании подготовленных операторов и значений заполнителей.

my $sth = $dbh->prepare("UPDATE LOW_PRIORITY TableName SET E1=?,F1=? WHERE X=?"); 

Затем, получить данные в петле своего рода:

while($whatever) { 
    my ($EC, $MR, $EM) = get_the_data(); 
    $sth->execute($EC, $MR, $EM); 
} 

Вам нужно только подготовить заявление один раз, а значения заполнителей заменяются (и гарантированно будет цитироваться) по драйвер DBD.

Подробнее о заполнителях в DBI docs.

+3

«Драйвер DBD» - это только специфический для сервера драйвер, используемый DBI, например DBD :: mysql. В любом случае вам не нужно беспокоиться о соединениях, но в любом случае - если вы продолжаете использовать один и тот же '$ dbh' для запуска операторов, вы будете использовать одно и то же соединение с базой данных и« подготовить один раз, выполнить многие «модели», продемонстрированные friedo, будут более эффективными, чем передача многих запросов в одной строке, поскольку это позволяет избежать накладных расходов, связанных с необходимостью индивидуального анализа (подготовки) каждого запроса. –

+3

@mastermind: интерполяция всегда плохая, независимо от того, что приложение; многие уязвимости возникают из-за ошибки программиста, а не от пользователя. – Ether

3

Вам не нужны mysql_multi_statements, как предлагает friedo.

Вам нужно отключить режим AutoCommit перед вызовом цикла, содержащий вашу команду UPDATE:

**$dbh->{AutoCommit} = 0;** 
while($condition) { 
    my $myParam = something(); 
    ... 
    $sth->execute($myParam); #your prepared UPDATE statement 
    ... 
} 
**$dbh->commit();** 
Смежные вопросы