7

スクリプトの1つでWITH句を使用しているときに発生する質問があります。質問は簡単に指摘できます。外部クエリだけでなく、CTEエイリアスを複数回使用したいのですが、核心があります。

例えば:

-- Define the CTE expression
WITH cte_test (domain1, domain2, [...])
AS
-- CTE query
(
    SELECT domain1, domain2, [...]
    FROM table
)
-- Outer query
SELECT * FROM cte_test
-- Now I wanna use the CTE expression another time
INSERT INTO sometable ([...]) SELECT [...] FROM cte_test

最後の行は外部クエリの外側にあるため、次のエラーが発生します。

メッセージ208、レベル16、状態1、行12無効なオブジェクト名'cte_test'。

CTEを複数回使用する方法はありますか?それを永続的にしますか?私の現在の解決策は、CTEの結果を格納する一時テーブルを作成し、この一時テーブルを以降のステートメントに使用することです。

-- CTE
[...]
-- Create a temp table after the CTE block
DECLARE  @tmp TABLE (domain1 DATATYPE, domain2 DATATYPE, [...])
INSERT INTO @tmp (domain1, domain2, [...]) SELECT domain1, domain2, [...] FROM cte_test
-- Any further DML statements
SELECT * FROM @tmp
INSERT INTO sometable ([...]) SELECT [...] FROM @tmp
[...]

率直に言って、私はこの解決策が好きではありません。他の誰かがこの問題のベストプラクティスを持っていますか?

前もって感謝します!

4

2 に答える 2

18

CommonTableExpressionは、データを永続化しません。これは基本的に、メインクエリ自体の前にサブクエリを作成する方法にすぎません。

これにより、通常のサブクエリよりもインラインビューのようになります。何度も入力しなくても、1つのクエリで繰り返し参照できるためです。

ただし、それでもビューとして扱われ、マクロのように、それを参照するクエリに展開されます。データの永続化はまったくありません。


これは、残念ながら、自分で永続化を行う必要があることを意味します。

  • CTEのロジックを永続化する場合は、インラインビューではなく、ビューだけが必要です。

  • CTEの結果セットを永続化する場合は、必要のないソリューションなど、一時テーブルタイプのソリューションが必要です。

于 2012-06-01T12:07:50.497 に答える
9

CTEは、それが属するSQLステートメントのスコープ内にのみ存在します。後続のステートメントでデータを再利用する必要がある場合は、データを格納するための一時テーブルまたはテーブル変数が必要です。この例では、再帰CTEを実装していない限り、CTEがまったく必要ないことがわかります。 -その内容を一時テーブル/テーブル変数に直接格納し、必要に応じて再利用できます。

また、結果を一時的なテーブル/テーブル変数に配置した場合とは異なり、DELETEステートメントは基になるテーブルから削除しようとすることに注意してください。

于 2012-06-01T12:02:34.453 に答える