UPDATE

Содержание раздела
  1. Поддерживаемые сущности и СУБД
  2. Особенности обновления данных в standalone-таблицы
  3. Сравнение с UPSERT VALUES и INSERT VALUES
  4. Как работает запрос
    1. Выбор датасорса-источника для SELECT
    2. Заполнение столбцов
    3. Выполнение при отключенном датасорсе
    4. Статистика
  5. Перезапуск и отмена операций
  6. Синтаксис
    1. Ключевое слово SET column_name = expression
    2. Ключевое слово FROM { [db_name2.]entity_name [FOR SYSTEM_TIME time_expression] [[AS] alias_name2] | (select) [AS] alias_name2 }
    3. Ключевое слово WHERE condition
    4. Ключевое слово RETRY
  7. Варианты ответа
  8. Ограничения
    1. Ограничения выполнения
    2. Ограничения СУБД
    3. Ограничения сущностей
    4. Ограничения партиционирования
    5. Другие ограничения
  9. Примеры
    1. Обновление столбца с заменой одной константы на другую
    2. Обновление столбца с дополнением константы префиксом
    3. Обновление столбца значениями из другой таблицы

Поддерживается в версиях: 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-подзапрос, источником данных служит датасорс (по убыванию приоритета):

  1. указанный в DATASOURCE_TYPE;
  2. подходящий для партиционированных и снапшот-таблиц подзапроса:
    1. первый по алфавиту среди подходящих для снапшот-таблиц со строгой консистентностью данных;
    2. наиболее подходящий для чтения/трансфера данных партиционированной или снапшот-таблицы, служащей источником/приемником;
  3. каждый целевой датасорс сам для себя (при наличии в них данных SELECT);
  4. подходящий для всех сущностей SELECT-подзапроса:
    1. [HTTP] вычисленный по queryId из подходящих;
    2. случайный из подходящих.

Заполнение столбцов

Все столбцы, указанные в запросе, заполняются значениями из запроса во всех записях таблицы, которые соответствуют условию 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%'