Spec-Zone.ru › MySQL 5.7

13.2.5.1 Оператор INSERT ... SELECT

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    SELECT ...
    [ON DUPLICATE KEY UPDATE assignment_list]

value:
    {expr | DEFAULT}

assignment:
    col_name = value

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;

Для операторов INSERT ... SELECT выполняются следующие условия:

  • Укажите IGNORE, чтобы игнорировать строки, которые могут вызвать нарушения уникальности ключа.

  • Целевая таблица оператора INSERT может появиться в фрагменте FROM части оператора SELECT запроса. Однако вы не можете вставить данные в таблицу и выбрать данные из той же таблицы в подзапросе.

    При выборе данных из той же таблицы, в которую происходит вставка, MySQL создает внутреннюю временную таблицу для хранения строк из оператора SELECT, а затем вставляет эти строки в целевую таблицу. Однако вы не можете использовать INSERT INTO t ... SELECT ... FROM t, когда t — это таблица TEMPORARY, потому что к таблицам TEMPORARY нельзя обратиться дважды в одном операторе. См. Раздел 8.4.4, «Использование внутренних временных таблиц в MySQL» и Раздел B.3.6.2, «Проблемы с временными таблицами».

  • Столбцы AUTO_INCREMENT работают как обычно.

  • Чтобы гарантировать, что двоичный журнал можно использовать для восстановления исходных таблиц, MySQL не допускает одновременных вставок для операторов INSERT ... SELECT (см. Раздел 8.11.3, «Одновременные вставки»).

  • Чтобы избежать проблем с неоднозначными ссылками на столбцы, когда оператор SELECT и оператор INSERT ссылаются на одну и ту же таблицу, предоставьте уникальный псевдоним для каждой таблицы, используемой в части SELECT, и квалифицируйте имена столбцов в этой части с соответствующим псевдонимом.

Вы можете явно выбрать, какие разделы или подразделы (или оба) исходной или целевой таблицы (или обеих) будут использоваться с фрагментом PARTITION, следующим за именем таблицы. Когда PARTITION используется с именем исходной таблицы в части SELECT оператора, выбираются только строки из разделов или подразделов, указанных в списке разделов. Когда PARTITION используется с именем целевой таблицы для части INSERT оператора, все выбранные строки должны быть вставлены в указанные в списке разделов разделы или подразделы. В противном случае оператор INSERT ... SELECT завершается неудачно. Дополнительную информацию и примеры см. в Разделе 22.5, «Выбор разделов».

Для операторов INSERT ... SELECT см. Раздел 13.2.5.2, «Оператор INSERT ... ON DUPLICATE KEY UPDATE» для условий, при которых столбцы оператора SELECT можно использовать в фрагменте ON DUPLICATE KEY UPDATE.

Порядок, в котором оператор SELECT без фрагмента ORDER BY возвращает строки, не является детерминированным. Это означает, что при использовании репликации нет гарантии, что такой оператор SELECT возвращает строки в том же порядке на источнике и реплике, что может привести к несоответствиям между ними. Чтобы предотвратить это, всегда записывайте операторы INSERT ... SELECT, которые будут реплицироваться, используя фрагмент ORDER BY, который генерирует тот же порядок строк на источнике и реплике. См. также Раздел 16.4.1.17, «Репликация и LIMIT».

Из-за этой проблемы операторы INSERT ... SELECT ON DUPLICATE KEY UPDATE и INSERT IGNORE ... SELECT помечены как небезопасные для репликации на основе операторов. Такие операторы выдают предупреждение в журнале ошибок при использовании режима репликации на основе операторов и записываются в двоичный журнал с помощью формата на основе строк при использовании режима MIXED. (Ошибка #11758262, Ошибка #50439)

См. также Раздел 16.2.1.1, «Преимущества и недостатки репликации на основе операторов и на основе строк».

Оператор INSERT ... SELECT, влияющий на разнесенные таблицы, использующие движок хранения, такой как MyISAM, который использует блокировки на уровне таблицы, блокирует все разделы целевой таблицы; однако, блокируются только те разделы, которые фактически считываются из исходной таблицы. (Это не происходит с таблицами, использующими движки хранения, такие как InnoDB, которые используют блокировки на уровне строк.) Дополнительную информацию см. в Разделе 22.6.4, «Разделение и блокировка».

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/insert-select.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API