2017-06-16 1 views
0

Die Frage ist einfacher als es klingt (denke ich). Ich habe eine Datenbanktabelle table und ich versuche, Daten in die Spalte first eingefügt werden. Hier ist ein Teil des Codes:Perl - Einfügen von Daten in SQL beim Lesen der Spalten aus einem Array?

my $stmt = $dbh->prepare($sql); 
@array=("first","second","third");  
$sql = "INSERT INTO table($array[0]) VALUES(?)"; 
$stmt->execute($some_value); 

Das Programm ohne Warnung ausgeführt wird, aber es füllt einfach die Tabelle mit 0, die von $some_value unterscheidet.

+1

Sie verwenden '$ sql' in der' prepare' Anweisung, bevor Sie ihr einen Wert zuweisen? Ist das richtig? – mob

+1

@mob Ich denke nicht, dass es richtig ist, aber es ist wahr ;-) – PerlDuck

+4

Sie können die SQL nicht ändern, nachdem Sie die Anweisung vorbereitet haben und erwarten, dass es funktioniert! –

Antwort

5

Zunächst ist die Benennung einer Tabelle table eine schlechte Idee, weil es wahrscheinlich ist, dass Sie seinen Namen hin und wieder entgehen müssen.

Zweitens sind Ihre Aussagen in der falschen Reihenfolge. Sie bereiten zuerst eine Anweisung (mit unbekanntem Inhalt) vor und weisen dieser Variablen dann nur eine SQL-Anweisung zu.

Try this:

my @columns = ("first","second","third");  
my $sql = "INSERT INTO table(" . $dbh->quote_identifier($columns[0]) . ") VALUES(?)"; 
my $stmt = $dbh->prepare($sql); 
$stmt->execute($some_value); 

ich dies nicht getestet, aber es kann notwendig sein

my $sql = "INSERT INTO `table` (" . $dbh->quote_identifier($columns[0]) . ") VALUES(?)"; 

zu schreiben, weil table ein Schlüsselwort in SQL ist. Nenne es besser nach den Dingen, die es enthält, nicht nach seiner Form.

Wie @ikegami in einem Kommentar darauf hingewiesen, ist es auch besser, den DBI-Treiber die Spaltennamen (mit quote_identifier() anstatt direkt zu verwenden) zu zitieren, weil es immer gefährlich ist, SQL-Anweisungen aus (nicht vertrauenswürdigen) Variablen zu erstellen.


Vielleicht sind Sie verwirrt, wie Anweisung Vorbereitung funktioniert. Die grundlegende Aussage kann nicht nach einem Aufruf prepare variiert werden, was bedeutet, in

INSERT INTO mytable (col1, col2) VALUES (?,?) 

Sie unterschiedliche Werte für die beiden ? Platzhalter liefern kann und dann die gleiche Aussage mit unterschiedlichen Werten für diese ? s erneut auszuführen. Zum Beispiel ist es nicht möglich

INSERT INTO ? (?, ?) VALUES (?,?) 

und dann zu schreiben prepare diese Aussage und dann

läuft
$sth->execute('my_table', 'col1', 'col2', 'val1', 'val2'); 

Das wird nicht funktionieren.


Wenn Sie zwei verschiedene INSERT-Anweisungen (für zwei verschiedene Spalten) ausführen möchten, müssen Sie zweimal vorgehen.Je nach Ihrem konkreten Fall können Sie entweder

my $stmt_for_col1 = $dbh->prepare("INSERT INTO my_table (col1) VALUES (?)"); 
my $stmt_for_col2 = $dbh->prepare("INSERT INTO my_table (col2) VALUES (?)"); 

und führen Sie dann die beiden Aussagen so oft wie Sie möchten und in beliebiger Reihenfolge:

$stmt_for_col1->execute('value_for_col1'); 
$stmt_for_col2->execute('value_for_col2'); 
$stmt_for_col1->execute('value_for_col1'); 

oder Verwendung nur eine Anweisung zu einem Zeitpunkt, :

my $stmt = $dbh->prepare("INSERT INTO my_table (col1) VALUES (?)"); 
$stmt->execute('value_for_col1'); 
$stmt->execute('value_for_col1'); 

$stmt = $dbh->prepare("INSERT INTO my_table (col2) VALUES (?)"); 
$stmt->execute('value_for_col2'); 
$stmt->execute('value_for_col2'); 

Der prepare Schritt pro Anweisung einmal erfolgt, Der Schritt execute kann (und wird oft) in einer Schleife ausgeführt werden, damit die Anweisung mit anderen Werten ausgeführt wird.

+0

Sie haben Recht, meine Verwirrung lag an der Tatsache, dass ich nicht wusste, wie man eine Prepare-Execute-Sequenz in einer Schleife vermeidet. –

Verwandte Themen