UPDATE
Содержание раздела
Поддерживается в версиях: 7.6 / 7.5 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.12 / 6.11 / 6.10 / 6.9.
Запрос обновляет значения указанных столбцов во всех записях таблицы, соответствующих условию.
Значения столбца можно обновить (см. синтаксис ниже):
- константой;
- значением выражения;
- результатом SELECT-подзапроса к другим сущностям.
Поддерживаемые сущности и СУБД
Обновление данных доступно в сущностях и СУБД, перечисленных ниже.
| Таблица | ADP | ADB | ADG | ADQM |
|---|---|---|---|---|
| Обычная логическая таблица | + | + | + | + |
| Партиционированная таблица, партиция* | + | – | – | – |
Снапшот-таблица* (если опция set.on.conflict.do не задана или равна update) | + | – | – | – |
| Прокси- или standalone-таблица | + | + | – | – |
* Партицированные таблицы, партиции и снапшот-таблицы могут размещаться только в ADP.
В снапшот-таблицах с опциями set.on.conflict.do=error и set.on.conflict.do=nothing обновление текущих записей невозможно.
Особенности обновления данных в standalone-таблицы
Обновление данных в standalone-таблицах выполняется через внешние writable-таблицы.
Сравнение с UPSERT VALUES и INSERT VALUES
Сравнение основных характеристик UPDATE, UPSERT VALUES и INSERT VALUES см. в таблице ниже.
| Запрос | СУБД | Вставка новых записей | Обновление записей | Обновление по условию | Столбцы, перезаписываемые при обновлении |
|---|---|---|---|---|---|
| UPDATE | Зависят от типа таблицы | – | + | + | Указанные в запросе |
| UPSERT VALUES | ADP, ADB | + | + | – | Указанные в запросе |
| INSERT VALUES | Все | + | + | – | Все |
Как работает запрос
Выбор датасорса-источника для SELECT
Если запрос содержит SELECT-подзапрос, источником данных служит датасорс (по убыванию приоритета):
- указанный в DATASOURCE_TYPE;
- подходящий для партиционированных и снапшот-таблиц подзапроса:
- первый по алфавиту среди подходящих для снапшот-таблиц со строгой консистентностью данных;
- наиболее подходящий для чтения/трансфера данных партиционированной или снапшот-таблицы, служащей источником/приемником;
- каждый целевой датасорс сам для себя (при наличии в них данных SELECT);
- подходящий для всех сущностей SELECT-подзапроса:
- [HTTP] вычисленный по queryId из подходящих;
- случайный из подходящих.
Заполнение столбцов
Все столбцы, указанные в запросе, заполняются значениями из запроса во всех записях таблицы, которые соответствуют условию WHERE. Значения неуказанных столбцов остаются без изменений.
Обновление столбцов, составляющий первичный ключ логической таблицы или снапшот-таблицы, недоступно.
Выполнение при отключенном датасорсе
Отключенный датасорс пропускается при исполнении запроса. Обновление данных считается успешным, если данные сохранены в необходимые датасорсы.
Статистика
Запросы UPDATE учитываются в категории WRITE статистики. Подробнее о категориях запросов в статистике см. в разделе GET_ENTITY_STATISTICS, о способах просмотра статистики — в разделе Управление статистикой.
Перезапуск и отмена операций
Кластер с кворумом нод автоматически отменяет сбойные операции записи при типовых сбоях, исключая необходимость ручного вмешательства.
Возможности по ручному управлению операциями описаны в разделе Управление операциями записи.
Синтаксис
[RETRY] UPDATE [db_name1.]table_name [[AS] alias_name1]
SET column_name = expression
[, ... ]
[FROM { [db_name2.]entity_name [FOR SYSTEM_TIME time_expression] [[AS] alias_name2] |
(select) [AS] alias_name2 } ]
[WHERE condition]
Параметры:
db_name-
Имя логической базы данных. Опционально, если выбрана логическая БД, используемая по умолчанию. Значения
db_name1иdb_name2могут как совпадать, так и отличаться. table_name-
Имя целевой таблицы. Возможные значения:
- имя логической таблицы,
- имя снапшот-таблицы,
- имя прокси-таблицы,
- имя внешней writable-таблицы, указывающей на standalone-таблицу.
alias_name-
Псевдоним таблицы или представления. Может включать латинские буквы, цифры и символы подчеркивания.
Ключевое слово SET column_name = expression
Задает имена обновляемых столбцов таблицы и выражения для обновления значений этих столбцов.
Возможные варианты выражения:
- константа;
- выражение, доступное для вычисления в целевых датасорсах;
- [для прокси- и standalone-таблиц] SELECT-подзапрос, доступный для исполнения в целевых датасорсах.
Ключевое слово FROM { [db_name2.]entity_name [FOR SYSTEM_TIME time_expression] [[AS] alias_name2] | (select) [AS] alias_name2 }
Задает имя сущности (entity_name) или SELECT-подзапрос (select), которые служат источником данных. Может включать ключевое слово SYSTEM_TIME.
Вставка доступна в любом из следующих случаев:
- [локальное исполнение] все целевые датасорсы содержат выбираемые данные;
- [трансфер между датасорсами] выбранный датасорс-источник также является одним из целевых датасорсов и поддерживает трансфер данных во все остальные целевые датасорсы (см. таблицу ниже).
В таблице ниже показаны сочетания типов датасорсов, между которыми поддерживается трансфер данных при исполнении запроса.
| Сущности-источники | Таблица-приемник | Датасорс-источник | Целевой датасорс | |||
|---|---|---|---|---|---|---|
| ADP | ADG | ADQM | ADB | |||
| Любые, кроме снапшот-таблиц | Любая из поддерживаемых | ADP | + | + | – | – |
| ADB | + | + | + | – | ||
| Снапшот-таблицы | Логическая или снапшот-таблица | ADP | + | – | – | – |
| Прокси- или standalone-таблица | ADP | + | + | – | – | |
Датасорсы таблицы можно указать при ее создании. Датасорсы существующей таблицы можно изменять для логических таблиц и снапшот-таблиц командами ALTER TABLE ADD DATASOURCE (добавляет датасорс) и DROP TABLE … DATASOURCE_TYPE (удаляет датасорс).
Ключевое слово WHERE condition
Задает условие выбора обновляемых строк таблицы. Условие может содержать сравнение с константами, подзапросы и JOIN-соединения.
Если в условии указан SELECT-подзапрос, он должен быть доступен для исполнения во всех датасорсах, где размещены данные таблицы.
Если ключевое слово не указано, обновляются все строки таблицы.
Ключевое слово RETRY
При типовых сбоях (перебои в сети, сбой ноды и т.п.) операции отменяются автоматически и не требуют ручного управления с помощью RETRY или других команд.
Перезапускает обработку операции записи со статусом 0 (Выполняется) в логической таблице. Если указано, после него должна следовать копия исходного запроса, создавшего перезапускаемую операцию.
Не поддерживается для других таблиц:
- игнорируется для прокси- и standalone-таблиц;
- приводит к ошибке для снапшот-таблиц.
Если ключевое слово не указано, система обрабатывает запрос как новый, а не перезапущенный.
Варианты ответа
В ответе возвращается:
- объект ResultSet c одной записью при успешном выполнении запроса;
- исключение при неуспешном выполнении запроса.
Успешный ответ содержит столбцы:
sysCn:- номер выполненной операции записи — при вставке в логическую или снапшот-таблицу;
- пустое значение — при вставке в прокси-таблицу или во внешнюю writable-таблицу;
ts:- дата и время завершения операции записи в формате
YYYY-MM-DD hh:mm:ss.SSSSSS— при выполнении операции вне дельты; - пустое значение — при выполнении операции в дельте;
- дата и время завершения операции записи в формате
rowsAffected— количество затронутых (добавленных, измененных и удаленных) строк. Расчет значения поддерживается для СУБД ADB и ADP.
Запрос с RETRY возвращает в rowsAffected количество строк, затронутых перезапущенной операцией записи. Строки, обработанные до перезапуска операции, не учитываются.
Ограничения
Ограничения выполнения
- Выполнение запроса к логической или снапшот-таблице недоступно, если она участвует в незавершенной операции по изменению схемы.
- Выполнение запроса вне дельты недоступно, если последняя дельта закрыта с меткой времени, превышающей серверное время.
- Не допускается параллельное выполнение идентичных запросов.
Ограничения СУБД
- Запрос доступен для логических таблиц, размещенных в любых поддерживаемых СУБД, для снапшот-таблиц (доступны только в ADP) и прокси-таблиц и standalone-таблиц, размещенных в ADB или ADP.
Ограничения сущностей
- Запрос недоступен для логических и материализованных представлений.
- Обновление записей невозможно в снапшот-таблицах с опциями
set.on.conflict.do=error(возвращается ошибка) иset.on.conflict.do=nothing(изменения пропускаются без ошибки). - Недоступно обновление значений столбцов логической таблицы, входящих в первичный ключ.
Ограничения партиционирования
- Одновременная запись данных (загрузка, вставка и удаление) в партиционированную таблицу и ее партиции недоступна.
Другие ограничения
- Все сущности, указанные в запросе на обновление столбцов прокси- или standalone-таблицы, должны размещаться в том же датасорсе, что и целевая таблица.
- Ключевое слово
SET, указанное в запросе на обновление столбцов логической таблицы, не может содержать SELECT-подзапрос. - Ключевое слово
RETRYдоступно только для логических таблиц; для других таблиц игнорируется или приводит к ошибке. - При обработке запроса отключенные (Датасорс, отключенный системой из-за сбоя или администратором
) датасорсы (СУБД или кластер СУБД хранилища
) пропускаются без возврата ошибки. Ошибка возвращается, если не осталось включенных (Датасорс, работающий в штатном режиме
) датасорсов, необходимых для записи данных.
Примеры
Обновление столбца с заменой одной константы на другую
UPDATE marketing.stores SET description = 'Магазин' WHERE description = 'Отдельный магазин'
Обновление столбца с дополнением константы префиксом
UPDATE marketing.payments_proxy SET type_code = 'RU_' || type_code WHERE currency_code = '643' OR currency_code = '810';
UPDATE marketing.payments_proxy SET type_code = 'US_' || type_code WHERE currency_code = '840';
UPDATE marketing.payments_proxy SET type_code = 'EU_' || type_code WHERE currency_code = '978';
UPDATE marketing.payments_proxy SET type_code = 'OT_' || type_code WHERE currency_code NOT IN ('643', '810', '840', '978');
Обновление столбца значениями из другой таблицы
UPDATE marketing.sales_snapshot as ssn
SET product_code = sl.product_code
FROM marketing.sales as sl
WHERE ssn.id = sl.id and ssn.product_code LIKE 'ABC0%'