SQLite RETURNING: получить id вставленной строки

Категория: Postgresql · Язык: SQL · Обновлено:

RETURNING в SQLite возвращает изменённые строки прямо из INSERT, UPDATE или DELETE, без отдельного SELECT и без last_insert_rowid(). Клауза появилась в SQLite 3.35.0, выпущенной в марте 2021 года. Она особенно удобна, когда нужно получить сгенерированный id или значения по умолчанию в одном запросе.

Вставить, обновить и удалить с результатом

SQL
CREATE TABLE notes (
    id INTEGER PRIMARY KEY,
    title TEXT NOT NULL,
    done INTEGER NOT NULL DEFAULT 0
);

INSERT INTO notes (title) VALUES ('Первая заметка')
RETURNING id, title;

UPDATE notes SET done = 1 WHERE id = 1
RETURNING id, done;

DELETE FROM notes WHERE id = 1
RETURNING id;

INSERT вернёт строку после применения значений по умолчанию, поэтому в результате видны и id, и done. UPDATE покажет новое состояние изменённых строк, а DELETE — только те строки, которые действительно удалены. Если условие не совпало ни с одной строкой, результат будет пустым.

RETURNING выполняется в той же транзакции, что и изменение: отдельный COMMIT не нужен. Для нескольких вставленных строк вернётся несколько строк результата. Порядок без внешнего SELECT ... ORDER BY не гарантирован, поэтому не полагайтесь на него в отчётах.

Проверить версию SQLite

Python
import sqlite3

print(sqlite3.sqlite_version)  # версия вашей сборки SQLite

В Python используется SQLite, встроенная в интерпретатор или систему. На старых дистрибутивах версия может быть ниже 3.35, и тогда RETURNING завершится ошибкой синтаксиса. Проверяйте sqlite3.sqlite_version в среде, где запускается код, а не только версию пакета sqlite3.

RETURNING не заменяет проверку ограничений: при нарушении UNIQUE или NOT NULL запрос завершится ошибкой и ничего не вернёт. Триггеры могут менять другие таблицы, но их строки в RETURNING не попадают. Для массовой загрузки больших файлов по-прежнему используйте executemany() или COPY-подобные инструменты, а RETURNING берите для точечных операций.

Документация: RETURNING, release 3.35.0.