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

Postgres bulk INSERT-funktion ved hjælp af JSON-argumenter

For tusindvis af registreringer

1. Opret en midlertidig tabel med inputrækker, der består af dine værdier $1 , $2 , $3 . Den hurtigste måde at uploade er COPY - eller \copy meta-kommando af psql hvis dataene ikke er på samme maskine. Lad os antage denne tabel:

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

Jeg tilføjede en PK-begrænsning, som er helt valgfri, men den sikrer, at vi har at gøre med unikke ikke-null int-værdier. Hvis du kan stå inde for inputdata, behøver du ikke begrænsningen.

2. Kæd dine kommandoer sammen med datamodificerende CTE'er. Som vi har fastslået under dit tidligere spørgsmål , der er ingen løbsforhold at tage sig af i denne særlige operation.

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;

Trin 1. og 2. skal køre i samme session (ikke nødvendigvis den samme transaktion), da omfanget af midlertidige tabeller er bundet til den samme session.

Bemærk, OPDATERING afhænger kun af den 1. INSERT , succes med 2. INSERT er garanteret, da der ikke er nogen ON CONFLICT GØR INGENTING og hele operationen ville blive rullet tilbage, hvis der er nogen konflikt i den 2. INSERT .

Relateret:

For blot et par poster

Der er forskellige muligheder hvordan. Din idé om at videregive et JSON-array til en funktion er en af ​​dem. Hvis objekter matcher måltabellen, kan du bruge json_populate_recordset() i en enkelt INSERT forespørgsel. Eller brug bare INSERT (som udarbejdet erklæring) uden funktionsindpakning.

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

For blot en håndfuld kolonner kan du også sende et array for hver kolonne og gå gennem dem parallelt. Du kan gøre dette med en simpel løkke på array-indekset. Siden Postgres 9.4 er der også den praktiske unnest() med flere parametre for at gøre det hele i en enkelt forespørgsel:

Den bedste løsning afhænger af det dataformat, du har .




  1. Hvordan ændrer jeg datatype for et importeret regneark i mysql?

  2. En måde at kontrollere Oracle færdige sql

  3. Kan jeg automatisk oprette en tabel i PostgreSQL fra en csv-fil med overskrifter?

  4. optimer forespørgsel med datotypefelt i mysql