sql >> Databáze >  >> RDS >> PostgreSQL

Funkce hromadného INSERT Postgres pomocí argumentů JSON

Pro tisíce záznamů

1. Vytvořte dočasnou tabulku vstupních řádků složených z vašich hodnot $1 , $2 , $3 . Nejrychlejší způsob nahrání je COPY - nebo \copy meta-příkaz psql pokud data nejsou na stejném stroji. Předpokládejme, že tato tabulka:

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

Přidal jsem omezení PK, které je zcela volitelné, ale zajišťuje, že máme co do činění s jedinečnými hodnotami int, které nejsou null. Pokud můžete ručit za vstupní data, nepotřebujete omezení.

2. Řetězte své příkazy pomocí CTE upravujících data. Jak jsme zjistili podle vaší předchozí otázky , v této konkrétní operaci nejsou žádné závodní podmínky.

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;

Kroky 1. a 2. musí probíhat ve stejné relaci (ne nutně stejná transakce), protože rozsah dočasných tabulek je vázán na stejnou relaci.

Poznámka:UPDATE závisí pouze na 1. INSERT , úspěch 2. INSERT je zaručena, protože neexistuje ON CONFLICT DO NOTHING a celá operace bude vrácena zpět, pokud dojde ke konfliktu ve 2. INSERT .

Související:

Jen pro pár záznamů

Jsou různé možnosti jak. Váš nápad předat funkci JSON pole je jedním z nich. Pokud objekty odpovídají cílové tabulce, můžete použít json_populate_recordset() v jediném INSERT dotaz. Nebo stačí použít INSERT (jako připravený příkaz) bez obálky funkcí.

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" }]');

Pro hrstku sloupců můžete také předat pole pro každý sloupec a procházet je paralelně. Můžete to udělat pomocí jednoduché smyčky na indexu pole. Od Postgresu 9.4 existuje také pohodlné unnest() s více parametry, abyste to všechno udělali v jediném dotazu:

Nejlepší řešení závisí na formátu dat, který máte .




  1. Zkontrolujte verzi SQLite

  2. Odesílání dat z React do MySQL

  3. Definování zdroje dat jta mimo kontejner

  4. MySQL> Tabulka neexistuje. Ale dělá to (nebo by mělo)