2010-07-22 19 views
119

Tengo un CTE muy complejo y me gustaría insertar el resultado en una tabla física.Combinación de INSERT INTO y WITH/CTE

¿Es el siguiente válido?

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

Estoy pensando en usar una función para crear este CTE que me permita reutilizarlo. ¿Alguna idea?

Respuesta

203

Primero debe poner el CTE y luego combinar el INSERT INTO con su instrucción de selección. Además, el "AS" palabra clave siguiente nombre de la CTE no es opcional:

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

Tenga en cuenta que el código se supone que el CTE volverá exactamente cuatro campos y que esos campos son coincidentes en orden y tipo con las especificadas en la instrucción INSERT. Si ese no es el caso, simplemente reemplace "SELECT *" con una selección específica de los campos que necesita.

En cuanto a su pregunta sobre el uso de una función, yo diría que "depende". Si está colocando los datos en una tabla solo por razones de rendimiento, y la velocidad es aceptable cuando la usa a través de una función, entonces consideraría la función como una opción. Por otro lado, si necesita usar el resultado del CTE en varias consultas diferentes, y la velocidad ya es un problema, elegiría una tabla (regular o temporal).

WITH common_table_expression (Transact-SQL)

14

Sí:

WITH tab (
    bla bla 
) 

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

SELECT * FROM tab 

Tenga en cuenta que esto es para SQL Server, que soporta múltiples CTE:

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

Teradata permite sólo una CTE y la sintaxis es como su ejemplo.

12

La cláusula WITH para expresiones de tabla comunes ir en la parte superior.

Envolver cada inserción en un CTE tiene la ventaja de segmentar visualmente la lógica de consulta del mapeo de columnas.

punto el error:

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_ 

mismo error:

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

unas pocas líneas de texto modelo hacen que sea extremadamente fácil de verificar el código inserta el número correcto de columnas de la orden correcto, incluso con un gran número de columnas. Tu yo futuro te lo agradecerá más tarde.

+2

Esto es genial! De repente, no odio las declaraciones INSERT tanto ... – NReilingh

Cuestiones relacionadas