INSERT INTOとWITH / CTEの組み合わせ


157

非常に複雑なCTEがあり、結果を物理テーブルに挿入したいと思います。

以下は有効ですか?

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

関数を使用して、このCTEを作成し、再利用できるようにすることを考えています。何かご意見は?

回答:


270

最初にCTEを配置してから、INSERT INTOを選択ステートメントと組み合わせる必要があります。また、CTEの名前に続く「AS」キーワードはオプションではありません。

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

このコードは、CTEが正確に4つのフィールドを返すこと、およびこれらのフィールドがINSERTステートメントで指定されたフィールドと順序とタイプが一致していることを前提としていることに注意してください。そうでない場合は、「SELECT *」を必要なフィールドの特定の選択に置き換えてください。

関数の使用についてのあなたの質問については、私は「それは依存する」と言います。パフォーマンス上の理由でデータをテーブルに配置し、関数を介してそれを使用するときに速度が許容できる場合は、関数をオプションと見なします。一方、CTEの結果をいくつかの異なるクエリで使用する必要があり、速度が既に問題となっている場合は、表(通常または一時)を使用します。

WITH common_table_expression(Transact-SQL)


19

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

数行のボイラープレートにより、非常に多数の列がある場合でも、コードが正しい数の列を正しい順序で挿入していることを確認するのが非常に簡単になります。あなたの将来の自己は後であなたに感謝します。


3
これは素晴らしい!突然、私はINSERTステートメントをそれほど嫌いになりません...
NReilingh 2016年

1
これは非常に便利です。最初の読み取りでそれを逃した他の人にとって、これが解決する問題は、挿入ステートメントで、マッピングが挿入されるフィールドの相対的な順序とそれらに挿入される値によって定義されることです。これらを普通に書くと、2つの順序が同じであることを目視検査で確認するのは非常に困難です。CTEを使用すると、値が挿入される列名で値に名前を付けることができます。これは、これらを2行に非常に適切に配置できることを意味します。
ティドリス

16

うん:

WITH tab (
  bla bla
)

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

SELECT * FROM tab

これは、複数のCTEをサポートするSQL Server用であることに注意してください。

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

Teradataは1つのCTEのみを許可し、構文は例です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.