我的存儲過程是這樣的:爲什麼我使用一次後無法訪問我的CTE?
WITH MYCTE(....)
AS
(
...
)
UPDATE ... (using my CTE)
DELETE (using my CTE) <--- says the object, my CTE, doesn't exist
我只能用一次?
我的存儲過程是這樣的:爲什麼我使用一次後無法訪問我的CTE?
WITH MYCTE(....)
AS
(
...
)
UPDATE ... (using my CTE)
DELETE (using my CTE) <--- says the object, my CTE, doesn't exist
我只能用一次?
在您的示例代碼中,CTE僅保留UPDATE。如果您需要更長的時間,請考慮使用它填充#tempTable或@tableVariable,然後從中更新和刪除。
您也可以增加您的UPDATE以使用OUTPUT子句,如下所示,以便您可以捕獲受影響的行。而在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
OUTPUT:
(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)
很棒的回答。我一直在使用SQL Server多年,並不知道你可以做OUTPUT。這在將來肯定會派上用場。 – WesleyJohnson 2009-10-20 01:04:34
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
條款不產生永久的對象之後多個查詢使用方法:它只是修改要添加該條款的一個查詢!如果您需要非常不同的功能,請考慮使用視圖...
...或臨時表(#或@)。 – 2009-10-19 20:52:35
CTE不創造任何 '真正的'。它們僅僅是一個語言元素,這是一種表達式,可以在語句中重複使用這種表格。當你說
WITH cteFoo AS (select ... from table where ...)
select ... from cteFoo where ...
是說
select ... from (select ... from table where ....) as cteFoo where ...
CTE的只是另一種方式和派生表非常相似,使用派生表的任何查詢可以rewriten的CTE,任何非遞歸CTE可以被重寫爲使用派生表的查詢。就我個人而言,我認爲CTE表格更簡潔易讀。
的CTE允許表表達式多次使用爲宣告一次:
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顯然更具有可讀性。但是你必須明白這兩種形式正在產生相同的查詢。 CTE表單可能會建議創建中間結果,然後在中間結果上運行連接,但這不是事實。 CTE表格被編譯成與派生表格完全相同的形式,這明確了CTE的表格表達式運行兩次。
這是我們爲什麼應該在我們的T-SQL中使用分號的一個很好的例子。在UPDATE和DELETE語句之後正確放置';'表明CTE是UPDATE語句的_part。 – NReilingh 2017-01-08 20:40:52