Предложение ON CONFLICT
Предложение ON CONFLICT — нестандартное расширение, характерное для SQLite, которое может встречаться во многих других командах SQL. В этом документе ему посвящён отдельный раздел, поскольку оно не входит в стандарт SQL и поэтому может быть незнакомо.
Описанное здесь предложение ON CONFLICT присутствует в SQLite ещё до версии 3.0.0 (2004-06-18). Фраза «ON CONFLICT» также является частью UPSERT — расширения для INSERT, добавленного в версии 3.24.0 (2018-06-04). Не путайте эти два отдельных случая использования фразы «ON CONFLICT».
Синтаксис предложения ON CONFLICT для команды CREATE TABLE показан выше. В командах INSERT и UPDATE ключевые слова «ON CONFLICT» заменяются на «OR», чтобы синтаксис звучал естественнее. Например, вместо «INSERT ON CONFLICT IGNORE» используется «INSERT OR IGNORE». Ключевые слова меняются, но значение предложения в обоих случаях одинаково.
Предложение ON CONFLICT допускается только для ограничений UNIQUE, NOT NULL и PRIMARY KEY. Предложение ON CONFLICT нельзя использовать с ограничениями CHECK и FOREIGN KEY. Существует пять алгоритмов разрешения конфликтов: ROLLBACK, ABORT, FAIL, IGNORE и REPLACE. Алгоритм разрешения конфликтов по умолчанию — ABORT. Их значения описаны ниже:
- ROLLBACK
При возникновении нарушения соответствующего ограничения алгоритм разрешения ROLLBACK прерывает текущую команду SQL с ошибкой SQLITE_CONSTRAINT и откатывает текущую транзакцию. Если активной транзакции нет (кроме неявной транзакции, создаваемой для каждой команды), алгоритм разрешения ROLLBACK работает так же, как алгоритм ABORT.
- ABORT
При возникновении нарушения соответствующего ограничения алгоритм разрешения ABORT прерывает текущую команду SQL с ошибкой SQLITE_CONSTRAINT и отменяет все изменения, внесённые текущей командой SQL; однако изменения, вызванные предыдущими командами SQL в той же транзакции, сохраняются, а транзакция остаётся активной. Это поведение используется по умолчанию и предусмотрено стандартом SQL.
- FAIL
-
При возникновении нарушения соответствующего ограничения алгоритм разрешения FAIL прерывает текущую команду SQL с ошибкой SQLITE_CONSTRAINT. Однако при разрешении FAIL не отменяются предыдущие изменения команды SQL, завершившейся ошибкой, и транзакция не завершается. Например, если команда UPDATE обнаружит нарушение ограничения на 100-й строке, которую она пытается обновить, изменения первых 99 строк сохранятся, а изменения строк начиная со 100-й не будут выполнены.
Поведение FAIL работает только для ограничений уникальности, NOT NULL и CHECK. Нарушение ограничения внешнего ключа приводит к ABORT.
- IGNORE
-
При возникновении нарушения соответствующего ограничения алгоритм разрешения IGNORE пропускает строку, содержащую нарушение ограничения, и продолжает обработку последующих строк команды SQL, как будто ничего не произошло. Остальные строки до и после строки, содержащей нарушение ограничения, обычно вставляются или обновляются. При использовании алгоритма разрешения конфликтов IGNORE ошибки ограничений уникальности, NOT NULL и UNIQUE не возвращаются. Однако для ошибок ограничений внешнего ключа алгоритм разрешения конфликтов IGNORE работает как ABORT.
- REPLACE
-
При нарушении ограничения UNIQUE или PRIMARY KEY алгоритм REPLACE удаляет существующие строки, вызывающие нарушение ограничения, перед вставкой или обновлением текущей строки, после чего выполнение команды продолжается в обычном режиме. При нарушении ограничения NOT NULL разрешение конфликта REPLACE заменяет значение NULL значением по умолчанию для этого столбца; если значение по умолчанию не задано, используется алгоритм ABORT. При нарушении ограничения CHECK или ограничения внешнего ключа алгоритм разрешения конфликта REPLACE работает как ABORT.
Когда стратегия разрешения конфликта REPLACE удаляет строки для соблюдения ограничения, триггеры удаления срабатывают только в том случае, если включены рекурсивные триггеры.
Хук обновления не вызывается для строк, удалённых стратегией разрешения конфликтов REPLACE. Кроме того, REPLACE не увеличивает счётчик изменений. Поведение, описанное в этом абзаце, может измениться в будущей версии.
Алгоритм, указанный в предложении OR команды INSERT или UPDATE, переопределяет любой алгоритм, указанный в CREATE TABLE. Если алгоритм не указан нигде, используется ABORT.
Последнее обновление этой страницы: 2025-11-22 13:15:11Z
SQLite is in the Public Domain.
https://sqlite.org/lang_conflict.html