使用游标时从游标中删除一行
Delete a row from cursor while using the cursor
我有一个游标遍历我的临时 table。在迭代时,我想检查一个条件并根据条件删除一些行(我将删除迭代器尚未到达的行)。
我尝试从游标迭代的 table 中删除行(因此临时 table),但没有成功,我可以在 Messages panel
中看到它们(我打印它姓名)。
是否可以从 table 游标在 SQL-Server 中迭代的行中删除行?如果不是,我有什么选择?
基本上,temp table 包含树状数据,并且根据列的值,如果它不符合条件,我需要删除它的子项(和孙子等) .
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 |
+-------+----------+-------+-------------------------+-----------------+--------+
如果游标是动态的,您可以从底层 table 中删除并从未来的 FETCH 中删除行,并且定义游标的查询不需要假脱机,有效地将其变成静态的光标.
在您的代码中,按未索引的 VARCHAR(MAX) 排序可防止游标看到基础 table.
中的任何更改
EG这个
drop table if exists #test
go
create table #test(id integer, name varchar(max), path varchar(1000), index ix_path (path))
insert into #test(id,name,path) values (1,'a','0000000'),(2,'b', '0769391'),(3,'c', '1768391')
DECLARE cursor_name CURSOR DYNAMIC
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
print 'deleting'
DELETE FROM #test
WHERE
Path LIKE '%76939%'
WHILE 1=1
BEGIN
FETCH NEXT FROM cursor_name INTO @Id, @Name, @Path;
if @@FETCH_STATUS <> 0 break
PRINT @Name
END;
CLOSE cursor_name;
DEALLOCATE cursor_name;
产出
(3 rows affected)
a
deleting
(1 row affected)
c
我有一个游标遍历我的临时 table。在迭代时,我想检查一个条件并根据条件删除一些行(我将删除迭代器尚未到达的行)。
我尝试从游标迭代的 table 中删除行(因此临时 table),但没有成功,我可以在 Messages panel
中看到它们(我打印它姓名)。
是否可以从 table 游标在 SQL-Server 中迭代的行中删除行?如果不是,我有什么选择?
基本上,temp table 包含树状数据,并且根据列的值,如果它不符合条件,我需要删除它的子项(和孙子等) .
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 |
+-------+----------+-------+-------------------------+-----------------+--------+
如果游标是动态的,您可以从底层 table 中删除并从未来的 FETCH 中删除行,并且定义游标的查询不需要假脱机,有效地将其变成静态的光标.
在您的代码中,按未索引的 VARCHAR(MAX) 排序可防止游标看到基础 table.
中的任何更改EG这个
drop table if exists #test
go
create table #test(id integer, name varchar(max), path varchar(1000), index ix_path (path))
insert into #test(id,name,path) values (1,'a','0000000'),(2,'b', '0769391'),(3,'c', '1768391')
DECLARE cursor_name CURSOR DYNAMIC
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
print 'deleting'
DELETE FROM #test
WHERE
Path LIKE '%76939%'
WHILE 1=1
BEGIN
FETCH NEXT FROM cursor_name INTO @Id, @Name, @Path;
if @@FETCH_STATUS <> 0 break
PRINT @Name
END;
CLOSE cursor_name;
DEALLOCATE cursor_name;
产出
(3 rows affected)
a
deleting
(1 row affected)
c