Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що робить RETURNING і чому він заощаджує запити?

RETURNING повертає дані рядків, які щойно вставлено, оновлено чи видалено, - тим самим запитом, без додаткового SELECT.

INSERT INTO orders (user_id, total) VALUES (7, 1999)
RETURNING id, created_at;

Типова потреба: дізнатися згенерований id, значення за замовчуванням (created_at, uuid), результат тригера.

З UPDATE і DELETE:

UPDATE accounts SET balance = balance - 500
WHERE id = 7 AND balance >= 500
RETURNING balance;
-- 0 рядків у відповіді - коштів не вистачило

DELETE FROM sessions WHERE last_activity < now() - interval '30 days'
RETURNING user_id;

PostgreSQL 18: старі й нові значення в одному запиті:

UPDATE products SET price = price * 1.1 WHERE category_id = 3
RETURNING id, old.price AS old_price, new.price AS new_price;

Раніше для «було - стало» потрібен був окремий запит до оновлення чи тригер.

З ON CONFLICT - дізнатися, чи рядок вставлено, чи оновлено:

INSERT INTO prices (sku, amount) VALUES ('A-1', 100)
ON CONFLICT (sku) DO UPDATE SET amount = EXCLUDED.amount
RETURNING id, (xmax = 0) AS inserted;

(xmax = 0 - поширений прийом, що спирається на внутрішню деталь MVCC, а не на гарантований інтерфейс.)

Чому це важливо:

  • на один запит менше - менше затримки, особливо коли база на іншому сервері;
  • атомарність: окремий SELECT після UPDATE може побачити вже змінений іншим запитом рядок, а RETURNING повертає саме те, що записав ваш запит;
  • черга задач: UPDATE ... WHERE id = (SELECT ... FOR UPDATE SKIP LOCKED) RETURNING * - взяти задачу й позначити її зайнятою одним запитом.

У Laravel: при Model::create() на PostgreSQL Eloquent отримує id саме через INSERT ... RETURNING "id". Для решти сценаріїв - сирий запит:

$rows = DB::select('UPDATE accounts SET balance = balance - ? WHERE id = ? AND balance >= ? RETURNING balance', [500, 7, 500]);

Докладніше в документації: Повернення даних зі змінених рядків

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання