ROWID是Oracle中标识行物理地址的伪列,非函数,不可加括号调用;其值唯一但不长期稳定,仅适用于即查即用场景,如精准定位、删除重复数据等。

ROWID 就是 Oracle 中行的物理地址,直接查 ROWID 伪列就能拿到,不需要“函数”——它本身不是函数,是每个表行自带的隐式伪列。
为什么不能用 ROWID() 这类函数?
Oracle 没有 ROWID() 函数。常见误解是把它当成类似 SYS_GUID() 的函数调用,但实际用法是:SELECT ROWID, ... FROM 表名。强行写成 ROWID() 会报错 ORA-00923: FROM keyword not found where expected。
-
ROWID是伪列,不是函数,不能加括号 - 它只在
SELECT、WHERE、ORDER BY中合法出现,不能出现在INSERT ... VALUES或存储过程赋值语句右侧直接调用(除非用SELECT ROWID INTO ...) - 试图在 PL/SQL 中写
v_rid := ROWID();会编译失败
怎么安全地查出并验证 ROWID 值?
直接查带 ROWID 的结果集即可,但要注意:ROWID 不保证长期稳定 —— 行迁移、表重组、分区交换等操作都可能改变它。所以只适合“即查即用”场景。
- 基础查询:
SELECT ROWID, empno, ename FROM emp WHERE deptno = 10 - 验证格式是否合法(扩展 ROWID 是 18 字符 base64 编码):
SELECT LENGTH(ROWID), DUMP(ROWID) FROM emp WHERE ROWNUM = 1 - 拆解物理含义(需 DBA 权限或对象权限):
SELECT dbms_rowid.rowid_object(ROWID) obj#, dbms_rowid.rowid_relative_fno(ROWID) file#, dbms_rowid.rowid_block_number(ROWID) block# FROM emp WHERE ROWNUM = 1
WHERE 条件里用 ROWID 要防什么坑?
用 WHERE ROWID = 'AAAR6EAAHAAAACbAAA' 看似快,但极易因字符串拼接、大小写、空格、换行导致匹配失败 —— ROWID 区分大小写且严格校验长度。
- 从查询中复制 ROWID 时,确保没带前后空格或不可见字符;可用
TRIM()包裹再比较 - 不要手动构造 ROWID 字符串,Oracle 不提供公开的编码规则 API,
DBMS_ROWID.ROWID_CREATE是内部包,非文档化,不建议生产使用 - 批量操作慎用硬编码 ROWID:如果先查出一批 ROWID 存到临时表,再执行 DELETE,中间若发生行迁移,第二次执行时部分 ROWID 可能已失效,报
ORA-01410: invalid ROWID
ROWID 和 ROWNUM 最容易混淆的点
ROWNUM 是结果集生成时动态分配的序号,ROWID 是数据块里的物理坐标 —— 它们生命周期、作用域、稳定性完全不同。
-
ROWNUM = 1可能每次执行返回不同行(无ORDER BY时),而ROWID = 'xxx'永远指向同一行(只要该行未被移动或删除) - 分页必须用
ROWNUM(配合子查询),精准定位单行更新/删除必须用ROWID - 用
FOR UPDATE锁定后,WHERE CURRENT OF依赖的是游标绑定的内部 ROWID,不是你 SELECT 出来的那个字符串值
真正关键的不是“怎么拿到 ROWID”,而是清楚它只适合短生命周期的精确寻址 —— 一旦离开当前事务上下文或跨过 DDL 操作,就别再假设它还有效。


















