【发布时间】:2023-03-03 22:08:01
【问题描述】:
我有一个遍历我的临时表的游标。在迭代时,我想检查一个条件并根据条件删除一些行(我将删除迭代器尚未到达的行)。
我尝试从光标正在迭代的表中删除行(所以临时表),但没有成功,我可以在Messages panel 中看到它们(我打印它的名称)。
是否可以从表中删除游标在 SQL-Server 中迭代的行?如果不是,我的替代方案是什么?
基本上,临时表包含树状数据,根据列的值,如果它不符合条件,我需要删除它的子项(和孙子等)。
DECLARE cursor_name CURSOR
FOR (SELECT * FROM #test) ORDER BY Path
DECLARE
@Id AS INTEGER,
@Name AS VARCHAR(MAX),
@Path AS VARCHAR(MAX)
OPEN cursor_name;
FETCH NEXT FROM cursor_name INTO @Id, @Name, @Path;
PRINT @Name
DELETE FROM #test
WHERE
Path LIKE '%76939%'
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM cursor_name INTO @Id, @Name, @Path;
PRINT @Name
END;
CLOSE cursor_name;
DEALLOCATE cursor_name;
#编辑
这里有更多关于这个问题的细节。我们的数据结构类似于树列表。每个项目都有多个列,这些列指定了该行的某些特征。这些特征可以被继承也可以不被继承(如果InheritanceFlag为1,那么它被继承,如果它是0,那么它不是)。
因此,当用户进行更改时,我们需要将更改传播给其子项,具体取决于所述标志。如果它的一个孩子将InheritanceFlag 设置为0,那么它不会改变它的值,它的孩子也不会。我想使用路径删除那些带有光标的行。
这是我拥有的数据。 ParentID 是其父代的 ID。在这种情况下,假设我们正在编辑项目 76938,因此我们正在查看它的子项。 ToEdit 列是我要创建的;有了它,我可以过滤行并直接将特征列更改为新值。
+-------+----------+-------+-------------------------+-----------------+--------+
| ID | ParentID | Name | Path | InheritanceFlag | ToEdit |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76938 | NULL | 1 | (76938) | 1 | X |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76942 | 76938 | 1.1 | (76938)\(76942) | 1 | 1 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76952 | 76942 | 1.1.1 | (76938)\(76942)\(76952) | 0 | 0 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76961 | 76942 | 1.1.2 | (76938)\(76942)\(76961) | 1 | 1 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76943 | 76938 | 1.2 | (76938)\(76943) | 1 | 1 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76944 | 76938 | 1.3 | (76938)\(76944) | 0 | 0 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76946 | 76944 | 1.3.1 | (76938)\(76944)\(76946) | 1 | 0 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76947 | 76944 | 1.3.2 | (76938)\(76944)\(76947) | 0 | 0 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76948 | 76944 | 1.3.3 | (76938)\(76944)\(76948) | 1 | 0 |
+-------+----------+-------+-------------------------+-----------------+--------+
| 76945 | 76938 | 1.4 | (76938)\(76945) | 1 | 1 |
+-------+----------+-------+-------------------------+-----------------+--------+
【问题讨论】:
-
您可以在
CURSOR中使用DELETE,但是,真正的问题是为什么您首先要使用CURSOR。CURSOR是一个迭代任务,SQL Server(和其他 RDBMS)在此类任务中表现不佳。 RDBMS 旨在完成基于集合的任务。上述的真正目标是什么,为什么不使用基于集合的方法? -
这有点难以解释,但我会试一试。我们的数据结构类似于树列表。有一个特性(多列)可以从父级继承或不继承。我们有一个 INT 标志告诉我们(每一位给出一列的继承设置)。所以我需要传播一个(或多个)特征的更改,并且我正在使用游标,所以当我看到一行没有从其父级继承时,我需要删除它的所有子级(我们有一个路径列,所以一个简单的
WHERE path like ...就足够了。我真的不明白在这种情况下如何不使用光标。 -
我认为你需要一个动态光标。
-
一个 rCTE 可以很好地满足您的需求。样本数据和预期结果将极大地帮助我们为您提供帮助。
-
好吧,等一下,我会建立一些东西
标签: sql-server database-cursor