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