2010-01-03 25 views
6

Parece que no es posible, pero bueno, podría preguntar, podría estar equivocado. Me preguntaba si hay alguna forma de que perl actualice varias filas usando una llamada MySQL, estoy usando DBI.Perl: actualizar varias filas con una llamada de MySQL

Cualquier ayuda o comentario sería muy apreciado, esto es posible en MSSQL a través de ASP y ASP.net así que me pregunto si también es posible a través de Perl en MySQL.

¡Gracias por sus comentarios!

+0

en su ejemplo, no hay razón para no combinar las dos actualizaciones en uno; ¿Puedes dar un ejemplo más parecido a las actualizaciones que realmente necesitas hacer? – ysth

Respuesta

14

Lo primero y más importante es que no debe interpolar las variables directamente en sus cadenas de SQL. Eso deja abierta la posibilidad de ataques de inyección SQL. Incluso si esas variables no provienen de la entrada del usuario, deja abierta la posibilidad de errores peligrosos que pueden arruinar sus datos.

El controlador MySQL DBD es compatible con varias instrucciones, aunque está desactivado de forma predeterminada como una característica de seguridad. Consulte mysql_multi_statements en la sección Class Methods en la documentación DBD :: mysql.

Pero una solución mucho mejor, que resuelve ambos problemas a la vez y es más portátil, es usar declaraciones preparadas y valores de marcador de posición.

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

A continuación, obtener sus datos en un bucle de algún tipo:

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

sólo es necesario para preparar el estado de una vez, y los valores de marcador de posición se sustituyen (y la garantía de ser adecuadamente citado) por el controlador DBD.

Más información sobre los marcadores de posición en el DBI docs.

+3

El "controlador DBD" es solo el controlador específico de back-end utilizado por DBI, como DBD :: mysql. No necesita preocuparse por las conexiones, sin embargo, en cualquier caso, siempre y cuando siga usando el mismo '$ dbh' para ejecutar las declaraciones, usará la misma conexión de base de datos y la 'preparación una vez, ejecutar muchos 'modelos demostrados por friedo será más eficiente que pasar muchas consultas en una sola cadena, ya que evita la sobrecarga de tener que analizar (preparar) cada consulta individualmente. –

+3

@mastermind: la interpolación siempre es mala, sin importar la aplicación; muchas vulnerabilidades surgen de un error del programador en lugar de una travesura del usuario. – Ether

3

No necesita mysql_multi_statements, como sugiere friedo.

Usted necesita apagar el modo AutoCommit antes de llamar al bucle que contiene el comando UPDATE:

**$dbh->{AutoCommit} = 0;** 
while($condition) { 
    my $myParam = something(); 
    ... 
    $sth->execute($myParam); #your prepared UPDATE statement 
    ... 
} 
**$dbh->commit();** 
Cuestiones relacionadas