PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Aggiornamento collettivo/batch/upsert in PostgreSQL

Inserimento collettivo

Puoi modificare l'inserimento collettivo di tre colonne da @Ketema:

INSERT INTO "table" (col1, col2, col3)
  VALUES (11, 12, 13) , (21, 22, 23) , (31, 32, 33);

Diventa:

INSERT INTO "table" (col1, col2, col3)
  VALUES (unnest(array[11,21,31]), 
          unnest(array[12,22,32]), 
          unnest(array[13,23,33]))

Sostituzione dei valori con segnaposto:

INSERT INTO "table" (col1, col2, col3)
  VALUES (unnest(?), unnest(?), unnest(?))

Devi passare array o elenchi come argomenti a questa query. Ciò significa che puoi eseguire enormi inserti in blocco senza eseguire la concatenazione di stringhe (e tutti i suoi hazzle e pericoli:sql injection e virgolette).

Aggiornamento collettivo

PostgreSQL ha aggiunto l'estensione FROM a UPDATE. Puoi usarlo in questo modo:

update "table" 
  set value = data_table.new_value
  from 
    (select unnest(?) as key, unnest(?) as new_value) as data_table
  where "table".key = data_table.key;

Nel manuale manca una buona spiegazione, ma c'è un esempio nella mailing list postgresql-admin. Ho cercato di approfondirlo:

create table tmp
(
  id serial not null primary key,
  name text,
  age integer
);

insert into tmp (name,age) 
values ('keith', 43),('leslie', 40),('bexley', 19),('casey', 6);

update tmp set age = data_table.age
from
(select unnest(array['keith', 'leslie', 'bexley', 'casey']) as name, 
        unnest(array[44, 50, 10, 12]) as age) as data_table
where tmp.name = data_table.name;
 

Ci sono anche altri post su StackExchange che spiegano UPDATE...FROM.. utilizzando un VALUES clausola invece di una sottoquery. Potrebbero essere più facili da leggere, ma sono limitati a un numero fisso di righe.