web-dev-qa-db-fra.com

Combinaison INSERT INTO et WITH / CTE

J'ai un CTE très complexe et j'aimerais insérer le résultat dans une table physique.

Le texte suivant est-il valide?

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

Je pense utiliser une fonction pour créer ce CTE qui me permettra de le réutiliser. Des pensées?

147
dcpartners

Vous devez d'abord placer le CTE, puis combiner l'INSERT INTO avec votre instruction select. En outre, le mot clé "AS" situé après le nom du CTE n'est pas facultatif:

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

Veuillez noter que le code suppose que le CTE renvoie exactement quatre champs et que ces champs correspondent dans l'ordre et le type à ceux spécifiés dans l'instruction INSERT. Si ce n'est pas le cas, remplacez simplement "SELECT *" par une sélection spécifique des champs dont vous avez besoin.

En ce qui concerne votre question sur l'utilisation d'une fonction, je dirais "ça dépend". Si vous placez les données dans une table uniquement pour des raisons de performances et que la vitesse est acceptable lorsque vous les utilisez via une fonction, alors je considérerais que la fonction est une option. D'un autre côté, si vous devez utiliser le résultat du CTE dans plusieurs requêtes différentes et que la vitesse est déjà un problème, optez pour une table (régulière ou temporaire).

WITH common_table_expression (Transact-SQL)

249
Valentino Vranken

Oui:

WITH tab (
  bla bla
)

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

SELECT * FROM tab

Notez qu'il s'agit de SQL Server, qui prend en charge plusieurs CTE:

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

Teradata n'autorise qu'un seul CTE et la syntaxe est donnée à titre d'exemple.

16
Cade Roux

La clause WITH pour les expressions de table communes va en haut.

Envelopper chaque insertion dans un CTE présente l'avantage de séparer visuellement la logique de requête du mappage de colonne.

Trouvez l'erreur:

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_

Même erreur:

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

Quelques lignes de passe-partout rendent extrêmement facile la vérification du code insère le bon nombre de colonnes dans le bon ordre, même avec un très grand nombre de colonnes. Votre futur moi vous remerciera plus tard.

16
Anon