DBAtlas · Атлас эксплуатации баз данных

Вернуть изменённую строку (RETURNING / OUTPUT)

Oracle

-- Single row: RETURNING ... INTO (PL/SQL bind variable)
UPDATE employee SET salary = salary * 1.1
WHERE id = 5
RETURNING salary INTO :new_salary;

-- Get back the key generated by an INSERT
INSERT INTO employee (name) VALUES ('Ayse')
RETURNING id INTO :new_id;

RETURNING возвращает значения строк, изменённых INSERT/UPDATE/DELETE (напр. автоматически сгенерированный ID), без отдельного SELECT. В Oracle одна строка возвращается через RETURNING ... INTO в bind-переменную, несколько строк — через RETURNING ... BULK COLLECT INTO в коллекцию.

PostgreSQL

INSERT INTO employee (name, salary)
VALUES ('Ayse', 15000)
RETURNING id, name;

UPDATE employee SET salary = salary * 1.1
WHERE department = 'IT'
RETURNING id, salary;

Предложение RETURNING в PostgreSQL очень гибкое: оно возвращает любой столбец (включая вычисляемые выражения) строк, затронутых операторами INSERT, UPDATE, DELETE и MERGE, сразу как набор результатов. Это самый чистый способ получить сгенерированные значения serial/identity.

MySQL

-- MySQL has no RETURNING; the generated key is retrieved separately:
INSERT INTO employee (name, salary) VALUES ('Ayse', 15000);
SELECT LAST_INSERT_ID();

-- MariaDB 10.5+ supports INSERT ... RETURNING:
INSERT INTO employee (name) VALUES ('Ayse') RETURNING id;

MySQL не поддерживает стандартный RETURNING; автоинкрементный ключ, сгенерированный INSERT, получают через LAST_INSERT_ID(), а обновлённые значения читают отдельным SELECT. MariaDB предлагает INSERT ... RETURNING с 10.5 и DELETE ... RETURNING с 10.0.

SQL Server

INSERT INTO employee (name, salary)
OUTPUT INSERTED.id, INSERTED.name
VALUES ('Ayse', 15000);

UPDATE employee SET salary = salary * 1.1
OUTPUT DELETED.salary AS old_salary, INSERTED.salary AS new_salary
WHERE id = 5;

Эквивалент в SQL Server — предложение OUTPUT: оно обращается к псевдотаблицам INSERTED (новые значения) и DELETED (старые значения); в UPDATE можно использовать обе. С OUTPUT ... INTO результаты можно записать в таблицу/табличную переменную. Идеально для копирования изменений в таблицу аудита.

MongoDB

// findOneAndUpdate returns the modified document
db.employee.findOneAndUpdate(
  { id: 5 },
  { $mul: { salary: 1.1 } },
  { returnDocument: "after" }   // return the updated version
)

В MongoDB команды findOneAndUpdate / findOneAndDelete / findOneAndReplace возвращают затронутый документ в одной атомарной операции. returnDocument: 'before' даёт версию до изменения, 'after' — после. insertOne возвращает _id вставленного документа.

Redis

# Some commands return the old/new value directly:
SET counter 0 GET       # (6.2+) returns the old value and writes the new one (replaces GETSET)
INCR visits          # increments and returns the new value

В Redis нет отдельного RETURNING, но многие команды записи сразу возвращают результат: INCR/INCRBY — новое значение, SET ... GET — старое значение (GETSET устарел с 6.2), LPOP/RPOP — удалённый элемент. Для атомарного чтения-записи такое поведение заменяет RETURNING.

Elasticsearch

# The _update response can return the result:
POST employee/_update/5
{
  "script": { "source": "ctx._source.salary *= 1.1" },
  "_source": true
}
# The response returns the updated document in get._source

В Elasticsearch операции index/update возвращают метаданные результата (_id, _version, result). Чтобы получить тело обновлённого документа, добавьте '_source': true в запрос _update; поле get ответа содержит текущий _source. Отдельный вызов GET не нужен.

Открыть в DBAtlas →