Сочетание INSERT INTO и WITH / CTE - PullRequest
143 голосов
/ 22 июля 2010

У меня очень сложный CTE, и я хотел бы вставить результат в физическую таблицу.

Действительно ли следующее?

INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos 
(
    BatchID,
    AccountNo,
    APartyNo,
    SourceRowID
)       
WITH tab (
  -- some query
)    
SELECT * FROM tab

Я думаю об использовании функции для создания этого CTE, который позволит мне использовать повторно. Есть мысли?

Ответы [ 3 ]

245 голосов
/ 22 июля 2010

Сначала нужно поставить CTE, а затем объединить INSERT INTO с оператором select.Кроме того, ключевое слово «AS» после имени CTE не является обязательным:

WITH tab AS (
    bla bla
)
INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos (
BatchID,
AccountNo,
APartyNo,
SourceRowID
)  
SELECT * FROM tab

Обратите внимание, что в коде предполагается, что CTE вернет ровно четыре поля и что эти поля совпадают по порядку и типу с этими.указано в операторе INSERT.Если это не так, просто замените «SELECT *» определенным выбором полей, которые вам требуются.

Что касается вашего вопроса об использовании функции, я бы сказал: «это зависит».Если вы помещаете данные в таблицу только из-за соображений производительности, и скорость является приемлемой при использовании их через функцию, тогда я считаю, что функция является опцией.С другой стороны, если вам нужно использовать результат CTE в нескольких разных запросах, а скорость уже является проблемой, я бы выбрал таблицу (обычную или временную).

WITH common_table_expression (Transact-SQL)

16 голосов
/ 08 мая 2015

Предложение WITH для общих табличных выражений идет вверху.

Обертывание каждой вставки в CTE позволяет визуально отделить логику запроса от сопоставления столбцов.

Найдите ошибку:

WITH _INSERT_ AS (
  SELECT
    [BatchID]      = blah
   ,[APartyNo]     = blahblah
   ,[SourceRowID]  = blahblahblah
  FROM Table1 AS t1
)
INSERT Table2
      ([BatchID], [SourceRowID], [APartyNo])
SELECT [BatchID], [APartyNo], [SourceRowID]   
FROM _INSERT_

Та же ошибка:

INSERT Table2 (
  [BatchID]
 ,[SourceRowID]
 ,[APartyNo]
)
SELECT
  [BatchID]      = blah
 ,[APartyNo]     = blahblah
 ,[SourceRowID]  = blahblahblah
FROM Table1 AS t1

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

16 голосов
/ 22 июля 2010

Yep:

WITH tab (
  bla bla
)

INSERT INTO dbo.prf_BatchItemAdditionalAPartyNos (  BatchID,                                                        AccountNo,
APartyNo,
SourceRowID)    

SELECT * FROM tab

Обратите внимание, что это для SQL Server, который поддерживает несколько CTE:

WITH x AS (), y AS () INSERT INTO z (a, b, c) SELECT a, b, c FROM y

Teradata допускает только один CTE, и синтаксис приведен в качестве примера.

...