sql >> Databasteknik >  >> RDS >> PostgreSQL

Flerradsskär med pg-löfte

Jag är författaren till pg-promise.

I äldre versioner av biblioteket täcktes detta av förenklade exempel i Performance Boost-artikeln, som fortfarande är bra att läsa när man skriver högpresterande databasapplikationer.

Det nyare tillvägagångssättet är att förlita sig på hjälparnas namnutrymme, som i slutändan är flexibelt och optimerat för prestanda.

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

Se API:ColumnSet, infoga.

En sådan infogning kräver inte ens en transaktion, för om en uppsättning värden inte kan infogas kommer ingen att infogas.

Och du kan använda samma tillvägagångssätt för att generera någon av följande frågor:

  • enrads INSERT
  • flera rader INSERT
  • enrads UPDATE
  • flera rader UPDATE

Är infogningar med ${} notation skyddade mot sql-injektion?

Ja, men inte ensam. Om du infogar schema-/tabell-/kolumnnamn dynamiskt är det viktigt att använda SQL-namn, som i kombination kommer att skydda din kod från SQL-injektion.

Relaterad fråga:PostgreSQL-uppdateringar med flera rader i Node.js

extras

F:Hur får man id av varje nytt rekord samtidigt?

Svar: Helt enkelt genom att lägga till RETURNING id till din fråga och exekvera den med metoden många:

const query = pgp.helpers.insert(values, cs) + ' RETURNING id';
    
const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]

eller ännu bättre, skaffa id-numret och konvertera resultatet till en rad heltal med hjälp av metodkarta:

const res = await db.map(query, undefined, a => +a.id);
//=> [1, 2, ...]

För att förstå varför vi använde + där, se:pg-promise returnerar heltal som strängar.

UPPDATERING-1

För att infoga ett stort antal poster, se Dataimport.

UPPDATERING-2

Med v8.2.1 och senare kan du linda in den statiska frågegenereringen till en funktion, så att den kan genereras inom frågemetoden, för att avvisa när frågegenereringen misslyckas:

// 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. SQL Server Performance TOP IO Query -1

  2. mysql primärnyckel med två kolumner med automatisk ökning

  3. Vilket är det bästa sättet att ta bort gamla rader från MySQL på rullande basis?

  4. PostgreSQL Connection Pooling:Del 2 – PgBouncer