Jestem autorem pg-promise.
W starszych wersjach biblioteki zostało to omówione w uproszczonych przykładach w artykule Performance Boost, który nadal jest dobrą lekturą podczas pisania wysokowydajnych aplikacji bazodanowych.
Nowszym podejściem jest poleganie na przestrzeni nazw pomocników, która jest ostatecznie elastyczna i zoptymalizowana pod kątem wydajności.
const pgp = require('pg-promise')({
/* initialization options */
capSQL: true // capitalize all generated SQL
});
const db = pgp(/*connection*/);
// our set of columns, to be created only once (statically), and then reused,
// to let it cache up its formatting templates for high performance:
const cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tmp'});
// data input values:
const values = [{col_a: 'a1', col_b: 'b1'}, {col_a: 'a2', col_b: 'b2'}];
// generating a multi-row insert query:
const query = pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')
// executing the query:
await db.none(query);
Zobacz API:ColumnSet, wstaw.
Takie wstawienie nie wymaga nawet transakcji, ponieważ jeśli jeden zestaw wartości nie zostanie wstawiony, żaden nie zostanie wstawiony.
Możesz użyć tego samego podejścia do wygenerowania dowolnego z następujących zapytań:
- jednowierszowy
INSERT
- wielorzędowy
INSERT
- jednowierszowy
UPDATE
- wielorzędowy
UPDATE
Czy wstawienia przy użyciu notacji ${} są chronione przed wstrzyknięciem sql?
Tak, ale nie sam. Jeśli dynamicznie wstawiasz nazwy schematów/tabeli/kolumn, ważne jest, aby używać nazw SQL, które w połączeniu chronią Twój kod przed wstrzyknięciem SQL.
Powiązane pytanie:wielowierszowe aktualizacje PostgreSQL w Node.js
dodatki
P:Jak uzyskać id
każdego nowego rekordu w tym samym czasie?
O: Wystarczy dołączyć RETURNING id
do zapytania i wykonując je metodą wiele:
const query = pgp.helpers.insert(values, cs) + ' RETURNING id';
const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]
lub jeszcze lepiej, pobierz identyfikatory i przekonwertuj wynik na tablicę liczb całkowitych, używając mapy metod:
const res = await db.map(query, undefined, a => +a.id);
//=> [1, 2, ...]
Aby zrozumieć, dlaczego użyliśmy +
tam, zobacz:pg-promise zwraca liczby całkowite jako łańcuchy.
AKTUALIZACJA-1
Aby wstawić ogromną liczbę rekordów, zobacz Importowanie danych.
AKTUALIZACJA-2
Korzystając z wersji 8.2.1 i nowszych, możesz opakować statyczne generowanie zapytań w funkcję, aby można było je wygenerować w ramach metody zapytania, aby odrzucić, gdy generowanie zapytania nie powiedzie się:
// generating a multi-row insert query inside a function:
const query = () => pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')
// executing the query as a function that generates the query:
await db.none(query);