PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Wkładka wielorzędowa z obietnicą pg

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);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przegląd replikacji logicznej w PostgreSQL

  2. Przyznaj uprawnienia do określonej bazy danych w PostgreSQL

  3. SQLAlchemia czy psycopg2?

  4. Jak obsłużyć opcjonalną wartość zwracaną przez zapytanie za pomocą skrzynki postgres?

  5. szybki losowy wybór wiersza w Postgresie