2016-04-23 3 views
0

Versuch, ein SQL-Update für Postgres zu machen 9. Beachten Sie die $ 1 auf der linken Seite des Gleichheitszeichens. Das ist der Name einer Spalte in einer Tabelle, die übergeben wird. Wenn ich einen Spaltennamen fest codiere, funktioniert das Update perfekt. Aber wenn ich versuche, die Spalte als Parameter ($ 1) zu übergeben, schlägt die Aktualisierung fehl. Warum und wie repariere ich das?sql Positionsparameter auf der linken Seite eines Gleichheitszeichens

pg.connect(connectionString,function (err, client) { 
    client.query("UPDATE people SET $1 = $2 WHERE pin = $3 RETURNING pin", 
     [param1, param2, param3], function(err, result){ 
     if(err) { 
      console.log("Error updating data: ", err); 
      res.send(false); 
     }else{ 
      res.send(true); 
     } 
     }); 
    }); 
+0

Sie können sich Spaltennamen ähnlich wie Variablennamen in anderen Sprachen vorstellen, so dass Platzhalter für sie ähnlich wie "eval" sind, so dass es im Allgemeinen nicht erlaubt ist. Überprüfen Sie die Dokumentation Ihrer Datenbankschnittstelle auf eine "Quote Identifier" - oder "Escape Identifier" -Funktion, verwenden Sie diese Funktion, um 'param1' richtig zu zitieren, und verwenden Sie eine String-Verkettung, um den in Anführungszeichen gesetzten Wert in Ihr SQL zu bekommen. Beachten Sie, dass Bezeichner (z. B. Tabellen- oder Spaltennamen) andere Anführungsregeln als Werte haben, also achten Sie darauf, die richtige Anführungsfunktion zu verwenden. –

Antwort

0

client.query verwendet vorbereitete Anweisung intern, so dass Ihre Abfrage in zwei SQL-Anweisungen ausgeführt wird:

PREPARE some_generated_name AS 
UPDATE people SET $1 = $2 WHERE pin = $3 RETURNING pin; 

EXECUTE some_generated_name('data1', 'data2', 'data3'); 

Dies ist ein sinnvoller Ansatz ist, wenn Sie die gleiche Abfrage viele Male ausgeführt werden soll. PREPARE teilt PostgreSQL mit, die vorausgehende Abfrage zu parsen und zu planen, weil viele Anweisungen kommen und er sollte dafür bereit sein.

Dann tut PostgreSQL alles, was er im Voraus tun kann, einschließlich Parsing und Planung. Parsen bedeutet, dass er die Abfrage syntaktisch validiert und "versteht". Planung bedeutet, dass er antizipiert, welche Operation auf welcher Tabelle ausgeführt wird.

Dies ist der Teil, in dem PostgreSQL versucht, das deklarative SQL in einen prozeduralen Satz von Anweisungen umzuwandeln, wie "diese bestimmte Tabelle holen", "diese Spalte in dieser Tabelle aktualisieren, wo diese Spalte mit dieser Variablen übereinstimmt", ... Übung dieses System ist viel komplexer, aber sehr interessant)

Das Problem ist, dass das Parsen mit einem dynamischen Spaltennamen nicht möglich ist, so lehnt PostgreSQL zu PREPARE Ihre Abfrage ab.

Sie sollten keine Spaltenvariablen verwenden. Sie müssen feste benannte Spalten verwenden, da Sie eine begrenzte Anzahl bekannter Spalten haben. Verwenden Sie eine Whitelist, um die Benutzereingaben zu validieren und eine einfache String-Verkettung zu verwenden.

+0

Ich glaube ich verstehe was du sagst. Das Folgende funktioniert. Ist es o.k? Die Spalte ist noch nicht fest codiert, wird aber nicht mehr als Parameter übergeben. Ist das ein Sicherheitsrisiko? 'pg.connect (Connection, Funktion (err, Client) { client.query ("UPDATE Menschen SET param1 = $ 1 WHERE pin = $ 2 RÜCKKEHR pin", [param2, param3], ...' – Tenbrink

+0

Sieht so aus, als würde dies mich anfällig für SQL-Injection machen? – Tenbrink

+0

Es wird, wenn Sie nicht param1 filtern. –