185

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

以下は有効ですか?

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

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

4

4 に答える 4

320

最初に CTE を配置してから、INSERT INTO を select ステートメントと組み合わせる必要があります。また、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)

于 2010-07-22T05:54:27.420 に答える
31

Common Table Expressionsの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

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

于 2015-05-08T20:49:11.777 に答える
18

はい:

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 のみを許可し、構文は例のとおりです。

于 2010-07-22T05:52:27.923 に答える