INSERT
Эта страница переведена при помощи нейросети GigaChat.
INSERT
- создание новых строк в таблице.
Синтаксис
[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ]
[ OVERRIDING { SYSTEM | USER } VALUE ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
[ ON CONFLICT [ conflict_target ] conflict_action ]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
where conflict_target can be one of:
( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ]
ON CONSTRAINT constraint_name
and conflict_action is one of:
DO NOTHING
DO UPDATE SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
( column_name [, ...] ) = ( sub-SELECT )
} [, ...]
[ WHERE condition ]
Описание
INSERT
вставляет новые строки в таблицу. Можно вставить одну или несколько строк, указанных списком значений (VALUES
), либо вставить ноль или более строк, полученных в результате выполнения запроса.
Имена целевых столбцов могут быть указаны в любом порядке. Если список имен столбцов не указан вовсе, то по умолчанию используются все столбцы таблицы в их объявленном порядке, или первые N
столбцов, если только N
столбцов поставляется через VALUES
или запрос. Значения, указанные через VALUES
или результаты запроса, сопоставляются со списком столбцов слева направо.
Каждый столбец, отсутствующий в явном или подразумеваемом списке столбцов, будет заполнен значением по умолчанию — либо его объявленным значением по умолчанию, либо NULL
, если значение по умолчанию не задано.
Если выражение для какого‑либо столбца не соответствует требуемому типу данных, PostgreSQL попытается выполнить автоматическое преобразование типа.
INSERT
в таблицы, у которых нет уникальных индексов, как правило, не блокирует другие операции. В таблицах с уникальными индексами эта операция может блокироваться, если в параллельных сеансах выполняются действия, которые блокируют или изменяют строки, совпадающие с вставляемыми значениями в уникальном индексе; подробнее смотрите раздел Проверки уникальности индекса. Можно использовать ON CONFLICT
, чтобы задать альтернативное действие при нарушении уникального или исключающего ограничения.
Необязательный параметр RETURNING
позволяет вычислить и вернуть значение или значения на основе каждой реально вставленной или обновленной строки (в случае ON CONFLICT DO UPDATE
). Это удобно при необходимости получить значения, задаваемые по умолчанию, например, номер секвенции SERIAL
. При этом можно использовать любое выражение с использованием столбцов таблицы. Синтаксис RETURNING
идентичен синтаксису списка вывода SELECT
. Возвращаются только строки, которые были реально вставлены или обновлены. Например, если строка не была обновлена из‑за несоответствия условия ON CONFLICT ... WHERE
, она не включается в возвращаемый результат.
Для выполнения INSERT
требуется привилегия INSERT
на целевую таблицу. При использовании ON CONFLICT DO UPDATE
также требуется привилегия UPDATE
на таблицу.
Если указан список столбцов, привилегии INSERT
нужны только на указанные столбцы. Аналогично, при использовании ON CONFLICT DO UPDATE
привилегии UPDATE
требуются только на столбцы, которые будут обновляться. Однако сам ON CONFLICT DO UPDATE
также требует привилегии SELECT
на любые столбцы, значения которых используются в его выражениях или условиях.
Использование RETURNING
также требует привилегии SELECT
на все упоминаемые в нем столбцы. При вставке строк из запроса необходима привилегия SELECT
на все таблицы и столбцы, используемые в этом запросе.
Параметры
Вставка
Этот раздел охватывает параметры, которые могут использоваться только при вставке новых строк. Параметры исключительно используются с предложением ON CONFLICT
описываются отдельно.
with_query
- Предложение
WITH
позволяет определить один или несколько подзапросов, доступных по имени внутри командыINSERT
. Подробнее смотрите документацию по SELECT.Если сама команда
SELECT
, используемая внутриINSERT
, содержит свойWITH
, то можно ссылаться на оба, но вложенныйWITH
имеет приоритет.
table_name
- Имя существующей таблицы, при необходимости дополненное схемой.
alias
- Замещающее имя для
table_name
. После его указания таблица скрывается за псевдонимом. Это полезно приON CONFLICT DO UPDATE
, чтобы избежать конфликтов имен с системной таблицейexcluded
.
column_name
- Имя столбца в таблице
table_name
. Это имя столбца при необходимости может быть дополнено именем вложенного поля или индексом в массиве. Когда данные вставляются только в некоторые поля столбца составного типа, в другие поля записываетсяNULL
. Обращаясь к столбцу в предложенииON CONFLICT DO UPDATE
, включать имя таблицы в ссылку на целевой столбец не нужно. Например, запись INSERT INTO table_name ... ON CONFLICT DO UPDATE SET table_name.col = 1
некорректна (это согласуется с общим поведением командыUPDATE
).
OVERRIDING SYSTEM VALUE
- Если этот параметр указан, то любые значения, предоставленные для столбцов идентичности, заменят значения, генерируемые по умолчанию последовательностью.
Для столбца идентичности, определенного как
GENERATED ALWAYS
, возникает ошибка при вставке явного значения (кромеDEFAULT
) без указания либоOVERRIDING SYSTEM VALUE
, либоOVERRIDING USER VALUE
. Для столбца идентичности, определенного какGENERATED BY DEFAULT
,OVERRIDING SYSTEM VALUE
является нормальным поведением и его указание ничего не делает, но PostgreSQL допускает это как расширение.
OVERRIDING USER VALUE
- Если этот параметр указан, то любые значения, указанные для столбцов идентичности, игнорируются и применяются значения, сгенерированные по умолчанию последовательностью.
Параметр полезен, например, при копировании значений между таблицами. Запись
INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM tbl1
будет копировать изtbl1
все столбцы, которые не являются столбцами идентичности вtbl2
, тогда как значения для столбцов идентичности вtbl2
будут генерироваться последовательностями, связанными сtbl2
.
DEFAULT VALUES
- Все столбцы будут заполнены значениями по умолчанию, так, как если бы
DEFAULT
был явно указан для каждого столбца. ПредложениеOVERRIDING
в этой форме не допускается.
expression
- Выражение или значение, которое следует присвоить соответствующему столбцу.
DEFAULT
- Соответствующий столбец будет заполнен его значением по умолчанию. Столбец идентичности будет заполнен новым значением, сгенерированным связанной последовательностью. Для сгенерированного столбца указание этого разрешено, но просто указывает нормальное поведение вычисления столбца из выражения генерации.
query
- Запрос (
SELECT
утверждение), который предоставляет строки для вставки. Обратитесь к команде SELECT, чтобы получить описание синтаксиса.
output_expression
- Выражение, которое должно быть вычислено и возвращено командой
INSERT
после вставки или обновления каждой строки. Выражение может использовать любые имена столбцов таблицы, указанной вtable_name
. Используйте*
, чтобы вернуть все столбцы вставленной или обновленной строки (строк).
output_name
- Имя возвращаемого столбца.
Предложение ON CONFLICT
Опциональное предложение ON CONFLICT
указывает альтернативное действие вместо вызова ошибки нарушения уникальности или ограничения исключения. Для каждой отдельной строки, предлагаемой для вставки, либо происходит вставка, либо, если нарушено арбитражное ограничение или индекс, указанный в conflict_target
, выполняется альтернативное действие — conflict_action
.
ON CONFLICT DO NOTHING
просто избегает вставки строки как альтернативное действие. ON CONFLICT DO UPDATE
обновляет существующую строку, которая конфликтует с предлагаемой для вставки строкой.
conflict_target
может выполнять вывод уникального индекса. При выполнении вывода он состоит из одного или нескольких столбцов index_column_name
и/или выражений index_expression
, а также необязательного index_predicate
. Все уникальные индексы таблицы table_name
, которые, независимо от порядка, содержат ровно те столбцы/выражения, что указаны в conflict_target
, считаются подходящими арбитражными индексами. Если указан index_predicate
, то арбитражные индексы также должны соответствовать ему как дополнительному требованию. Обратите внимание, что это означает: если доступен уникальный индекс без предиката, который удовлетворяет всем другим критериям, он будет использован при ON CONFLICT
. Если попытка вывода индекса неудачна — будет вызвана ошибка.
ON CONFLICT DO UPDATE
гарантирует атомарность выполнения — либо вставка, либо обновление, но не обе сразу. Если не возникло других ошибок, гарантируется одно из двух действий, даже при высокой параллельности. Такое поведение также известно как UPSERT
(объединение UPDATE
и INSERT
).
conflict_target
- Указывает, на какие конфликты
ON CONFLICT
должен реагировать, выбирая арбитражные индексы. Либо выполняется вывод уникального индекса, либо явно указывается ограничение. ДляON CONFLICT DO NOTHING
указыватьconflict_target
необязательно — при его отсутствии обрабатываются конфликты со всеми применимыми ограничениями и уникальными индексами. ДляON CONFLICT DO UPDATE
указаниеconflict_target
обязательно.
conflict_action
- Указывает альтернативное действие, которое следует предпринять при конфликте. Это может быть либо
DO NOTHING
, либо предложениеDO UPDATE
, которое определяет точные действия по обновлению конфликтующей строки.Внутри
SET
иWHERE
вON CONFLICT DO UPDATE
доступ к существующей строке осуществляется по имени таблицы (или псевдониму), а к предложенной для вставки строке — через специальную таблицуexcluded
. Для использованияexcluded
требуется привилегияSELECT
на все читаемые в выражениях столбцы целевой таблицы.Обратите внимание, все триггеры уровня строки
BEFORE INSERT
влияют на значения вexcluded
, так как их действия могли повлиять на то, что строка была исключена из вставки.
index_column_name
- Имя столбца в таблице
table_name
. Используется для вывода арбитражных индексов. Формат такой же, как вCREATE INDEX
. Необходима привилегияSELECT
на указанный столбец.
index_expression
- Аналогично
index_column_name
, но используется для выражений в определениях индексов, не являющихся простыми столбцами. Формат соответствуетCREATE INDEX
. Требуется привилегияSELECT
на все столбцы, используемые в выражении.
collation
- Требует, чтобы соответствующие
index_column_name
илиindex_expression
использовали определенную сортировку. Обычно не указывается, так как сортировка редко влияет на нарушения ограничений. Формат аналогичен CREATE INDEX
.
opclass
- Требует использование конкретного класса операторов для соответствующего
index_column_name
илиindex_expression
при выводе индексов. Обычно не требуется, так как семантика равенства одинакова для большинства классов. Формат также аналогиченCREATE INDEX
.
index_predicate
- Используется для вывода частичных уникальных индексов. Можно выводить любой индекс, удовлетворяющий предикату, даже если он сам по себе не является частичным. Формат такой же, как в
CREATE INDEX
. Требуется привилегияSELECT
на все используемые в выражении столбцы.
constraint_name
- Указывает явно имя ограничения для использования в качестве арбитражного, вместо вывода индекса или ограничения.
condition
- Задает выражение, возвращающее значение типа
boolean
. Обновлены будут только те строки, для которых это выражение возвращаетtrue
. Однако при выполнении действияON CONFLICT DO UPDATE
все конфликтующие строки блокируются. Обратите внимание,condition
вычисляется после определения конфликта, на основании которого происходит выбор строки для обновления.
Ограничения исключения не поддерживаются как арбитры для ON CONFLICT DO UPDATE
. Во всех случаях поддерживаются только ограничения NOT DEFERRABLE
и уникальные индексы.
INSERT
с ON CONFLICT DO UPDATE
является детерминированным: команда не может повлиять на одну и ту же строку более одного раза. В случае, если строки, предложенные к вставке, дублируют друг друга по атрибутам, охваченным арбитражным индексом или ограничением, будет вызвана ошибка нарушения кардинальности.
Также обратите внимание: в настоящий момент не поддерживается выполнение ON CONFLICT DO UPDATE
в INSERT
, примененном к партиционированной таблице, если это приведет к необходимости переместить строку в другую партицию.
Предпочтительнее использовать вывод уникального индекса, а не явное указание ограничения через ON CONFLICT ON CONSTRAINT constraint_name
.
Вывод продолжит работать корректно, даже если исходный индекс будет заменен другим эквивалентным, например, при использовании CREATE UNIQUE INDEX ... CONCURRENTLY
перед удалением старого индекса.
Выводимая информация
При успешном завершении команда INSERT
возвращает тег команды следующего вида:
INSERT oid count
где count
- это количество вставленных или обновленных строк, oid
— всегда 0. Раньше это был OID вставленной строки при таблицах WITH OIDS
, но сейчас этот режим устарел.
Если использован RETURNING
, будет возвращен набор строк, аналогичный SELECT
.
Примечания
Если указанная таблица является партиционированной, каждая строка автоматически направляется в соответствующую партицию и вставляется в нее. Если указанная таблица является партицией, произойдет ошибка, если одна из входных строк нарушает ограничение раздела.
Также можно рассмотреть возможность использования MERGE
, поскольку это позволяет объединить INSERT
, UPDATE
и DELETE
внутри одного оператора. Смотрите MERGE.
Примеры
Добавление одной строки в таблицу films
:
INSERT INTO films VALUES
('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');
В этом примере столбец len
опускается и, таким образом, получает значение по умолчанию:
INSERT INTO films (code, title, did, date_prod, kind)
VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
В этом примере для столбца с датой задается указание DEFAULT
, а не явное значение:
INSERT INTO films VALUES
('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes');
INSERT INTO films (code, title, did, date_prod, kind)
VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');
Добавление строки, полностью состоящей из значений по умолчанию:
INSERT INTO films DEFAULT VALUES;
Добавление нескольких строк с использованием многострочного синтаксиса VALUES
:
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
В этом примере в таблицу films
вставляются некоторые строки из таблицы tmp_films
, имеющей ту же структуру столбцов, что и films
:
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
Этот пример демонстрирует добавление данных в столбцы с типом массива:
-- Create an empty 3x3 gameboard for noughts-and-crosses
INSERT INTO tictactoe (game, board[1:3][1:3])
VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
-- The subscripts in the above example aren't really needed
INSERT INTO tictactoe (game, board)
VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');
Добавление одной строки в таблицу distributors
и получение последовательного номера, сгенерированного благодаря указанию DEFAULT
:
INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')
RETURNING did;
Увеличение счетчика продаж для продавца, занимающегося компанией Acme Corporation, и сохранение всей измененной строки вместе с текущим временем в таблице журнала:
WITH upd AS (
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
RETURNING *
)
INSERT INTO employees_log SELECT *, current_timestamp FROM upd;
Добавление дистрибьюторов или изменение существующих данных должным образом. Предполагается, что в таблице определен уникальный индекс, ограничивающий значения в столбце did
. Заметьте, что для обращения к значениям, изначально предлагаемым для добавления, используется специальная таблица excluded
:
INSERT INTO distributors (did, dname)
VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
Добавление дистрибьютора или отсутствие действий для строк, предложенных для добавления, если уже есть существующая исключающая строка (строка, содержащая конфликтующие значения в столбце или столбцах после срабатывания триггеров перед добавлением строки). В данном примере предполагается, что определен уникальный индекс, ограничивающий значения в столбце did
:
INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH')
ON CONFLICT (did) DO NOTHING;
Добавление дистрибьюторов или изменение существующих данных должным образом. В данном примере предполагается, что в таблице определен уникальный индекс, ограничивающий значения в столбце did
. Предложение WHERE
позволяет ограничить набор фактически изменяемых строк (однако любая существующая строка, не подлежащая изменению, все же будет заблокирована):
-- Don't update existing distributors based in a certain ZIP code
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
ON CONFLICT (did) DO UPDATE
SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
WHERE d.zipcode <> '21201';
-- Name a constraint directly in the statement (uses associated
-- index to arbitrate taking the DO NOTHING action)
INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design')
ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;
Добавление дистрибьютора, если возможно. В противном случае не делать ничего (DO NOTHING
). В данном примере предполагается, что в таблице определен уникальный индекс, ограничивающий значения в столбце did
по подмножеству строк, в котором логический столбец is_active
содержит true
:
-- This statement could infer a partial unique index on "did"
-- with a predicate of "WHERE is_active", but it could also
-- just use a regular unique constraint on "did"
INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
ON CONFLICT (did) WHERE is_active DO NOTHING;
Совместимость
INSERT
соответствует стандарту SQL, за исключением следующих расширений:
- предложение
RETURNING
; - использование
WITH
совместно сINSERT
; - возможность указания альтернативного действия через
ON CONFLICT
.
Кроме того, стандарт SQL не допускает случай, когда список имен столбцов опущен, но при этом в VALUES
или запросе указаны значения не для всех столбцов. Если нужно более соответствующее стандарту SQL утверждение, чем ON CONFLICT
, смотрите MERGE.
Стандарт SQL указывает, что OVERRIDING SYSTEM VALUE
можно указывать только в том случае, если существует всегда генерируемый столбец идентичности. PostgreSQL позволяет использовать это условие в любом случае и игнорирует его, если оно неприменимо.
Возможные ограничения условия query
описаны в разделе SELECT.