INSERT¶
DML-команда INSERT
используется для записи кортежей в
таблицу. На данный момент атомарность записи гарантируется только для
одного кортежа в рамках одного запроса.
Синтаксис¶
Выражение¶
Диаграмма
Литерал¶
Диаграмма
Параметры¶
- TABLE — имя таблицы. Соответствует правилам имен для всех объектов в кластере.
Примеры вставки данных¶
Тестовые таблицы
Примеры использования команд включают в себя запросы к тестовым таблицам.
С явным указанием колонок:
INSERT INTO warehouse (id, item, type) VALUES (1, 'bricks', 'heavy');
Без указания колонок (при условии, что передаются значения для всех колонок):
INSERT INTO warehouse VALUES (1, 'bricks', 'heavy');
Обработка конфликтов¶
В некоторых случаях вставка кортежа может вернуть ошибку, например, при попытке вставить кортеж с уже существующим индексом:
INSERT INTO warehouse (id, item, type)
VALUES (1, 'bricks', 'heavy');
Результат:
---
sbroad: Lua error (IR dispatch): LuaError(ExecutionError("sbroad: failed to create transaction: RolledBack(FailedTo(Insert, Some(Space), \"TupleFound: Duplicate key exists in unique index \\\"WAREHOUSE_pkey\\\" in space \\\"WAREHOUSE\\\" with old tuple - [1, 1934, \\\"bricks\\\", \\\"heavy\\\"] and new tuple - [1, 1934, \\\"bricks\\\", \\\"heavy\\\"]\"))"))
Для обработки таких ситуаций можно использовать необязательный параметр
ON CONFLICT
, который может принимать одно из трех значений:
FAIL
, вернуть ошибку в случае конфликтаREPLACE
, затереть старый кортеж новым по первичному ключуNOTHING
, ничего не делать (оставить старую версию кортежа)
Вариант с DO FAIL
предполагает, что запрос будет возвращать ошибку в
случае конфликта вставки. Может возникнуть ситуация, когда запрос
успешно вставит данные на части узлов хранения, но вернет ошибку на
остальных (данные на них откатятся), что приведет к неконсистентному
состоянию кластера.
Чтобы решить эту проблему, можно повторить вставку с другими параметрами
разрешения конфликта — например, DO REPLACE
(замена кортежа на новый).
Вариант с DO REPLACE
решает проблему конфликтов только в первичном
ключе. Если таблица содержит несколько уникальных индексов (помимо
первичного ключа) и конфликт произошел в одном из них, DO REPLACE
вернет ошибку. На узле хранения, где произошел конфликт, данные не будут
зафиксированы в таблице.
Вариант с DO NOTHING
никогда не возвращает ошибку из-за конфликтов в
уникальных индексах, т.к. просто оставляет старую версию кортежа в
таблице. При такой вставке в результате вернется только количество
успешно вставленных новых кортежей (кортежи, где был конфликт и остались
прежние данные, в подсчет не попадают).
Если параметр ON CONFLICT
не указан, то по умолчанию используется
поведение DO FAIL
.
INSERT INTO warehouse (id, item, type)
VALUES (1, 'bricks', 'heavy')
ON CONFLICT DO NOTHING;
Результат:
0
Для успешной вставки (замены кортежа) следует использовать вариант DO
REPLACE
:
INSERT INTO warehouse (id, item, type)
VALUES (1, 'bricks', 'heavy')
ON CONFLICT DO REPLACE;
Результат:
1
Ошибка вставки может также быть вызвана ограничениями неблокирующего
SQL. Если речь идет о запросе на вставку более одного
кортежа, то для исправления неконсистентного состояния кластера следует
повторить запрос с другим способом разрешения конфликтов DO NOTHING
.
Примечание
На данный момент вставка с обработкой конфликтов поддерживается только для шардированных таблиц
Параметризация¶
Параметризация значений при INSERT
влияет на тип
данных при выполнении запроса. Так, в обычном виде дробные числа
конвертируются в числа с фиксированной запятой (например, values(2.5)
в decimal 2.5
). В параметризированном виде дробнному числу будет
назначен типа с плавающей запятой (например, values(?), {2.5}
в
double 2.5
). См. подробнее о типах данных.