暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oracle数据库中rowid的解释

原创 陈耀斌 2025-08-12
139

在Oracle数据库中,ROWID是一个伪列(pseudocolumn),它代表了表中每一行的物理地址。ROWID包含了数据对象号、数据文件号、数据块号以及行号等信息,因此它是唯一且不变的(除非发生行迁移等特殊情况)。

1. 语法问题:* 的特殊性

SELECT * 表示选择表中所有用户定义的列(不包括伪列如 ROWID、ROWNUM 等)。

当直接组合 ROWID, * 时,Oracle 无法解析这种写法,因为它违反了语法规则:

sql

-- 错误写法(直接报错 ORA-00936)SELECT ROWID, * FROM employees;

2. 解决方案:使用表别名限定

通过表别名明确指定作用域即可解决:

sql

-- 正确写法:用别名限定SELECT t.ROWID, t.* FROM employees t;

为什么有效?

t.* 明确表示选择表 t 的所有列(不包括伪列)。

t.ROWID 明确指向表 t 的伪列。

此时两者作用域清晰,无歧义。

3. 根本原因分析

* 的解析规则
Oracle 要求 * 必须被限定(如 表名.* 或 别名.*)。直接使用 * 只能单独出现(如 SELECT *),不能与其他列混用。

伪列的特殊性
ROWID 是伪列(Pseudocolumn),不属于用户定义的列。它与 * 代表的列集合存在逻辑冲突。

4. 其他替代写法

显式列出所有列(不推荐):

· SELECT ROWID, employee_id, first_name, ... FROM employees;

·子查询(可行但冗余):

SELECT ROWID, t.* FROM (SELECT * FROM employees) t;

总结

场景

写法

结果

直接组合 ROWID, *

SELECT ROWID, * FROM 表名;

报错 ORA-00936

用别名限定作用域

SELECT 别名.ROWID, 别名.* FROM 表名 别名;

成功执行

关键点:始终用表别名限定 ROWID 和 *(如 t.ROWID, t.*),即可避免语法错误。这是Oracle的明确语法要求。

总结原因:1. 当使用`*`时,它表示选择表中的所有列,包括伪列ROWID(实际上`*`并不包括伪列,但这里的问题不是重复)。实际上,问题在于当使用`*`时,如果同时单独选择ROWID,在没有表别名的情况下,Oracle无法正确解析。2. Oracle要求当使用表别名时,所有列(包括伪列)都应该用别名限定。因此,为了避免错误,当需要同时选择ROWID和所有列时,应该使用表别名,并且用别名限定ROWID和`*`。注意:在Oracle中,`*`并不包括伪列(如ROWID, ROWNUM等),所以理论上选择ROWID和`*`并不会造成重复列。但是,由于语法解析的原因,直接同时使用ROWID和`*`而不加别名限定是不允许的。所以,根本原因在于Oracle的语法解析要求,当使用`*`时,如果还有其他列,那么整个选择列表需要明确。而使用表别名可以明确每个列的来源,从而避免歧义。

最后修改时间:2025-08-12 17:14:29
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论