
在Oracle数据库系统中,ROWNUM和ROWID都被称作伪列,但二者在本质与用途上存在显著差异。ROWID是记录在数据库中的物理地址标识,只要数据未被移动,其值通常保持不变。而ROWNUM则是一个逻辑序号,它是在数据查询结果集返回后才被动态赋予的编号,且总是从1开始顺序递增。需要注意的是,ROWNUM的赋值是基于查询结果逐行进行的,因此其值并非预先固定,而是在查询过程中实时生成的。
关于ROWNUM的使用,常见的一个误区是认为它不支持使用>、>=、=及BETWEEN…AND等操作符。实际上,并非语法不支持,而是其运行机制导致这类条件往往无法返回预期结果。例如,执行如下查询意图获取第10行以后的记录:
SELECT ROWNUM, c1 FROM t1 WHERE ROWNUM > 10;
该语句很可能不返回任何数据。原因在于,ROWNUM是从1开始为结果集的每一行依次赋值。当判断首行是否满足ROWNUM > 10时,其ROWNUM值为1,条件不成立,该行即被排除。随后,下一行在新的结果集中重新被赋值为1,同样无法满足条件,由此导致所有行均被过滤。
那么,如何正确实现诸如“查询第10行之后的数据”这类需求呢?通常需要借助嵌套查询,先为结果集生成具有连续序号的临时列,再基于该列进行筛选:
SELECT * FROM ( SELECT ROWNUM AS rn, t1.* FROM t1 WHERE ... ) WHERE rn > 10;
这种模式在分页查询场景中应用十分广泛。
此外,使用时需注意:ROWNUM不能以任何基表名称作为前缀,例如t1.ROWNUM的写法是错误的。理解ROWNUM的动态赋值机制,是避免常见错误并灵活运用的关键。相比之下,ROWID因其物理特性,在作为条件时则无此类限制,可直接用于精确定位记录。