RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
UPDATE

1. Обзор

update-stmt:

WITH RECURSIVE common-table-expression , UPDATE OR ROLLBACK qualified-table-name OR REPLACE OR IGNORE OR FAIL OR ABORT SET column-name-list = expr column-name , FROM table-or-subquery , join-clause WHERE expr returning-clause

column-name-list:

common-table-expression:

expr:

join-clause:

qualified-table-name:

returning-clause:

table-or-subquery:

UPDATE используется, чтобы изменить подмножество значений, сохраненных в ноле или большем количестве строк таблицы базы данных, определенной полным именем таблицы, определенным как часть запроса UPDATE.

2. Детали

Если UPDATE не имеет WHERE, все строки в таблице изменяются UPDATE. Иначе UPDATE затрагивает только те строки, для которых WHERE оценен как true. Это не ошибка, если оператор Where не оценивается к true ни для какой строки в таблице, это просто означает, что UPDATE затрагивает нуль строк.

Модификации, сделанные к каждой строке, затронутой UPDATE, определяются списком назначений после ключевого слова SET. Каждое назначение определяет column-name, слева от знака равенства и скалярное выражение справа. Для каждой затронутой строки названные колонки установлены в значения, найденные, оценив соответствующие скалярные выражения. Если единственное имя столбца появляется несколько раз в списке выражений присваивания, все кроме самого правого возникновения проигнорированы. Колонки, которые не появляются в списке назначений, оставляют неизмененными. Скалярные выражения могут обратиться к колонкам обновляемой строки. В этом случае все скалярные выражения оценены, прежде чем любые назначения сделаны.

С SQLite version 3.15.0 (2016-10-14) назначение в пункте SET может быть списком имен столбцов слева и значением строк того же самого размера справа.

"OR action", который следует за ключевым словом UPDATE, позволяет пользователю номинировать определенный ограничительный алгоритм разрешения конфликтов, чтобы использовать во время этой команды UPDATE. См. ON CONFLICT.

2.1. Ограничения UPDATE в CREATE TRIGGER

Следующие дополнительные ограничения синтаксиса относятся к запросам UPDATE, которые происходят в теле запроса CREATE TRIGGER.

  • table-name, определенное как часть запроса UPDATE в триггере, должно быть неквалифицировано. Другими словами, префикс schema-name. имени таблицы не позволен в UPDATE в триггерах. Если таблица, к которой приложен триггер, не находится в базе данных TEMP, таблица, обновляемая триггером, должна быть в той же самой базе данных. Если таблица, к которой приложен триггер, находится в базе данных TEMP, то неквалифицированное название обновляемой таблицы решено таким же образом, как для запроса верхнего уровня (просмотр сначала БД TEMP, затем main, потом любые другие базы данных в порядоке, в котором они были приложены).

  • INDEXED BY и NOT INDEXED не позволены в UPDATE в триггерах.

  • LIMIT и ORDER BY в UPDATE не поддерживаются в триггерах, независимо от параметров компиляции, используемых, чтобы построить SQLite.

2.2. UPDATE FROM

Идея UPDATE FROM это расширение SQL, которое позволяет UPDATE вестись другими таблицами в базе данных. "Целевая" таблица "target" это таблица, которая обновляется. С UPDATE FROM можно присоединиться к целевой таблице против других таблиц в базе данных, чтобы помочь вычислить, каким строкам нужно обновление и чем должны быть новые значения. UPDATE FROM поддерживается, начиная с версии SQLite version 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 вычисляет сумму, на которую inventory должен быть уменьшен для каждого itemId. К тому подзапросу присоединяются для таблицы inventory и количество каждого затронутой строки уменьшается на эту сумму.

Целевая таблица не включена в пункт FROM, если намерение не состоит в том, чтобы сделать самосоединение против целевой таблицы. В случае самосоединения в пункте FROM должен быть псевдоним к другому имени, чем целевая таблица.

Если соединение между целевой таблицей и результатами пункта FROM в многократных строках вывода для той же самой целевой строки таблицы, то только одна из тех строк вывода используется для обновления целевой таблицы. Отобранная строка вывода произвольна и могла бы измениться от одного выпуска SQLite к следующему.

2.2.1. UPDATE FROM в других СУБД SQL

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. Вместо этого полная спецификация соединения дана в промежуточных ключевых словах SET и UPDATE. Эквивалентный запрос в 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;

У запроса MySQL UPDATE нет одной целевой таблицы как делают другие системы. Любая из таблиц, которые участвуют в соединении, может быть изменена в пункте SET. Синтаксис MySQL UPDATE позволяет вам обновлять многократные таблицы сразу!

2.3. LIMIT и ORDER BY

Если SQLite строится с выбором времени компиляции SQLITE_ENABLE_UPDATE_DELETE_LIMIT, синтаксис запроса UPDATE расширен с дополнительным пунктами ORDER BY и LIMIT следующим образом:

update-stmt-limited:

WITH RECURSIVE common-table-expression , UPDATE OR ROLLBACK qualified-table-name OR REPLACE OR IGNORE OR FAIL OR ABORT SET column-name-list = expr column-name , FROM table-or-subquery , join-clause WHERE expr returning-clause ORDER BY ordering-term , LIMIT expr OFFSET expr , expr

Если UPDATE имеет LIMIT, максимальное количество строк, которые будут обновлены, найдено, оценив сопровождающее выражение и приведя его к целочисленному значению. Отрицательная величина интерпретируется как "no 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.