RETURNING în SQLite

Inserare și modificare SQLite 3.35.0

Face ca INSERT, UPDATE sau DELETE să returneze rândurile modificate, de exemplu id-ul generat, fără un SELECT separat.

Sintaxă
INSERT INTO tabel ... RETURNING expresie [AS alias], ...;
UPDATE tabel SET ... WHERE ... RETURNING *;
DELETE FROM tabel WHERE ... RETURNING coloane;

Ce face RETURNING

RETURNING se pune la sfârșitul unui INSERT, UPDATE sau DELETE și transformă comanda într-una care întoarce rezultate, ca un SELECT. Primești câte un rând pentru fiecare rând inserat, modificat sau șters.

Pentru INSERT și UPDATE vezi valorile noi, inclusiv cele completate automat: cheia INTEGER PRIMARY KEY, valorile DEFAULT, coloanele generate. Pentru DELETE vezi valorile rândurilor șterse. Poți scrie *, coloane sau expresii cu alias.

Limite din documentație: RETURNING merge doar în comenzile de pe primul nivel, nu în declanșatori și nici ca subinterogare (nu poți scrie WITH r AS (INSERT ... RETURNING ...) cum se poate în PostgreSQL). Ordinea rândurilor returnate nu este garantată, iar modificările făcute de declanșatori sau de chei străine nu apar în rezultat.

Parametri

Parametru Descriere
expresie Coloană, * sau orice expresie calculată din rândul modificat; poate avea alias cu AS.

Ce returnează

Câte un rând pentru fiecare rând afectat de comandă.

Exemple

Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.

CREATE TABLE comenzi (
  id     INTEGER PRIMARY KEY,
  client TEXT NOT NULL,
  total  INTEGER NOT NULL,
  stare  TEXT NOT NULL DEFAULT 'noua'
);
INSERT INTO comenzi (client, total) VALUES
  ('Ana', 200),
  ('Vlad', 350),
  ('Ana', 120);

Exemplul 1: Id-ul și valoarea implicită după INSERT

Nu am dat id și nici stare; RETURNING arată ce a completat SQLite: următorul id (4) și valoarea implicită „noua”.

INSERT INTO comenzi (client, total) VALUES ('Elena', 90)
  RETURNING id, client, stare;

Rezultat

╭────┬────────┬───────╮
│ id │ client │ stare │
╞════╪════════╪═══════╡
│  4 │ Elena  │ noua  │
╰────┴────────┴───────╯

Exemplul 2: Valorile noi după UPDATE

Clienta Ana primește 10% reducere la ambele comenzi. Expresia total * 9 / 10 folosește doar întregi, deci rezultatul rămâne întreg.

UPDATE comenzi SET total = total * 9 / 10, stare = 'reducere'
  WHERE client = 'Ana'
  RETURNING id, total AS total_nou, stare;

Rezultat

╭────┬───────────┬──────────╮
│ id │ total_nou │  stare   │
╞════╪═══════════╪══════════╡
│  1 │       180 │ reducere │
│  3 │       108 │ reducere │
╰────┴───────────┴──────────╯

Exemplul 3: Ce s-a șters, cu DELETE … RETURNING

Util pentru jurnale: afli exact ce rânduri au dispărut, fără să le citești înainte.

DELETE FROM comenzi WHERE total < 300
  RETURNING *;

SELECT count(*) AS ramase FROM comenzi;

Rezultat

╭────┬────────┬───────┬───────╮
│ id │ client │ total │ stare │
╞════╪════════╪═══════╪═══════╡
│  1 │ Ana    │   200 │ noua  │
│  3 │ Ana    │   120 │ noua  │
╰────┴────────┴───────┴───────╯
╭────────╮
│ ramase │
╞════════╡
│      1 │
╰────────╯

Greșeli frecvente

  • Folosești RETURNING într-un declanșator sau într-o subinterogare. SQLite dă eroare de sintaxă; citește rezultatul în aplicație și trimite comanda următoare separat.
  • Te bazezi pe ordinea rândurilor din RETURNING. Nu poți scrie ORDER BY acolo; dacă ai nevoie de o ordine, sorteaz-o în aplicație.
  • Rulezi codul pe un SQLite mai vechi de 3.35.0 (de exemplu pe un server vechi sau într-o aplicație cu biblioteca inclusă). Verifică SELECT sqlite_version();.

Comenzi înrudite

  • INSERT ... ON CONFLICT (upsert): Inserează un rând sau, dacă cheia există deja, actualizează rândul existent (ori nu face nimic), într-o singură comandă.
  • INSERT OR IGNORE / OR REPLACE: Alege ce face SQLite când un INSERT sau UPDATE încalcă o constrângere: oprește comanda, sare peste rând sau înlocuiește rândul vechi.
  • rowid și INTEGER PRIMARY KEY: Orice tabel SQLite obișnuit are o coloană ascunsă rowid; o coloană INTEGER PRIMARY KEY devine alias al ei și primește automat valori.
  • SQLite din Python (sqlite3): Modulul sqlite3 din biblioteca standard Python: conectare, interogări cu parametri, tranzacții și rânduri ca dicționare.