UPDATE
Изменяет строки таблицы.
Синтаксис
[ WITH [ RECURSIVE ] <with_query> [, ...] ]
UPDATE [ONLY] <table> [[AS] <alias>]
SET {<column> = {<expression> | DEFAULT} |
(<column> [, ...]) = ({<expression> | DEFAULT} [, ...])} [, ...]
[FROM <fromlist>]
[WHERE <condition> | WHERE CURRENT OF <cursor_name> ]
[RETURNING * | <output_expression> [[AS] <output_name> ] [, ...]]
Описание
UPDATE изменяет значения указанных столбцов во всех строках, удовлетворяющих условию. В выражении SET необходимо указать только те столбцы, которые нужно изменить; столбцы, не изменяемые явно, сохраняют свои предыдущие значения.
По умолчанию команда UPDATE обновляет строки в указанной таблице и во всех ее подтаблицах. Если нужно обновить только указанную таблицу, используйте выражение ONLY.
Существует два способа изменить таблицу, используя информацию из других таблиц базы данных: с помощью подзапросов или путем указания дополнительных таблиц в выражении FROM. Какой метод более подходит, зависит от конкретных обстоятельств.
Если указано выражение WHERE CURRENT OF, обновляется та строка, которая была получена из указанного курсора последней.
WHERE CURRENT OF не поддерживается для реплицированных таблиц.
Для обновления таблицы или как минимум столбцов, которые указаны в списке для изменения, необходимо иметь привилегию UPDATE. Также необходимо иметь привилегию SELECT для всех столбцов, значения которых считываются в выражениях или условии.
По умолчанию Greengage DB получает блокировку EXCLUSIVE на таблицы для операций UPDATE в heap-таблицах. Если включен Global Deadlock Detector, режим блокировки для операций UPDATE в heap-таблицах становится ROW EXCLUSIVE.
Выводимая информация
В случае успешного выполнения команды UPDATE возвращается сообщение вида:
UPDATE <count>
где count — количество измененных строк. Если значение count равно 0, значит, ни одна строка не соответствует условию (это не считается ошибкой).
Параметры
| Параметр | Описание |
|---|---|
with_query |
Выражение Для команды Запрос (оператор См. Общие табличные выражения (CTE) и SELECT для получения дополнительной информации |
ONLY |
Если указан, изменяются строки только в указанной таблице. Если не указан, обрабатываются также все таблицы, наследуемые от указанной таблицы |
table |
Имя существующей таблицы (опционально указанное со схемой) |
alias |
Альтернативное имя для целевой таблицы. Если указан псевдоним, он полностью скрывает фактическое имя таблицы. Например, в запросе |
column |
Имя столбца в таблице. При необходимости имя столбца может быть дополнено именем подстолбца или индексом массива. Имя таблицы добавлять к имени целевого столбца не нужно |
expression |
Выражение, результат которого будет присваиваться столбцу. В этом выражении могут использоваться предыдущие значения этого и других столбцов таблицы |
DEFAULT |
Присвоить столбцу значение по умолчанию (это может быть NULL, если для столбца не определено выражение по умолчанию) |
fromlist |
Список табличных выражений, позволяющих обращаться к столбцам других таблиц в условии |
condition |
Выражение, возвращающее значение типа boolean. Будут изменены только те строки, для которых это выражение возвращает |
cursor_name |
Имя курсора, который будет использоваться в условии Обратите внимание, что За дополнительными сведениями о создании курсоров обратитесь к описанию DECLARE |
output_expression |
Выражение, которое будет вычислено и возвращено командой |
output_name |
Имя, назначаемое возвращаемому столбцу |
Примечания
Использование оператора SET для столбцов ключа распределения таблицы в Greengage DB запрещено.
При наличии выражения FROM целевая таблица, по сути, соединяется с таблицами, указанными в списке FROM, и каждая выходная строка соединения представляет собой операцию изменения для целевой таблицы. При использовании FROM необходимо убедиться, что соединение создает не более одной выходной строки для каждой строки, которую нужно изменить. Другими словами, целевая строка не должна соединяться более чем с одной строкой из других таблиц. Если это условие нарушается, то для обновления целевой строки будет использована только одна из строк соединения, но какая именно, предсказать сложно.
Из-за этой неопределенности обращение к другим таблицам только внутри подзапросов является более безопасным, хотя часто такие запросы хуже читаются и работают медленнее, чем соединение.
Выполнение команд UPDATE и DELETE непосредственно для определенной партиции (дочерней таблицы) партиционированной таблицы не поддерживается. Вместо этого выполняйте эти команды для корневой партиционированной таблицы, созданной с помощью команды CREATE TABLE.
Для партиционированной таблицы при отключенном (по умолчанию) Global Deadlock Detector во время операции UPDATE блокируются все дочерние таблицы. При включенном Global Deadlock Detector блокируются только некоторые из дочерних таблиц.
Примеры
Изменение слова Drama на Dramatic в столбце kind таблицы films:
UPDATE films
SET kind = 'Dramatic'
WHERE kind = 'Drama';
Изменение значений температуры и сброс уровня осадков к значению по умолчанию в одной строке таблицы weather:
UPDATE weather
SET temp_lo = temp_lo + 1,
temp_hi = temp_lo + 15,
prcp = DEFAULT
WHERE city = 'San Francisco'
AND date = '2016-07-03';
Выполнение того же изменения с применением альтернативного синтаксиса со списком столбцов:
UPDATE weather
SET (temp_lo, temp_hi, prcp) = (temp_lo + 1, temp_lo + 15, DEFAULT)
WHERE city = 'San Francisco'
AND date = '2016-07-03';
Увеличение количества продаж для продавца, занимающегося компанией Acme Corporation, с применением выражения FROM (при условии, что обе объединяемые таблицы распределены в Greengage DB по столбцу id):
UPDATE employees
SET sales_count = sales_count + 1
FROM accounts
WHERE accounts.name = 'Acme Corporation'
AND employees.id = accounts.id;
Выполнение того же изменения с подзапросом в выражении WHERE:
UPDATE employees
SET sales_count = sales_count + 1
WHERE id = (SELECT id FROM accounts WHERE name = 'Acme Corporation');
Попытка добавить новый продукт с указанием его количества. Если продукт уже существует, изменяется его количество в существующей записи. Чтобы реализовать этот подход, не откатывая всю транзакцию, можно использовать точки сохранения:
BEGIN;
-- другие операции
SAVEPOINT sp1;
INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
-- Предполагая, что описанная выше операция завершается ошибкой из-за нарушения уникальности ключа,
-- выполняем следующие команды:
ROLLBACK TO sp1;
UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003';
-- другие операции и завершение
COMMIT;
Совместимость
Эта команда соответствует стандарту SQL, за исключением того, что выражение FROM является расширением Greengage DB.
Согласно стандарту, значения списку столбцов могут быть назначены из выражения, выдающего одну строку со значениями для нужного количества целевых столбцов, например, это может быть подзапрос:
UPDATE accounts
SET (contact_last_name, contact_first_name) =
(SELECT last_name, first_name
FROM salesmen
WHERE salesmen.id = accounts.sales_id);
В настоящее время это не реализовано — источником значений должен быть список независимых выражений.
В некоторых других системах баз данных поддерживается выражение FROM, в котором предполагается, что целевая таблица должна быть указана повторно. Greengage DB интерпретирует FROM иначе. Будьте осторожны при портировании приложений, использующих это расширение.