私のストアドプロシージャは次のようになります。
WITH MYCTE(....)
AS
(
...
)
UPDATE ... (using my CTE)
DELETE ( using my CTE) <--- says the object, my CTE, doesn't exist
1回しか使えないの?
私のストアドプロシージャは次のようになります。
WITH MYCTE(....)
AS
(
...
)
UPDATE ... (using my CTE)
DELETE ( using my CTE) <--- says the object, my CTE, doesn't exist
1回しか使えないの?
コード例では、CTE は UPDATE に対してのみ保持されます。より長く持続させる必要がある場合は、#tempTable または @tableVariable に値を設定し、それらから UPDATE および DELETE を行うことを検討してください。
次のようにOUTPUT句を使用するように UPDATE を拡張して、影響を受ける行を取得することもできます。そして、次のように DELETE で使用します。
set nocount on
DECLARE @Table table (PK int, col1 varchar(5))
DECLARE @SavedPks table (PK int)
INSERT INTO @Table VALUES (1,'g')
INSERT INTO @Table VALUES (2,'g')
INSERT INTO @Table VALUES (3,'g')
INSERT INTO @Table VALUES (4,'g')
INSERT INTO @Table VALUES (5,'x')
INSERT INTO @Table VALUES (6,'x')
set nocount off
;WITH MYCTE
AS
(
SELECT PK, col1 FROM @Table
)
UPDATE MYCTE
SET col1='xyz'
OUTPUT INSERTED.PK
INTO @SavedPks
WHERE col1='g'
SELECT 'A',* FROM @Table
DELETE @Table
WHERE PK IN (SELECT PK from @SavedPks)
SELECT 'B',* FROM @Table
出力:
(4 row(s) affected)
PK col1
---- ----------- -----
A 1 xyz
A 2 xyz
A 3 xyz
A 4 xyz
A 5 x
A 6 x
(6 row(s) affected)
(4 row(s) affected)
PK col1
---- ----------- -----
B 5 x
B 6 x
(2 row(s) affected)
CTEは「本物」を作成しません。これらは単なる言語要素であり、ステートメントで繰り返し使用される可能性のあるテーブル式を表現する方法です。あなたが言う時
WITH cteFoo AS (select ... from table where ...)
select ... from cteFoo where ...
別の言い方です
select ... from (select ... from table where ....) as cteFoo where ...
CTEと派生テーブルは非常に似ており、派生テーブルを使用するクエリはCTEとして書き換えることができ、非再帰CTEは派生テーブルを使用するクエリとして書き換えることができます。個人的には、CTEフォームの方が簡潔で読みやすいので、ずっと好みます。
CTEでは、複数回使用されるテーブル式を1回だけ宣言できます。
WITH cte AS (select ... from table where ...)
select ...
from cte a join cte b on ...
where ...
これを意味的に類似した派生テーブル形式と比較してください。
select ...
from (
select ... from table where ...) as a
join (
select ... from table where ...) as b
on ...
where ...
CTEは明らかにより読みやすくなっています。ただし、2つのフォームが同じクエリを生成していることを理解する必要があります。CTEフォームは、中間結果が作成され、その中間結果に対して結合が実行されることを示唆している場合がありますが、これは正しくありません。CTEフォームは、派生テーブル1とまったく同じフォームにコンパイルされます。これにより、CTEのテーブル式が2回実行されることが明確になります。
CTE 式は、その本体でのみ有効です。他の場所で使用したい場合は、WITH
句も繰り返す必要があります。
WITH MYCTE(....) AS ( ... )
UPDATE ... (using my CTE);
-- a semicolon is necessary for statements followed by a CTE declaration
WITH MYCTE(....) AS ( ... )
DELETE ( using my CTE);
はい、WITH MYCTE
句は後で複数のクエリで使用する永続的なオブジェクトを作成していません。その句を追加している1つのクエリを変更するだけです! 非常に異なる機能が必要な場合は、代わりにビューの使用を検討してください...