使用相同CTE的两次更新

时间:2010-12-21 14:24:14

标签: sql-server

我必须在树枝中“取消删除”文件夹(已标记为已移除,我更改了标志的值)。每个文件夹都可以包含文件或文件夹(存储在不同的表中)。我有一个CTE,它定义了所有需要更新的文件夹。

 WITH arbre(id) AS(
     SELECT idDossier
     FROM portail_managers_dossier
     WHERE idDossier = @id
     UNION ALL
     SELECT d.idDossier
     FROM portail_managers_dossier AS d
     INNER JOIN arbre AS a
     ON a.id = d.idParent)

然后我有两个UPDATE请求,每个表一个

 UPDATE portail_managers_dossier
 SET dtDateSuppr = NULL
 WHERE idDossier IN (SELECT id FROM arbre);


 UPDATE portail_managers_document
 SET dtDateSuppr = NULL
 WHERE idDossier IN (SELECT id FROM arbre);

我的问题是:我不知道如何在不同的表上合并两个UPDATE请求。 CTE仅存在于请求结束之前,因此我必须将其定义两次。有没有办法在单个请求中编写上述所有代码?

2 个答案:

答案 0 :(得分:11)

正如您所发现的,CTE将在第一次更新后失去范围。但是,为什么不将CTE中的查询结果写入临时表,而不是使用CTE,并根据内容临时表进行更新?

答案 1 :(得分:0)

您可以在执行更新之前,将 idDossier 列表从cte中保存到变量中。

-- declare table variable
declare @listOfIDs table (idDossier int);

-- select ids of two tables
;WITH arbre(id) AS
(
     SELECT idDossier
     FROM portail_managers_dossier
     WHERE idDossier = @id
     UNION ALL
     SELECT d.idDossier
     FROM portail_managers_dossier AS d
     INNER JOIN arbre AS a
     ON a.id = d.idParent
 )

-- saving ids
insert @listOfIDs(idDossier) select idDossier from arbre

-- execute twice updates
UPDATE portail_managers_dossier
SET dtDateSuppr = NULL
WHERE idDossier IN (SELECT idDossier FROM @listOfIDs);

UPDATE portail_managers_document
SET dtDateSuppr = NULL
WHERE idDossier IN (SELECT idDossier FROM @listOfIDs);