15.2.7.1 Оператор INSERT ... SELECT
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{ SELECT ...
| TABLE table_name
| VALUES row_constructor_list
}
[ON DUPLICATE KEY UPDATE assignment_list]
value:
{expr | DEFAULT}
value_list:
value [, value] ...
row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]
assignment:
col_name =
value
| [row_alias.]col_name
| [tbl_name.]col_name
| [row_alias.]col_alias
assignment_list:
assignment [, assignment] ...
С помощью INSERT ...
SELECT можно быстро вставить множество строк в таблицу из результата оператора SELECT, который может выбирать данные из одной или нескольких таблиц. Например:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
Оператор TABLE можно использовать вместо оператора SELECT, как показано здесь:
INSERT INTO ta TABLE tb;
TABLE tb эквивалентно SELECT *
FROM tb. Это может быть полезно, когда необходимо вставить все столбцы из исходной таблицы в целевую таблицу, и не требуется фильтрация с помощью WHERE. Кроме того, строки из TABLE можно упорядочить по одному или нескольким столбцам, используя ORDER BY, и ограничить число вставляемых строк с помощью предложения LIMIT. Дополнительную информацию см. в разделе 15.2.16, «Оператор TABLE».
Для операторов INSERT ...
SELECT, и, за исключением случаев, указанных отдельно, также для INSERT ... TABLE выполняются следующие условия:
Укажите
IGNORE, чтобы игнорировать строки, которые могут вызвать нарушения уникальности ключей.-
Целевая таблица оператора
INSERTможет появляться в предложенииFROMчасти оператораSELECTзапроса или в качестве таблицы, указанной операторомTABLE. Однако нельзя вставлять данные в таблицу и выбирать данные из той же таблицы в подзапросе.При выборе данных из таблицы и вставке данных в ту же таблицу MySQL создаёт временную внутреннюю таблицу для хранения строк из оператора
SELECT, а затем вставляет эти строки в целевую таблицу. Однако нельзя использоватьINSERT INTO t ... SELECT ... FROM t, когдаtявляется таблицейTEMPORARY, так как к таблицамTEMPORARYнельзя обратиться дважды в одном операторе. По той же причине нельзя использоватьINSERT INTO t ... TABLE t, когдаtявляется временной таблицей. См. раздел 10.4.4, «Использование внутренних временных таблиц в MySQL», и раздел B.3.6.2, «Проблемы с временными таблицами». Столбцы
AUTO_INCREMENTработают как обычно.Для обеспечения возможности использования двоичного журнала для повторного создания исходных таблиц MySQL не допускает одновременных вставок для операторов
INSERT ... SELECTилиINSERT ... TABLE(см. раздел 10.11.3, «Одновременные вставки»).-
Чтобы избежать проблем с неоднозначными ссылками на столбцы, когда оператор
SELECTи операторINSERTссылаются на одну и ту же таблицу, предоставьте уникальный псевдоним для каждой используемой таблицы в части оператораSELECTи квалифицируйте имена столбцов в этой части с помощью соответствующего псевдонима.Оператор
TABLEне поддерживает псевдонимы.
Вы можете явно выбрать, какие разделы или подразделы (или оба) исходной или целевой таблицы (или обеих) использовать с помощью предложения PARTITION после имени таблицы. Когда PARTITION используется с именем исходной таблицы в части оператора SELECT оператора, строки выбираются только из разделов или подразделов, указанных в списке разделов. Когда PARTITION используется с именем целевой таблицы для части оператора INSERT оператора, необходимо убедиться, что все выбранные строки можно вставить в указанные в списке разделов разделы или подразделы. В противном случае оператор INSERT ...
SELECT завершается ошибкой. Дополнительную информацию и примеры см. в разделе 26.5, «Выбор разделов».
Оператор TABLE не поддерживает предложение PARTITION.
Для операторов INSERT
... SELECT, см. раздел 15.2.7.2, «Оператор INSERT ... ON DUPLICATE KEY UPDATE» для условий, при которых столбцы оператора SELECT могут быть использованы в предложении ON DUPLICATE KEY UPDATE. Это также работает для INSERT ... TABLE.
Порядок, в котором оператор SELECT или оператор TABLE без предложения ORDER BY возвращает строки, является не детерминированным. Это означает, что при использовании репликации нет гарантии, что такой оператор SELECT возвращает строки в том же порядке на источнике и реплике, что может привести к несоответствиям между ними. Чтобы предотвратить это, всегда пишите операторы INSERT ... SELECT или INSERT ... TABLE, которые должны быть реплицированы, используя предложение ORDER BY, которое гарантирует одинаковый порядок строк на источнике и реплике. См. также раздел 19.5.1.19, «Репликация и LIMIT».
Из-за этой проблемы операторы INSERT ...
SELECT ON DUPLICATE KEY UPDATE и INSERT IGNORE ...
SELECT помечены как небезопасные для репликации на основе операторов. Такие операторы генерируют предупреждение в журнале ошибок при использовании режима на основе операторов и записываются в двоичный журнал с использованием формата на основе строк при использовании режима MIXED. (Ошибка #11758262, ошибка #50439)
См. также раздел 19.2.1.1, «Преимущества и недостатки репликации на основе операторов и на основе строк».
© 2025 Oracle
Licensed under the GPLv2 License.