2010-01-03 8 views
6

Scheint, dass es nicht möglich sein kann, aber hey ich könnte genauso gut fragen, ich könnte falsch liegen. Ich frage mich, ob es sowieso Perl gibt, um mehrere Zeilen mit einem MySQL-Aufruf zu aktualisieren, ich benutze DBI.Perl: Update mehrere Zeilen mit einem MySQL Call

Jede Hilfe oder Feedback würde sehr geschätzt werden, dies ist in MSSQL durch ASP und ASP.net möglich, so fragte mich, ob auch durch Perl auf MySQL möglich.

Vielen Dank für Ihr Feedback!

+0

in Ihrem Beispiel, gibt es keinen Grund, nicht die beiden Updates zu einem kombinieren; Können Sie ein Beispiel mehr wie die Updates geben, die Sie tatsächlich tun müssen? – ysth

Antwort

14

Zuerst und am wichtigsten, sollten Sie Variablen nicht direkt in Ihre SQL-Zeichenfolgen interpolieren. Das lässt die Möglichkeit von SQL-Injection-Angriffen offen. Selbst wenn diese Variablen nicht von Benutzereingaben stammen, können gefährliche Fehler auftreten, die Ihre Daten beschädigen können.

Der MySQL DBD-Treiber unterstützt mehrere Anweisungen, obwohl er standardmäßig als Sicherheitsfunktion deaktiviert ist. Siehe mysql_multi_statements unter dem Class Methods Abschnitt in der DBD :: mysql-Dokumentation.

Aber eine viel bessere Lösung, die beide Probleme auf einmal löst und portabler ist, ist die Verwendung vorbereiteter Anweisungen und Platzhalterwerte.

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

Dann erhalten Sie Ihre Daten in einer Schleife von einer Art:

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

Sie müssen nur die Anweisung einmal vorbereiten und die Platzhalter-Werte ersetzt werden (und garantiert richtig zitiert werden) durch der DBD-Treiber.

Lesen Sie mehr über Platzhalter in der DBI docs.

+3

Der "DBD-Treiber" ist nur der Backend-spezifische Treiber, der von DBI verwendet wird, z. B. DBD :: mysql. Sie müssen sich in jedem Fall keine Gedanken über die Verbindungen machen. Solange Sie die $ dbh für die Ausführung der Anweisungen verwenden, verwenden Sie dieselbe Datenbankverbindung und die Einmalvorbereitung. execute many 'Das von friedo demonstrierte Modell ist effizienter als das Übergeben vieler Abfragen in einer einzigen Zeichenfolge, da es den Aufwand vermeidet, jede Abfrage einzeln analysieren (vorbereiten) zu müssen. –

+3

@mastermind: Interpolation ist immer schlecht, egal was die Anwendung; Viele Sicherheitslücken entstehen durch Programmierfehler und nicht durch Unfug des Benutzers. – Ether

3

Sie brauchen keine mysql_multi_statements, wie friedo vorschlägt.

Sie müssen deaktivieren Autocommitmodus, bevor Sie die Schleife mit Ihrem UPDATE Befehl aufrufen:

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