2016-08-24 4 views
2

Wie ich bereits hier On Stackoverflow ist es möglich, mehrere Zeilen in einer Abfrage zu aktualisieren, indem Sie so etwas wie dieserPostgreSQL mehrreihigen Updates in Node.js

update test as t set 
    column_a = c.column_a, 
    column_c = c.column_c 
from (values 
    ('123', 1, '---'), 
    ('345', 2, '+++') 
) as c(column_b, column_a, column_c) 
where c.column_b = t.column_b; 

besondere Dank an @Roman Pekar für die klare Antwort zu tun .

Jetzt versuche ich diese Art der Aktualisierung mit Abfragen zu einer PostgreSQL-Datenbank in NodeJS zusammenführen.

hier ein snipped meines Code ist:

var requestData = [ 
    {id: 1, value: 1234} 
    {id: 2, value: 5678} 
    {id: 3, value: 91011} 
] 


client.connect(function (err) { 
    if (err) throw err; 

client.query(buildStatement(requestData), function (err, result) { 
    if (err) throw err; 

    res.json(result.rows); 

    client.end(function (err) { 
     if (err) throw err; 
    }); 
}); 
}); 


var buildStatement = function(requestData) { 
var params = []; 
var chunks = []; 

for(var i = 0; i < requestData.length; i++) { 

    var row = requestData[i]; 
    var valuesClause = []; 

    params.push(row.id); 
    valuesClause.push('$' + params.length); 
    params.push(row.value); 
    valuesClause.push('$' + params.length); 

    chunks.push('(' + valuesClause.join(', ') + ')'); 

} 

return { 
    text: 'UPDATE fit_ratios as f set ratio_budget = c.ratio_budget from (VALUES ' + chunks.join(', ') + ') as c(ratio_label, ratio_budget) WHERE c.ratio_label = f.ratio_label', values: params 
     } 
} 

ich nicht einen Fehler, aber es ist meine Tabelle nicht aktualisiert, ich weiß nicht wirklich, was hier schief geht. Vielleicht ein Syntaxfehler in meinem Abfragecode? Ich finde einfach keine speziellen Beispiele für mehrreihige Abfrage-, wenn in NodeJS pg Paket aktualisiere

Antwort

1

Das folgende Beispiel basiert auf Bibliothek pg-promise, und seine Methode helpers.update:

// library initialization, usually placed in its own module: 
const pgp = require('pg-promise')({ 
    capSQL: true // capitalize all generated SQL 
}); 

const db = pgp(/*your connection details*/); 

// records to be updated: 
const updateData = [ 
    {id: 1, value: 1234}, 
    {id: 2, value: 5678}, 
    {id: 3, value: 91011} 
]; 

// declare your ColumnSet once, and then reuse it: 
const cs = new pgp.helpers.ColumnSet(['?id', 'value'], {table: 'fit_ratios'}); 

// generating the update query where it is needed: 
const update = pgp.helpers.update(updateData, cs) + ' WHERE v.id = t.id'; 
//=> UPDATE "fit_ratios" AS t SET "value"=v."value" 
// FROM (VALUES(1,1234),(2,5678),(3,91011)) 
// AS v("id","value") WHERE v.id = t.id 

// executing the query: 
db.none(update) 
    .then(()=> { 
     // success; 
    }) 
    .catch(error=> { 
     // error; 
    }); 

Dieses Verfahren zur Erzeugung von multi- Reihe Updates können wie folgt charakterisiert werden:

  • sehr schnell, da sie auf Typ beruht ColumnSet, die intelligente Caching für Abfragegenerierung implementiert
  • completel y Sicher, da alle Datentypen durch die Abfrageformatierungs-Engine der Bibliothek gehen, um sicherzustellen, dass alles korrekt formatiert und gemastert wird.
  • sehr flexibel, aufgrund der erweiterten ColumnConfig Syntax für die Spalten-Definition unterstützt.
  • sehr einfach zu bedienen, aufgrund der vereinfachten Schnittstelle von pg-promise implementiert.

Bitte beachte, dass wir ? vor Spalte id, um anzuzeigen, verwenden, dass der Spalt Teil der Bedingung ist, aber nicht aktualisiert werden. Für die vollständige Spaltensyntax siehe die Klassen Column und ColumnConfig Struktur.


Verwandte Frage: Multi-row insert with pg-promise.

1

Zuallererst akzeptierte ich die Antwort von @ vitaly-t, als er mir beibrachte, eine bessere und schnellere Bibliothek zu verwenden pg-promise und es löste mein Problem. (Periode)

Aber meine eigene Frage für die Menschen zu beantworten, die mit dem gleichen Problem könnten am Ende und mit der Bibliothek pg bleiben wollen, hier ist, wo ich den Fehler gemacht (es ist nur Syntax)

In ich mein Original-Code hatte diese Zeile am Ende

return { 
    text: 'UPDATE fit_ratios as f set ratio_budget = c.ratio_budget from (VALUES ' + chunks.join(', ') + ') as c(ratio_label, ratio_budget) WHERE c.ratio_label = f.ratio_label', values: params 
     } 
} 

Das erste Mal, dass ich das sah, war es schwer zu verstehen, so war es sehr einfach, einige Fehler zu machen.Ändern Sie diese Codezeile zu dem, was Sie mit Spaltennamen, indem Sie stattdessen die Schlüssel meines Objekt meiner ursprünglichen Problem zu

return { 
    text: 'UPDATE fit_ratios as f set ratio_budget = c.value from (VALUES ' + chunks.join(', ') + ') as c(id, value) WHERE c.id = f.ratio_id', 
       values: params 
} 

ich verpasst knapp unterhalb fixiert zu sehen. (z.B. c.ratio_label bis c.id, ...)

Verwandte Themen