Sql server 使用相同CTE的两次更新
我必须“取消移动”树状图中的文件夹(如果这些文件夹已被标记为已删除,我将更改该标记的值)。每个文件夹可以包含文件或文件夹(存储在不同的表中)。我有一个CTE,它定义了所有需要更新的文件夹Sql server 使用相同CTE的两次更新,sql-server,Sql Server,我必须“取消移动”树状图中的文件夹(如果这些文件夹已被标记为已删除,我将更改该标记的值)。每个文件夹可以包含文件或文件夹(存储在不同的表中)。我有一个CTE,它定义了所有需要更新的文件夹 WITH arbre(id) AS( SELECT idDossier FROM portail_managers_dossier WHERE idDossier = @id UNION ALL SELECT d.idDossier FROM por
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 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);
我的问题是:我不知道如何合并不同表上的两个更新请求。CTE只存在到请求结束,所以我必须定义它两次。有没有办法在一个请求中编写上述所有代码?正如您所发现的,CTE在第一次更新后将失去作用域。但是,与其使用CTE,为什么不将CTE中的查询结果写入临时表,并根据临时表的内容进行更新?在执行更新之前,您可以将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);
这也是我的建议。@Mike M.-我喜欢CTE,但不幸的是,它们不能解决世界上所有的问题:)。我已经读到临时表格会损害性能,应该尽可能避免。但我恐怕我遇到了无法避免的情况@Thibault—“损害绩效”与你试图完成的目标有关。是的,如果您不必将行写入临时表,那就太好了,但您有一项工作要做,而在这种情况下,CTE不会做您想做的事情。@Thibault:在您的情况下,递归CTE作为谓词中的
的一部分,无论如何都会被假脱机到临时表(或哈希表)中。