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

Zbiorcza funkcja INSERT Postgres przy użyciu argumentów JSON

Dla tysięcy rekordów

1. Utwórz tymczasową tabelę wierszy wejściowych, składającą się z wartości $1 , $2 , $3 . Najszybszym sposobem przesyłania jest COPY - lub \copy meta-polecenie psql jeśli dane nie znajdują się na tej samej maszynie. Załóżmy, że ta tabela:

CREATE TEMP TABLE tmp(id int PRIMARY KEY, val1 text, val2 text);

Dodałem ograniczenie PK, które jest całkowicie opcjonalne, ale zapewnia, że ​​mamy do czynienia z unikalnymi wartościami int o wartości niezerowej. Jeśli możesz ręczyć za dane wejściowe, nie potrzebujesz ograniczenia.

2. Połącz swoje polecenia z CTE modyfikującymi dane. Jak ustaliliśmy na podstawie Twojego poprzedniego pytania , w tej konkretnej operacji nie ma warunków wyścigu.

WITH ins1 AS (
   INSERT INTO table1 AS t1 (id, val1, val2)
   SELECT id, val1, val2 FROM tmp ON CONFLICT DO NOTHING
   RETURNING t1.id, t1.val1, t1.val2  -- only actually inserted rows returned
   )
, ins2 AS (
   INSERT INTO table2 (table1_id, val1)
   SELECT id, val1 FROM ins1
   )
UPDATE table3 t3
SET    val2 = i.val2
     , time = now()
FROM   ins1 i
WHERE  t3.table1_id = i.id;

Kroki 1. i 2. muszą być uruchomione w tej samej sesji (niekoniecznie ta sama transakcja), ponieważ zakres tabel tymczasowych jest powiązany z tą samą sesją.

Uwaga, UPDATE zależy tylko od pierwszego INSERT , sukces drugiego INSERT jest gwarantowane, ponieważ nie ma ON CONFLICT DO NOTHING a cała operacja zostanie wycofana, jeśli wystąpi jakikolwiek konflikt w drugim INSERT .

Powiązane:

Tylko kilka rekordów

Istnieją różne opcje. Twój pomysł na przekazanie tablicy JSON do funkcji jest jednym z nich. Jeśli obiekty pasują do tabeli docelowej, możesz użyć json_populate_recordset() w jednym INSERT zapytanie. Lub po prostu użyj INSERT (jako przygotowana instrukcja) bez opakowania funkcji.

INSERT INTO target_tbl  -- it's ok to omit target columns here
SELECT *
FROM   json_populate_recordset(null::target_tbl,  -- use same table type
          json '[{ "id": "1", "val1": "1-val1", "val2": "1-val2" },
                 { "id": "2", "val1": "2-val1", "val2": "2-val2" },
                 { "id": "3", "val1": "3-val1", "val2": "3-val2" },
                 { "id": "4", "val1": "4-val1", "val2": "4-val2" }]');

W przypadku zaledwie kilku kolumn możesz również przekazać tablicę dla każdej kolumny i przejść przez nie równolegle. Możesz to zrobić za pomocą prostej pętli na indeksie tablicy. Od Postgresa 9.4 dostępna jest również wygodna funkcja unnest() z wieloma parametrami, aby zrobić to wszystko w jednym zapytaniu:

Najlepsze rozwiązanie zależy od formatu danych, który posiadasz .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Łączenie Django i Postgresql z Docker

  2. Unikalne połączenie w tabeli

  3. 100% wykorzystanie procesora spowodowane przez nieznane zapytanie postgres

  4. Postgres CASE w kolejności BY przy użyciu aliasu

  5. Wybierz użytkowników należących tylko do określonych działów