Ms sql select into insert: SQL INSERT INTO SELECT Statement

сервер sql — INSERT INTO против SELECT INTO

спросил

Изменено
2 года, 2 месяца назад

Просмотрено
148 тысяч раз

В чем разница между использованием

 SELECT ... INTO MyTable FROM...
 

и

 ВСТАВИТЬ В MyTable (...)
ВЫБЕРИТЕ ИЗ ....
 

?

Из BOL [INSERT, SELECT…INTO] я знаю, что использование SELECT…INTO создаст таблицу вставки в файловой группе по умолчанию , если она еще не существует, и что журнал для этого оператора зависит от модели восстановления базы данных.

  1. Какой оператор предпочтительнее?
  2. Есть ли другие последствия для производительности?
  3. Как лучше всего использовать SELECT…INTO вместо INSERT INTO…?

Изменить: я уже говорил, что знаю, что SELECT INTO. .. создает таблицу, в которой ее не существует. Что я хочу знать, так это то, что SQL включает это утверждение по какой-то причине, что это такое? Делает ли он что-то другое за кулисами для вставки строк, или это просто синтаксический сахар поверх 9?0033 СОЗДАТЬ ТАБЛИЦУ и ВСТАВИТЬ В .

  • sql-сервер
  • tsql
  • sql-сервер-2008

1

  1. Они делают разные вещи. Используйте INSERT , когда таблица существует. Используйте SELECT INTO , если это не так.

  2. Да. INSERT без табличных подсказок обычно регистрируется. SELECT INTO регистрируется минимально при условии, что установлены правильные флаги трассировки.

  3. По моему опыту, SELECT INTO чаще всего используется с промежуточными наборами данных, такими как таблицы #temp , или для копирования всей таблицы, например, для резервного копирования. INSERT INTO используется при вставке в существующую таблицу с известной структурой.

РЕДАКТИРОВАТЬ

Чтобы исправить ваше редактирование, они делают разные вещи. Если вы создаете таблицу и хотите определить структуру, используйте CREATE TABLE и ВСТАВИТЬ . Пример задачи, которую можно создать: у вас есть небольшая таблица с полем varchar. Самая большая строка в вашей таблице теперь составляет 12 байт. Вашему реальному набору данных потребуется до 200 байт. Если вы сделаете SELECT INTO из вашей маленькой таблицы, чтобы создать новую, более поздняя INSERT завершится ошибкой усечения, потому что ваши поля слишком малы.

4

  1. Какой оператор предпочтительнее? Зависит от того, что вы делаете.

  2. Есть ли другие последствия для производительности? Если таблица является постоянной, вы можете создавать индексы во время создания таблицы, что влияет на производительность как отрицательно, так и положительно. Выбрать в не воссоздает индексы, существующие в текущих таблицах, поэтому последующее использование таблицы может быть медленнее, чем должно быть.

  3. Как лучше всего использовать SELECT…INTO вместо INSERT INTO…? Select into используется, если вы не знаете структуру таблицы заранее. Это быстрее написать, чем создать таблицу и оператор вставки, поэтому он используется для ускорения разработки в разы. Часто быстрее использовать, когда вы создаете быструю временную таблицу для проверки вещей или резервную таблицу определенного запроса (возможно, записи, которые вы собираетесь удалить). Редко можно увидеть его использование в производственном коде, который будет выполняться несколько раз (за исключением временных таблиц), потому что это приведет к сбою, если таблица уже существует.

Иногда используется не по назначению людьми, которые не понимают, что делают. И в результате они могут вызвать хаос в БД. Я твердо уверен, что неуместно использовать SELECT INTO для чего-либо, кроме одноразовой таблицы (временная резервная копия, временная таблица, которая исчезнет в конце хранимой процедуры и т. д.). Постоянные таблицы нуждаются в серьезном осмыслении их дизайна, а SELECT INTO позволяет легко избежать размышлений о чем-то даже таком базовом, как о том, какие столбцы и какие типы данных.

В общем, я предпочитаю использовать оператор создания таблицы и вставки — у вас больше элементов управления, и это лучше для повторяющихся процессов. Кроме того, если таблица является постоянной таблицей, она должна быть создана из отдельного сценария создания таблицы (того, который находится в системе управления версиями), поскольку создание постоянных объектов, как правило, в коде не должно быть вставкой/удалением/обновлением или выбором из стол. Изменения объектов должны обрабатываться отдельно от изменений данных, поскольку объекты имеют последствия, выходящие за рамки потребностей конкретной вставки/обновления/выбора/удаления. Вам нужно рассмотреть лучшие типы данных, подумать об ограничениях FK, PK и других ограничениях, рассмотреть требования аудита, подумать об индексации и т. д.

0

У каждого оператора есть отдельный вариант использования. Они не взаимозаменяемы.

SELECT...INTO MyTable... создает новую MyTable там, где ее раньше не было.

INSERT INTO MyTable...SELECT... используется, когда MyTable уже существует.

3

Основное отличие состоит в том, что SELECT INTO MyTable создаст новую таблицу с именем MyTable с результатами, тогда как INSERT INTO требует, чтобы MyTable уже существовала.

Вы должны использовать SELECT INTO только в том случае, если таблицы не существует и вы хотите создать ее на основе результатов вашего запроса. Таким образом, эти два утверждения действительно несопоставимы. Они делают очень разные вещи.

В целом SELECT INTO чаще используется для разовых задач, а INSERT INTO используется регулярно для добавления строк в таблицы.

РЕДАКТИРОВАТЬ:
Хотя вы можете использовать CREATE TABLE и INSERT INTO для выполнения того, что делает SELECT INTO, с SELECT INTO вам не нужно заранее знать определение таблицы. SELECT INTO, вероятно, включен в SQL, потому что он значительно упрощает такие задачи, как создание специальных отчетов или копирование таблиц.

2

На самом деле SELECT … INTO не только создает таблицу, но и завершится ошибкой, если она уже существует, поэтому, по сути, единственный раз, когда вы будете использовать ее, — это когда таблица, в которую вы вставляете, не существует.

Что касается вашего EDIT:

Я лично в основном использую SELECT … INTO , когда создаю временную таблицу. Это для меня основное использование. Однако я также использую его при создании новых таблиц со многими столбцами со структурой, аналогичной другим таблицам, а затем редактирую их, чтобы сэкономить время.

2

Я хочу затронуть только второй пункт вопроса, связанный с производительностью, потому что никто другой этого не осветил. Select Into намного быстрее, чем вставка в, когда речь идет о таблицах с большими наборами данных. Я предпочитаю выбирать в, когда мне нужно прочитать очень большую таблицу. вставка в для таблицы с 10 миллионами строк может занять несколько часов, в то время как выбор в сделает это за минуты, а что касается потери индексов в новой таблице, вы можете воссоздать индексы по запросу и все еще можете сэкономить намного больше времени по сравнению с вставить в.

4

SELECT INTO обычно используется для создания временных таблиц или для копирования другой таблицы (данных и/или структуры).

В повседневном коде вы используете INSERT, потому что ваши таблицы уже должны существовать для чтения, ОБНОВЛЕНИЯ, УДАЛЕНИЯ, СОЕДИНЕНИЯ и т. д. Примечание: ключевое слово INTO необязательно для INSERT

То есть приложения обычно не создают и не удаляют таблицы как часть обычных операций, если только это не временная таблица для некоторого ограниченного объема и специального использования.

Таблица, созданная с помощью SELECT INTO, не будет иметь ключей, индексов или ограничений, в отличие от реальной, сохраненной, уже существующей таблицы. вы во время, а затем вставляете в него записи из исходной таблицы. Вновь созданная таблица имеет ту же структуру, что и исходная таблица. Если вы попытаетесь использовать select into для существующей таблицы, это приведет к ошибке, поскольку будет предпринята попытка создать новую таблицу с тем же именем.
Вставка в требует, чтобы таблица существовала в вашей базе данных до того, как вы вставите в нее строки.

Простая разница между select Into и Insert Into заключается в следующем:
—> Выберите В не нужна существующая таблица. Если вы хотите скопировать данные таблицы A, просто введите Select * INTO [tablename] из A. Здесь имя таблицы может быть существующей таблицей или будет создана новая таблица, имеющая ту же структуру, что и таблица A.

—> Insert In to do нужна существующая таблица. INSERT INTO [tablename] SELECT * FROM A;.
Здесь имя_таблицы — это существующая таблица.

Select Into обычно более популярен для копирования данных, особенно данных резервного копирования.

Вы можете использовать в соответствии с вашими требованиями, это полностью выбор разработчика, который следует использовать в его сценарии.

Эффективность Вставка INTO выполняется быстро.

Ссылки:

https://www.w3schools.com/sql/sql_insert_into_select.asp
https://www.w3schools.com/sql/sql_select_into.asp

Все остальные ответы отличные/правильные (основное различие заключается в том, существует ли уже DestTable ( INSERT ) или еще не существует ( ВЫБЕРИТЕ... В ))

Вы можете предпочесть использовать INSERT (вместо SELECT . .. INTO ), если вы хотите иметь возможность COUNT(*) строк, которые были вставлены до сих пор.

Использование SELECT COUNT(*) ... WITH NOLOCK — это простой/грубый метод, который может помочь вам проверить «прогресс» INSERT ; полезно, если это длительная вставка, как видно из этого ответа).

[Если вы используете…]
INSERT DestTable SELECT ... FROM SrcTable
… тогда ваш запрос SELECT COUNT(*) from DestTable WITH (NOLOCK) будет работать.

Выбор для больших наборов данных может быть полезен только для одного пользователя, использующего одно единственное подключение к базе данных, выполняющего задачу массовой операции. Я не рекомендую использовать

 SELECT * INTO table
 

, так как это создает одну большую транзакцию и создает блокировку схемы для создания объекта, не позволяя другим пользователям создавать объект или получать доступ к системным объектам до тех пор, пока SELECT INTO операция завершена.

В качестве доказательства концепции откройте 2 сеанса, в первом сеансе попробуйте использовать

 выберите во временную таблицу из огромной таблицы
 

и во втором разделе попробуйте

 создать временную таблицу
 

и проверьте блокировки, блокировку и продолжительность второго сеанса, чтобы создать объект временной таблицы. Я рекомендую всегда создавать и вставлять инструкции, а при необходимости для минимального ведения журнала используйте флаг трассировки 610.

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Вставка результатов хранимой процедуры во временную таблицу

В некоторых случаях с SQL Server может возникнуть ситуация, когда вы захотите взять результирующие данные из хранимой процедуры и вставить их во временную таблицу для использования в другом запросе. Определить, как выполнить эту задачу, может быть довольно сложно, поэтому мы кратко опишем пару вариантов, в зависимости от ваших конкретных потребностей и конфигурации базы данных.

Прежде чем мы рассмотрим конкретные методы, давайте создадим пример процедуры. Хотя это и не особенно полезно, давайте создадим процедуру BooksByPrimaryAuthor , которая принимает параметр @PrimaryAuthor и извлекает записи из нашей таблицы books , где этот @PrimaryAuthor соответствует. Оператор генерации процедуры может выглядеть так:

 CREATE PROC BooksByPrimaryAuthor
  @PrimaryAuthornvarchar(100)
КАК
НАЧИНАТЬ
  ВЫБИРАТЬ
    *
  ОТ
    книги
  ГДЕ
    первичный_автор = @PrimaryAuthor;
КОНЕЦ
ИДТИ
 

В идеале мы хотели бы сделать что-то вроде этого, где мы SELECT результирующие данные из нашей процедуры и вставляем их во временную таблицу:

 SELECT
  *
В
  #tmpSortedBooks
ОТ
  EXEC BooksByPrimaryAuthor 'Tolkien'
 

Проблема приведенный выше синтаксис неверен и не будет работать . Нам нужен новый метод.

Одной из возможностей является использование оператора OPENROWSET , который позволяет получить доступ к удаленным данным из источника OLE DB и может быть выполнил непосредственно из другого оператора SQL. OPENROWSET — это метод одноразового подключения и извлечения данных, поэтому его не следует использовать для частых подключений (в этом случае предпочтительнее связывание серверов).

OPENROWSET может быть целью любого оператора INSERT , DELETE или UPDATE , что делает его идеальным для наших целей «выполнения» нашей хранимой процедуры и извлечения этих данных обратно для нашего ожидания. временная таблица.

Перед использованием OPENROWSET может потребоваться изменить некоторые параметры конфигурации, в частности, разрешить специальный доступ. Это можно настроить с помощью следующих инструкций:

 sp_configure «Показать дополнительные параметры», 1
ИДТИ
РЕКОНФИГУРАЦИЯ
ИДТИ
sp_configure «Специальные распределенные запросы», 1
ИДТИ
РЕКОНФИГУРАЦИЯ
ИДТИ
 

Теперь мы можем использовать OPENROWSET , который имеет особый синтаксис, которого необходимо придерживаться:

 OPENROWSET(
  <ИМЯ_ПОСТАВЩИКА>,
  <ИСТОЧНИК_ДАННЫХ>,
  <ОПЦИИ>
)
 

Таким образом, мы можем выполнить нашу хранимую процедуру через OPENROWSET и передать ее в нашу временную таблицу следующим образом:

 SELECT
  *
В
  #tmpSortedBooks
ОТ
  OPENROWSET(
    'SQLNCLI',
    'Сервер=(локальный)\SQL2008;Trusted_Connection=yes;',
    'EXEC BooksByPrimaryAuthor Tolkien'
)
 

Возможно, вам потребуется изменить значения PROVIDER_NAME и DATA_SOURCE для ваших собственных целей.