Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 使用相同CTE的两次更新_Sql Server - Fatal编程技术网

Sql server 使用相同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

我必须“取消移动”树状图中的文件夹(如果这些文件夹已被标记为已删除,我将更改该标记的值)。每个文件夹可以包含文件或文件夹(存储在不同的表中)。我有一个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 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作为谓词中的
的一部分,无论如何都会被假脱机到临时表(或哈希表)中。