2017-05-29 15 views
2

nicht ermitteln Ich versuche, eine PostgreSQL vorbereitete Anweisung mit node.js pg npm-Paket zu erstellen. Allerdings habe ich immer einen Fehler bekommen:

could not determine data type of parameter $1

function promiseQuery(sql, values) { 
    return new Promise(function(resolve, reject) { 
     pool.query('select $1 from workers', ['name'], function(err, result) { 
      if (err) {console.log(err); reject(err)} 
      else resolve(result.rows); 
     }) 
    }); 
} 

Im db des name Feld ist text not null einzugeben.

Ich versuche auch pg-promise, aber auch keinen Erfolg.

+0

sind Sie sicher, dass Sie Kennung wie das passieren kann .. –

+0

@VaoTsun in pg Dokumentation ein sehr ähnliches Beispiel ist: https://www.npmjs.com/package/pg – wizard

+0

genau, geben Sie die Dokumentation die Syntax : 'pool.query ('SELECT $ 1 :: int AS number', ['2'], function (err, res)', die Sie nicht in Ihrem Code verwenden – VladNeacsu

Antwort

2

In der Abfrage select name from workers, aus der Sicht der SQL syntaxname ist ein identifier und Kennungen können niemals als $N Parameter übergeben werden, sie wörtlich in dem Befehl erscheinen. Andernfalls kann die Abfrage nicht vorbereitet werden.

$N Parameter können nur in der Abfrage an Positionen erscheinen, an denen Literale (Konstanten) stehen.

Sie würden die gleichen Fehler haben, wenn etwas ähnliches mit dem PREPARE SQL-Befehl versucht, außerhalb jeder Client-seitige Bibliothek:

PREPARE p as SELECT $1 FROM pg_class; 
ERROR: could not determine data type of parameter $1 

Die Lösung ist die Abfrage in Javascript mit String-Ersatz Techniken zu bauen für Spaltennamen oder Tabellennamen, bevor Sie sie an die Datenbank senden.

2

Erweiterung auf die Antwort von Daniel Vérité ...

Sie können nicht Prepared Statements mit dynamischen Spaltennamen kombinieren, dann würden Sie die Abfrage auf der Client-Seite erzeugen müssen.

Mit pg-promise Syntax für SQL Names können Sie richtig Ihre Abfrage wie folgt entkommen:

db.any('SELECT $1~ FROM table', [colName]) 
// OR: 
db.any('SELECT $1:name FROM table', [colName]) 
// OR: 
db.any('SELECT ${colName~} FROM table', {colName}) 
// OR: 
db.any('SELECT ${colName:name} FROM table', {colName}) 
// Etc, other variable syntax, like $[], $//, $<>, $() 

Und wenn Sie wollen, dass es für eine Liste von Spalten tun, dann der einfachste Weg, es so zu tun ist:

const colNames = ['one', 'two', 'three']; 

db.any('SELECT $1~ FROM table', [colNames]) 
// etc, the same variations as above, all will generate: 
// SELECT "one","two","three" FROM table 

oder von allen Objekteigenschaften:

const data = { 
    one: 123, 
    two: true, 
    three: 'text' 
}; 
db.any('SELECT $1~ FROM table', [data]) 
// etc, the same variations as above, all will generate: 
// SELECT "one","two","three" FROM table 

Alle diese Methoden umgehen die Abfrage ordnungsgemäß und stellen sicher, dass die SQL-Injektion nicht möglich ist.

Verwandte Themen