Oracle 11g中可以通过指定ROWNUM来删除行吗?

Dha*_*ram 0 sql oracle rownum sql-delete

我有一些价值观如下:

MYSTRING
--------
Dharshan
Ramalingam
Devid
Run Code Online (Sandbox Code Playgroud)

我可以通过下面的查询选择特定的行值

select * from ( select mystring , rownum rn  FROM teststring  )
Run Code Online (Sandbox Code Playgroud)

其中 rn = 2;

告诉我删除第二行的方法,给出行号并给我简短的解释。我已经尝试如下,但它不起作用......

delete   from testring where rownum=2;
Run Code Online (Sandbox Code Playgroud)

Lal*_*r B 5

select * from ( select mystring , rownum rn  FROM teststring  ) where  rn = 2;
Run Code Online (Sandbox Code Playgroud)

您的查询随机返回行,没有指定的顺序。堆组织表是行以不特定顺序存储的表。这是一个标准的 Oracle 表

从 Oracle文档来看,

如果没有 order_by_clause,则无法保证多次执行的同一查询将以相同的顺序检索行。

delete from testring where rownum=2;
Run Code Online (Sandbox Code Playgroud)

您的上述查询表明您不了解ROWNUM 的工作原理

您的查询永远不会删除任何行。

ROWNUM值在行通过查询的谓词阶段之后但在查询执行任何排序或聚合之前分配给该行。此外,ROWNUM 值仅在分配后才会递增,这就是以下查询永远不会返回行的原因:

select * 
  from t 
 where ROWNUM = 2;
Run Code Online (Sandbox Code Playgroud)

因为ROWNUM = 2第一行不成立,所以ROWNUM不会前进到 2。因此,任何ROWNUM值都不会大于 1。

如何正确使用ROWNUM:

当您想根据 ROWNUM 选择一行时,您可以执行诸如分页之类的操作:

SQL> SELECT empno
  2  FROM
  3    (SELECT empno, sal, ROWNUM AS rnum FROM
  4      ( SELECT empno, sal FROM emp ORDER BY sal
  5      )
  6    )
  7  WHERE rnum =2;

     EMPNO
----------
      7900
Run Code Online (Sandbox Code Playgroud)

它发生在三个层面:

  • 最里面的子查询首先根据ORDER BY子句对行进行排序。
  • 第二级,子查询分配ROWNUM
  • 最外面的查询根据内部查询给出的 ROWNUM 来过滤行,内部查询不再是伪列,而是子查询结果集。