问题描述
我在一次采访中被问到“如何使用 for 循环删除前十行”?
我回答说,“这听起来不合逻辑,因为删除前十行不需要使用 for 循环”。我说得对吗?
如果我必须提出问题,答案是什么?
for i in 1..10
loop
delete from table where rownum=1;
end loop
解决方法
for i in 1..10
loop
delete from table where rownum=1;
end loop
代码有误。 是的,在 for 循环中删除行是不合逻辑的,但问题仍然令人困惑。 如果您说要删除查询获取的前十行 无论按什么顺序,你都可以使用这样的东西。
DELETE FROM mytable
WHERE key IN (SELECT key from mytable FETCH FIRST 10 ROWS ONLY);
使用 for 循环没有意义,但你仍然可以做这样的事情。
DECLARE
key dbms_sql.number_table;
BEGIN
SELECT EMPNO BULK COLLECT INTO key FROM emp;
FOR i IN 1..10
LOOP
DELETE FROM EMP WHERE EMPNO = key(i);
END LOOP;
COMMIT;
END;
,
您可以使用 SQL 和 ROWID
伪列直接关联 SELECT
语句,其中 ORDER
发生在 DELETE
语句中,使用指针指向行(而不是必须关联表中的主键):
DELETE FROM table_name
WHERE ROWID IN (
SELECT ROWID
FROM table_name
ORDER BY value
FETCH FIRST 10 ROWS ONLY
)
如果您想使用 FOR
循环,那么您可以在 PL/SQL 中通过使用 BULK COLLECT
来存储 ROWID
值来执行相同的操作:
DECLARE
TYPE rowid_t IS TABLE OF ROWID;
rowids rowid_t;
BEGIN
SELECT ROWID
BULK COLLECT INTO ROWIDS
FROM table_name
ORDER BY value
FETCH FIRST 10 ROWS ONLY;
FOR i IN 1 .. rowids.COUNT LOOP
DELETE FROM table_name
WHERE ROWID = rowids(i);
END LOOP;
END;
/
(注意:您希望循环到集合的大小,而不是天真地循环到最大值 10,因为表中可能没有 10 行要删除。)
dbfiddle here
,使用for循环语句:
create table test_tbl
as select level num
from dual
connect by level<=100
/
begin
for rc in (select rowid rid
from test_tbl
order by num fetch first 10 rows only)
loop
delete from test_tbl where rowid=rc.rid;
end loop;
commit;
end;
/