Ce face INSERT INTO ... RETURNING
Comanda INSERT INTO adaugă rânduri noi într-un tabel, fie din valori explicite (VALUES), fie din rezultatul unei interogări (INSERT INTO ... SELECT). În PostgreSQL, clauza RETURNING atașată la finalul unui INSERT (dar și la UPDATE sau DELETE) returnează imediat coloanele dorite din rândurile nou create.
Aceasta elimină complet nevoia apelurilor suplimentare de tip LAST_INSERT_ID() și funcționează impecabil și atunci când inserăm zeci de rânduri într-o singură instrucțiune multi-row VALUES.
Clauze, operatori și argumente
| Clauză / Operator | Descriere |
|---|---|
INSERT INTO tabel (coloane) |
Specifică tabelul țintă și lista explicită de coloane care primesc valori. |
VALUES (...), (...) |
Furnizează unul sau mai multe tupluri de valori pentru inserare într-o singură comandă atomică. |
DEFAULT |
Cuvânt cheie folosit în VALUES pentru a aplica valoarea implicită a coloanei respective. |
RETURNING * / expr |
Returnează rândurile inserate (inclusiv ID-urile generate de secvențe/UUID și valorile DEFAULT) exact ca un SELECT. |
Exemple
Exemplul 1: Inserarea mai multor produse și preluarea ID-urilor cu RETURNING
Inserăm două produse dintr-un foc și cerem înapoi id-ul autogenerat, sku-ul și momentul creării.
INSERT INTO produse (sku, denumire, pret)
VALUES
('MON-27-4K', 'Monitor IPS 27 inch 4K', 1699.90),
('KBD-MECH-RO', 'Tastatură Mecanică Layout RO', 429.00)
RETURNING id, sku, pret, creat_la;
Rezultat interogare
id | sku | pret | creat_la
----+-------------+---------+----------------------------
41 | MON-27-4K | 1699.90 | 2025-03-20 10:14:22.418+02
42 | KBD-MECH-RO | 429.00 | 2025-03-20 10:14:22.418+02
(2 rows)
INSERT 0 2
Exemplul 2: Arhivarea și copierea rândurilor cu INSERT INTO … SELECT … RETURNING
Copiem comenzile finalizate din 2024 într-un tabel de arhivă și afișăm ID-urile procesate.
INSERT INTO arhiva_comenzi (comanda_id, client_id, total_lei, plasata_la)
SELECT id, client_id, total_lei, plasata_la
FROM comenzi
WHERE plasata_la < '2025-01-01' AND status = 'livrata'
RETURNING comanda_id, total_lei;
Rezultat interogare
comanda_id | total_lei
------------+-----------
1012 | 340.00
1019 | 890.50
(2 rows)
INSERT 0 2
Greșeli frecvente
- Omiterea listei de coloane în
INSERT INTO tabel VALUES (...): dacă ordinea coloanelor se schimbă sau se adaugă o coloană nouă în tabel, interogarea va eșua sau va insera date în coloana greșită. - Executarea unui
SELECT MAX(id)dupăINSERTpentru a afla cheia generată: într-o aplicație concurentă, o altă sesiune poate insera un rând între timp; folosește întotdeaunaRETURNING id.
Comenzi și funcții înrudite
ON CONFLICT DO UPDATE (UPSERT): Rezolvă atomic conflictele de cheie unică la inserare: ignoră rândul duplicat sau îl actualizează pe loc.gen_random_uuid() și GENERATED AS IDENTITY: Definește chei primare moderne cu coloane auto-incrementate standard SQL (IDENTITY) sau identificatori unici globali (UUID v4).WITH (Common Table Expressions): Definește subinterogări numite (CTE) pentru structurarea clară a interogărilor complexe și înlănțuirea operațiilor DML.