SQLite LinuxWindowsmacOS

Почему SQLite не понимает RETURNING в INSERT, UPDATE и DELETE

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

При выполнении INSERT ... RETURNING, UPDATE ... RETURNING или DELETE ... RETURNING приложение сообщает «SQL logic error», «near RETURNING: syntax error» либо «SQLITE_ERROR». В SQLite эта конструкция доступна с 3.35.0 (12 марта 2021 года). Версия команды sqlite3, Python или PHP на другом сервере ничего не доказывает: проверять нужно библиотеку в том процессе, где происходит сбой.

В этой статье
  1. Что происходит и когда возникает
  2. Возможные причины: как различить
  3. Пошаговая диагностика и исправление
  4. Команды и проверочные примеры
  5. Как проверить результат
  6. Если не помогло

#Что происходит и когда возникает

При выполнении INSERT ... RETURNING, UPDATE ... RETURNING или DELETE ... RETURNING приложение сообщает «SQL logic error», «near RETURNING: syntax error» либо «SQLITE_ERROR». В SQLite эта конструкция доступна с 3.35.0 (12 марта 2021 года). Версия команды sqlite3, Python или PHP на другом сервере ничего не доказывает: проверять нужно библиотеку в том процессе, где происходит сбой.

#Возможные причины: как различить

Возможная причинаКак узнатьЧто делать
Старая SQLite в приложенииRETURNING отсутствует в SQLite до 3.35.0.SELECT sqlite_version() внутри соединения возвращает 3.34.x или ниже.Обновить связанную библиотеку приложения либо использовать совместимый SQL.
Приложение использует другую библиотекуСистемный sqlite3 и библиотека PHP/Python могут быть разных версий.sqlite3 --version и SELECT sqlite_version() из приложения показывают разные значения.Проверять в работающем процессе, не подменять библиотеку вслепую.
Неверное расположение RETURNINGRETURNING разрешён только в верхнеуровневых INSERT, UPDATE, DELETE, не в произвольном SELECT или вложенном запросе.Версия не ниже 3.35, но тестовый корректный INSERT работает, а исходный SQL не выполняется.Исправить синтаксис и учитывать ограничения RETURNING.

#Пошаговая диагностика и исправление

  1. Зафиксируйте исходный запрос и сообщениеПрименять, если ошибка появилась после обновления кода или переезда. Найдите в журнале только SQL-оператор (без паролей и личных данных), номер версии приложения и точный текст ошибки. Отдельно отметьте, это INSERT, UPDATE или DELETE. Ничего в базе пока не меняйте; если нет доступа к журналу, попросите разработчика показать диагностический вывод.
  2. Проверьте версию внутри приложенияЕсли проблема в Python, откройте терминал в той же виртуальной среде и запустите пример ниже: команда выведет версию библиотеки SQLite, встроенной в модуль sqlite3. Если ошибка из PHP, выполните в локальном служебном скрипте (не публикуйте его на сайте) запрос SELECT sqlite_version() через то же PDO-соединение и удалите файл после проверки. В sqlite3-консоли выполните SELECT sqlite_version();. Если версия меньше 3.35.0, переходите к выбору совместимости.
  3. Повторите безопасный пример без рабочей таблицыОткройте терминал: Linux — меню приложений → «Терминал», Windows — «Пуск» → «Терминал», macOS — «Терминал». Выполните пример Python с подключением :memory: из блока ниже; права администратора не нужны. В версии 3.35+ выводится число 1. Если появляется ошибка синтаксиса, подтвердите версию и не тестируйте вставки в рабочей базе.
  4. Проверьте синтаксис исходного SQLЕсли тест в памяти прошёл, убедитесь, что RETURNING находится в конце верхнеуровневого INSERT/UPDATE/DELETE и возвращаемые им строки действительно считываются приложением. SQLite не разрешает поместить UPDATE ... RETURNING внутрь CTE как самостоятельную таблицу. Вынесите операцию из вложенного запроса; сначала испытайте на копии, затем повторите только штатную операцию.
  5. Выберите обновление без подмены системных библиотекЕсли версия устарела, подготовьте тестовую среду с поддерживаемым выпуском языка/драйвера и SQLite 3.35+; проверьте версии из самого приложения и тесты транзакций. На работающем сервере не заменяйте системный libsqlite3 вручную: это может нарушить зависимости. Вариант с обновлением согласуйте с владельцем приложения и сделайте резервную копию.
  6. Используйте совместимую схему без RETURNING, если обновление невозможноДля одиночного INSERT в пределах одного соединения иногда можно выполнить обычный INSERT и прочитать идентификатор через last_insert_rowid() либо API lastrowid — только если таблица использует подходящий ROWID и этот идентификатор вам нужен. Выполните чтение в том же соединении непосредственно после вставки; это не заменяет RETURNING для UPDATE/DELETE и таблиц WITHOUT ROWID. Испытайте в отдельной базе, не копируйте пример на боевую таблицу.
  7. Повторите исходную операцию в тестовой копииПосле обновления драйвера или исправления SQL запустите ранее падавшую операцию на копии базы, сравните возвращённые строки и количество изменений, затем выполните ROLLBACK, если она была диагностической. Если ошибка сохранилась при 3.35+, сохраните полный SQL без конфиденциальных значений и перейдите к документации ограничений RETURNING.

#Команды и проверочные примеры

Linux · Терминал (Bash)Команда
Терминал Linux/macOS с Python 3; на Windows используйте python вместо python3, если так установлен Python. Права администратора не нужны.
python3 -c "import sqlite3; print(sqlite3.sqlite_version)"
Python
Только оперативная память, никаких рабочих файлов; при поддержке RETURNING вывод (1,).
import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE demo(id INTEGER PRIMARY KEY, name TEXT)")
print(con.execute("INSERT INTO demo(name) VALUES (?) RETURNING id", ("Проба",)).fetchone())
con.close()

#Как проверить результат

Версия SQLite не ниже 3.35.0, тест в :memory: выводит (1,), а операция приложения в тестовой копии возвращает ожидаемые данные. Важно проверить именно используемый драйвер, а не только внешнюю команду sqlite3.

#Если не помогло

При «near RETURNING» на новой версии проверьте границы SQL-оператора, запрет на RETURNING в триггерах и вложенных запросах и поддержку драйвером набора строк. При системной ошибке загрузки библиотеки верните прежний пакет или окружение и обратитесь к ответственному за сервер.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.