使用 for 循环删除前 10 行

问题描述

我在一次采访中被问到“如何使用 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;  
/