ОБНОВЛЕНИЕ
Содержание
1. Обзор
Оператор UPDATE используется для изменения подмножества значений, хранящихся в нуле или более строках таблицы базы данных, идентифицированной с помощью qualified-table-name, указанного в операторе UPDATE.
2. Подробности
Если оператор UPDATE не содержит оператора WHERE, все строки в таблице изменяются оператором UPDATE. В противном случае оператор UPDATE затрагивает только те строки, для которых выражение WHERE логическое выражение истинно. Это не ошибка, если выражение WHERE не оценивается как истинное для какой-либо строки в таблице — это просто означает, что оператор UPDATE затрагивает ноль строк.
Изменения, вносимые в каждую строку, на которую влияет оператор UPDATE, определяются списком присваиваний после ключевого слова SET. Каждое присваивание указывает имя_столбца слева от знака равенства и скалярное выражение справа. Для каждой затронутой строки указанные столбцы устанавливаются в значения, полученные путем вычисления соответствующих скалярных выражений. Если одно имя столбца встречается более одного раза в списке выражений присваивания, все, кроме самого правого вхождения, игнорируются. Столбцы, которые не появляются в списке присваиваний, остаются неизменными. Скалярные выражения могут ссылаться на столбцы строки, которая обновляется. В этом случае все скалярные выражения вычисляются перед выполнением каких-либо присваиваний.
Начиная со SQLite версии 3.15.0 (2016-10-14), присваивание в разделе SET может быть скобочным списком имён столбцов слева и строковым значением той же размерности справа.
Необязательная фраза "ИЛИ действие", следующая за ключевым словом UPDATE, позволяет пользователю указать конкретный алгоритм разрешения конфликтов ограничений, который следует использовать во время этого одного оператора UPDATE. Дополнительная информация содержится в разделе, озаглавленном ON CONFLICT.
2.1. Ограничения на операторы UPDATE в CREATE TRIGGER
Следующие дополнительные ограничения на синтаксис применяются к операторам UPDATE, которые встречаются в теле оператора CREATE TRIGGER.
Имя таблицы, указанное в операторе UPDATE внутри тела триггера, должно быть неквалифицированным. Другими словами, префикс имя_схемы. для имени таблицы в операторе UPDATE в триггерах недопустим. Если таблица, к которой прикреплен триггер, находится в базе данных TEMP, то таблица, обновляемая программой триггера, должна находиться в той же базе данных. Если таблица, к которой прикреплен триггер, находится в базе данных TEMP, то неквалифицированное имя обновляемой таблицы разрешается так же, как и для оператора верхнего уровня (сначала ищется в базе данных TEMP, затем в основной базе данных, а затем в других базах данных в порядке их подключения).
-
Операторы INDEXED BY и NOT INDEXED недопустимы в операторах UPDATE внутри триггеров.
Операторы LIMIT и ORDER BY для оператора UPDATE не поддерживаются внутри триггеров независимо от используемых параметров компиляции SQLite.
2.2. UPDATE FROM
Идея UPDATE-FROM — это расширение SQL, которое позволяет оператору UPDATE управляться другими таблицами в базе данных. "Целевая" таблица — это таблица, которая обновляется. С помощью UPDATE-FROM вы можете объединить целевую таблицу с другими таблицами в базе данных, чтобы помочь вычислить, какие строки необходимо обновить и какими должны быть новые значения в этих строках. UPDATE-FROM поддерживается начиная с SQLite версии 3.33.0 (2020-08-14).
Другие реляционные базы данных также реализуют UPDATE-FROM, но поскольку конструкция не является частью стандартов SQL, каждый продукт реализует UPDATE-FROM по-разному. Реализация SQLite стремится к совместимости с PostgreSQL. Реализации в SQL Server и MySQL этой же идеи работают немного по-другому.
В качестве примера того, как UPDATE-FROM может быть полезным, предположим, что у вас есть приложение для обработки продаж, которое накапливает покупки в таблице SALES. В конце дня вы хотите скорректировать таблицу INVENTORY в соответствии с ежедневными продажами. Для этого вы можете выполнить UPDATE таблицы INVENTORY, который корректирует количество на основе агрегированных продаж за день. Оператор будет выглядеть так:
UPDATE inventory SET quantity = quantity - daily.amt FROM (SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily WHERE inventory.itemId = daily.itemId;
Подзапрос в операторе FROM вычисляет величину, на которую необходимо уменьшить инвентарь для каждого itemId. Этот подзапрос объединяется с таблицей инвентаря, и количество каждой затронутой строки инвентаря уменьшается на соответствующую величину.
Целевая таблица не включается в оператор FROM, если только цель не состоит в том, чтобы выполнить самообъединение с целевой таблицей. В случае самообъединения таблица в операторе FROM должна быть алиасована под другим именем, чем целевая таблица.
Если объединение между целевой таблицей и таблицей в операторе FROM приводит к нескольким результативным строкам для одной и той же строки целевой таблицы, то для обновления целевой таблицы используется только одна из этих результативных строк. Выбор результативной строки произвольный и может меняться от одной версии SQLite к другой, а также от одного запуска к другому.
2.2.1. UPDATE FROM в других системах управления реляционными базами данных
SQL Server также поддерживает UPDATE FROM, но в SQL Server целевая таблица должна быть включена в оператор FROM. Другими словами, целевая таблица называется дважды в операторе. В SQL Server оператор корректировки инвентаря, показанный выше, запишется так:
UPDATE inventory
SET quantity = quantity - daily.amt
FROM inventory,
(SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily
WHERE inventory.itemId = daily.itemId;
MySQL поддерживает идею UPDATE FROM, но делает это без использования оператора FROM. Вместо этого полное описание объединения приводится между ключевыми словами UPDATE и SET. Эквивалентный оператор MySQL будет выглядеть так:
UPDATE inventory JOIN
(SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily
USING( itemId )
SET inventory.quantity = inventory.quantity - daily.amt;
Оператор UPDATE MySQL не имеет только одной целевой таблицы, как в других системах. Любая из таблиц, участвующих в объединении, может быть изменена в операторе SET. Синтаксис UPDATE MySQL позволяет обновлять сразу несколько таблиц!
2.3. Дополнительные предложения LIMIT и ORDER BY
Если SQLite скомпилирован с опцией SQLITE_ENABLE_UPDATE_DELETE_LIMIT времени компиляции, то синтаксис оператора UPDATE расширяется дополнительными предложениями ORDER BY и LIMIT следующим образом:
Если оператор UPDATE содержит оговорку LIMIT, максимальное количество строк, которые будут обновлены, определяется путём вычисления соответствующего выражения и приведения его к целому значению. Отрицательное значение интерпретируется как «нет ограничения».
Если выражение LIMIT вычисляет неотрицательное значение N, а оператор UPDATE содержит оговорку ORDER BY, то все строки, которые должны быть обновлены в отсутствие оговорки LIMIT, сортируются согласно ORDER BY, и обновляются первые N строк. Если оператор UPDATE также содержит оговорку OFFSET, она аналогичным образом вычисляется и приводится к целому значению. Если выражение OFFSET вычисляет неотрицательное значение M, то первые M строк пропускаются, и вместо них обновляются следующие N строк.
Если оператор UPDATE не содержит оговорку ORDER BY, то все строки, которые должны быть обновлены в отсутствие оговорки LIMIT, собираются в произвольном порядке перед применением оговорок LIMIT и OFFSET для определения того, какие из них фактически обновляются.
Оговорка ORDER BY в операторе UPDATE используется только для определения строк, попадающих в LIMIT. Порядок, в котором строки модифицируются, произвольный и не зависит от оговорки ORDER BY.
Последнее изменение этой страницы 2022-01-08 05:02:57 UTC
SQLite is in the Public Domain.
https://sqlite.org/lang_update.html