INSERT#
INSERT
INSERT — создание новых строк в таблице
Синтаксис
[ WITH [ RECURSIVE ]with_query
[, ...] ] INSERT INTOtable_name
[ ASalias
] [ (column_name
[, ...] ) ] [ OVERRIDING { SYSTEM | USER } VALUE ] { DEFAULT VALUES | VALUES ( {expression
| DEFAULT } [, ...] ) [, ...] |query
} [ ON CONFLICT [conflict_target
]conflict_action
] [ RETURNING { * |output_expression
[ [ AS ]output_name
] } [, ...] ] whereconflict_target
can be one of: ( {index_column_name
| (index_expression
) } [ COLLATEcollation
] [opclass
] [, ...] ) [ WHEREindex_predicate
] ON CONSTRAINTconstraint_name
andconflict_action
is one of: DO NOTHING DO UPDATE SET {column_name
= {expression
| DEFAULT } | (column_name
[, ...] ) = [ ROW ] ( {expression
| DEFAULT } [, ...] ) | (column_name
[, ...] ) = (sub-SELECT
) } [, ...] [ WHEREcondition
]
Описание
INSERT
вставляет новые строки в таблицу.
Можно вставить одну или несколько строк, указанных выражениями значений,
или ноль или более строк, полученных из запроса.
Имена целевых столбцов могут быть перечислены в любом порядке. Если вообще не указан список имен столбцов, то по умолчанию используются все столбцы таблицы в их объявленном порядке; или первые N
имен столбцов, если в VALUES
или query
указано только N
столбцов. Значения, указанные в VALUES
или query
, связываются с явным или неявным списком столбцов слева направо.
Каждая колонка, отсутствующая в явном или неявном списке колонок, будет заполнена значением по умолчанию, либо ее объявленным значением по умолчанию, либо значением null, если такового нет.
Если выражение для любого столбца не является правильным типом данных, будет попытка автоматического преобразования типов.
INSERT
в таблицы, не имеющие уникальных индексов, не будет блокироваться параллельной активностью. Таблицы с уникальными индексами могут быть заблокированы, если параллельные сессии выполняют действия, которые блокируют или изменяют строки, соответствующие уникальным значениям индекса, которые вставляются; подробности описаны в Раздел 61.5. ON CONFLICT
может использоваться для указания альтернативного действия вместо возникновения ошибки нарушения ограничения уникальности или исключения (см. ON CONFLICT Clause ниже).
Необязательное предложение RETURNING
заставляет INSERT
вычислять и возвращать значения на основе каждой фактически вставленной строки (или обновленной, если использовалось предложение ON CONFLICT DO UPDATE
). Это особенно полезно для получения значений, которые были предоставлены по умолчанию, таких как серийный номер последовательности. Однако разрешено использование любого выражения, использующего столбцы таблицы. Синтаксис списка RETURNING
идентичен синтаксису списка вывода SELECT
. Будут возвращены только строки, которые были успешно вставлены или обновлены. Например, если строка была заблокирована, но не обновлена, потому что условие предложения ON CONFLICT DO UPDATE ... WHERE
condition
не было выполнено, строка не будет возвращена.
необходимо иметь привилегию INSERT
на таблицу, чтобы вставить в нее данные. Если присутствует ON CONFLICT DO UPDATE
, также требуется привилегия UPDATE
на таблицу.
Если указан список столбцов, вам нужно только иметь привилегию INSERT
на перечисленные столбцы.
Аналогично, когда указано ON CONFLICT DO UPDATE
, вам нужно только иметь привилегию UPDATE
на столбец (-ы), которые перечислены для обновления. Однако ON CONFLICT DO UPDATE
также требует привилегию SELECT
на любой столбец, значения которого считываются в выражениях ON CONFLICT DO UPDATE
или condition
.
Использование предложения RETURNING
требует наличия привилегии SELECT
на все столбцы, упомянутые в RETURNING
.
Если вы используете предложение query
для вставки строк из запроса, вам, конечно же, необходимо иметь привилегию SELECT
на любую таблицу или столбец, используемые в запросе.
Параметры
Вставка
Содержание этого раздела охватывает параметры, которые могут использоваться только при вставке новых строк. Параметры, исключительно используемые с оператором ON CONFLICT
, описаны отдельно.
with_query
С помощью
WITH
вы можете указать одно или несколько подзапросов, на которые можно ссылаться по имени в запросеINSERT
. См. Раздел 7.8 и SELECT для получения подробной информации.Возможно, что
запрос
(операторSELECT
) также может содержать предложениеWITH
. В таком случае оба набораwith_query
могут быть использованы внутризапроса
, но второй набор имеет приоритет, так как он более тесно вложен.table_name
Имя (опционально с указанием схемы) существующей таблицы.
alias
Заменяющее имя для
table_name
. Когда указывается псевдоним, он полностью скрывает фактическое имя таблицы. Это особенно полезно, когдаON CONFLICT DO UPDATE
нацелен на таблицу с именемexcluded
, поскольку в противном случае это имя будет воспринято как имя специальной таблицы, представляющей строку, предлагаемую для вставки для вставки.column_name
Имя столбца в таблице, указанной параметром
table_name
. Имя столбца может быть уточнено с помощью подполя или индекса массива, если это необходимо. (Вставка только в некоторые поля составного столбца оставляет другие поля пустыми). При ссылке на столбец с использованием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
является нормальным поведением и его указание ничего не меняет, но Tantor SE-1C позволяет его использовать как расширение).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
гарантирует атомарный результат INSERT
или UPDATE
; при отсутствии независимых ошибок, один из этих двух результатов гарантирован, даже при высокой параллельности. Это также известно как UPSERT — “UPDATE или INSERT”.
conflict_target
Определяет, какие конфликты
ON CONFLICT
принимают альтернативное действие, выбирая индексы арбитра. Может выполнять вывод уникального индекса или явно указывать ограничение. ДляON CONFLICT DO NOTHING
необязательно указыватьconflict_target
; если он не указан, обрабатываются конфликты со всеми используемыми ограничениями (и уникальными индексами). ДляON CONFLICT DO UPDATE
conflict_target
должен быть указан.conflict_action
conflict_action
определяет альтернативное действиеON CONFLICT
. Оно может быть либоDO NOTHING
, либоDO UPDATE
с указанием подробностей действияUPDATE
в случае конфликта. ПредложенияSET
иWHERE
вON CONFLICT DO UPDATE
имеют доступ к существующей строке, используя имя таблицы (или псевдоним), а также к строке, предлагаемой для вставки, с помощью специальной таблицыexcluded
. Для чтения столбцовexcluded
требуется привилегияSELECT
на любом столбце в целевой таблице.Обратите внимание, что эффекты всех триггеров
BEFORE INSERT
на каждую строку отражаются в значенияхexcluded
, поскольку эти эффекты могли привести к исключению строки из вставки.index_column_name
Имя столбца
table_name
. Используется для вывода арбитражных индексов. Следует форматуCREATE INDEX
. Требуется привилегияSELECT
на столбецindex_column_name
.index_expression
Аналогично
index_column_name
, но используется для вывода выражений на столбцыtable_name
, которые появляются в определениях индексов (а не простых столбцах). Следует форматуCREATE INDEX
. Требуется привилегияSELECT
на любом столбце, появляющемся вindex_expression
.collation
Когда указано, требует, чтобы соответствующий
index_column_name
илиindex_expression
использовал определенное правило сортировки для сопоставления во время вывода. Обычно это опускается, так как правила сортировки обычно не влияют на возникновение нарушения ограничения. Следует форматуCREATE INDEX
.opclass
Когда указано, требует, чтобы соответствующий
index_column_name
илиindex_expression
использовал определенный класс операторов для сопоставления во время вывода. Обычно это опускается, так как семантика equality часто эквивалентна для классов операторов типа, или потому что достаточно доверять тому, что определенные уникальные индексы имеют соответствующее определение равенства. Следует форматуCREATE INDEX
.index_predicate
Используется для разрешения вывода частичных уникальных индексов. Можно вывести любые индексы, удовлетворяющие предикату (которые фактически не обязательно являются частичными индексами). Следует формату
CREATE INDEX
. Требуется привилегияSELECT
на любой столбец, появляющийся внутриindex_predicate
.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
возвращается тег команды в следующем формате:
INSERToid
count
count
- это количество вставленных или обновленных строк. oid
всегда равен 0 (раньше это был OID, присвоенный вставленной строке, если count
был ровно один, и целевая таблица была объявлена WITH OIDS
, и 0 в противном случае, но создание таблицы WITH OIDS
больше не поддерживается).
Если команда INSERT
содержит предложение RETURNING
,
результат будет аналогичен результату SELECT
,
содержащему столбцы и значения, определенные в списке
RETURNING
, вычисленные для вставленной или
обновленной строки(строк), выполненной командой.
Примечания
Если указанная таблица является секционированной таблицей, каждая строка будет направлена в соответствующую секцию и вставлена в него. Если указанная таблица является секцией, произойдет ошибка, если одна из входных строк нарушает ограничение секции.
Также можно рассмотреть использование 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
- это расширение Tantor SE-1C,
а также возможность использовать WITH
с INSERT
и возможность
указать альтернативное действие с помощью ON CONFLICT
.
Кроме того, стандарт запрещает опускать список имен столбцов, если не все столбцы
заполняются из VALUES
или query
.
Если вы предпочитаете использовать более соответствующее стандарту SQL-операторы, вместо ON CONFLICT
,
см. MERGE.
Согласно стандарту SQL, OVERRIDING SYSTEM VALUE
может быть указан только в том случае, если существует столбец идентификатора, который всегда генерируется. В PostgreSQL это предложение разрешено в любом случае и игнорируется, если оно не применимо.
Возможные ограничения внутри предложения query
документированы в разделе SELECT.