`

关于在使用rowid和rownum时遇到ORA-01446错误的原因即解决方法。

阅读更多
关于在使用rowid和rownum时遇到ORA-01446错误的原因即解决方法。

ORA-01446: cannot select ROWID from view with DISTINCT, GROUP BY, etc.
Cause:     A SELECT statement attempted to select ROWIDs from a view
           containing columns derived from functions or expressions.
           Because the rows selected in the view do not correspond to
           underlying physical records, no ROWIDs can be returned.
Action:    Remove ROWID from the view selection clause, then re-execute the statement.

翻译中文就是:
ORA-01446: 无法从DISTINCT、GROUP BY等子句的视图中选择ROWID。
原因:     一个查询命令试图从一个含有根据函数或者表达式衍生出的列的视图中查询ROWIDS。
           因为从视图中查询出来的行不能和实际的物理记录对应,所以不能返回ROWIDS。
解决方法: 从试图的查询字符中移除ROWID,然后重新执行命令。

我们看下面这个例子:

语句1:select * from (select t.*, rowid from dual t);

语句2:select t.*, rowid, rownum from dual t;

语句3:select * from (select t.*, rowid, rownum from dual t);

语句4:select dummy from (select t.*, rowid, rownum from dual t);

语句5:select * from (select t.*, rowid ri, rownum from dual t);


语句1执行成功。因为查询实际上是走全表扫描。
SQL> select * from (select t.*, rowid from dual t);

D ROWID
- ------------------
X AAAADeAABAAAAyiAAA


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'DUAL'


语句2执行成功。原因同语句1。
SQL> select t.*, rowid, rownum from dual t;

D ROWID                  ROWNUM
- ------------------ ----------
X AAAADeAABAAAAyiAAA          1


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   COUNT
   2    1     TABLE ACCESS (FULL) OF 'DUAL'


语句3执行失败。因为涉及到了伪劣rownum的使用。
rowid和rownum虽然都是伪列,但它们是不同的:rowid 可以说是物理存在的,表示记录在表空间中的唯一位置ID,在DB中唯一。只要记录没被搬动过,rowid是不变的。rowid 相对于表来说又像表中的一般列;而rownum记录的是oracle数据库从数据文件或缓冲区中读取数据的顺序。它取得第一条记录则rownum值为1,第二条为2,依次类推。
语句3要从子查询中查询rownum列,相当于把子查询的结果集当作一个视图,由于还需要从视图中取得rowid,所以会报ORA-01446错误。
SQL> select * from (select t.*, rowid, rownum from dual t);
select * from (select t.*, rowid, rownum from dual t)
       *
ERROR 位于第 1 行:
ORA-01446: cannot select ROWID from view with DISTINCT, GROUP BY, etc.


语句4执行成功。因为最后筛选的记录集中只含有dummy,没有包含rowid。
SQL> select dummy from (select t.*, rowid, rownum from dual t);

D
-
X


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   VIEW
   2    1     COUNT
   3    2       TABLE ACCESS (FULL) OF 'DUAL'


语句5执行成功。因为子查询中把rowid对应的列使用了别名ri,所以对视图的查询就没有包含rowid。
SQL> select * from (select t.*, rowid ri, rownum from dual t);

D RI                     ROWNUM
- ------------------ ----------
X AAAADeAABAAAAyiAAA          1


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   VIEW
   2    1     COUNT
   3    2       TABLE ACCESS (FULL) OF 'DUAL'




如果不明白语句3的可以看看这里。
select * from (select dummy,rowid from dual)
等同于
select dummy,rowid from (select dummy,rowid from dual);
内外的rowid是相同的。

select * from (select dummy,rownum from dual)
等同于
select dummy,rownum from (select dummy,rownum from dual);
内外的rownum不同,子查询会当作视图。

select * from (select dummy,rowid,rownum from dual)
等同于
select dummy,rowid,rownum from (select dummy,rowid,rownum from dual);
由于内外rownum不相同,子查询会当作视图,所以报错。



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/heyixiang/archive/2007/12/29/2003391.aspx
分享到:
评论

相关推荐

    Oracle坏块故障葵花宝典.docx

    然而,在执行索引扫描时遇到了ORA-01578错误,推测索引可能存在坏块。通过查询`dba_extents`表定位到有问题的索引,并重建相关索引后,问题得以解决。 **解决方案** - 登录数据库并检查表`ep_tablet`的数据完整性...

    oracle伪列以与伪表.doc

    - 创建唯一索引时,如果存在重复记录,Oracle会抛出ORA-01452错误。此时,可以通过查找并删除重复记录来解决问题。 - 查找重复记录: - 方法1:通过`GROUP BY`和`HAVING`子句找出出现多次的ID。 - 方法2:利用`MIN...

    oracle的伪列与分页

    Oracle提供了一些内置的伪列供用户使用,如`ROWID`和`ROWNUM`等,这些伪列可以帮助开发人员更方便地进行查询、排序等操作。 #### 二、ROWID与ROWNUM详解 **ROWID:** - **定义**:ROWID是Oracle中用于唯一标识表中...

    PLSQL教程.doc

    PL/SQL允许开发者通过捕获和处理异常来应对运行时可能遇到的问题。基本的异常处理结构如下: ```plsql EXCEPTION WHEN first_exception THEN -- 处理代码 WHEN second_exception THEN -- 处理代码 WHEN OTHERS ...

    oracle经典面试题

    - 当遇到 ORA-01555 错误(快照过旧),通常是因为事务回滚段太小或不足。可以通过增加回滚段大小或者优化查询逻辑来解决该问题。 #### 19. $ORACLE_HOME 与 $ORACLE_BASE 的区别 - `$ORACLE_BASE`:Oracle 的根...

    Oracle经验集锦

    在执行大量数据更新操作时,可能会遇到 `ORA-01555: snapshot too old` 错误。这通常是由于回滚段大小不足造成的。可以设置事务使用的回滚段: ```sql SET TRANSACTION USE ROLLBACK SEGMENT roll_abc; DELETE FROM ...

    DB2兼容模式设置文档

    - **ROWNUM和ROWID验证**:通过查询表来验证`ROWNUM`的正确性。 - **FOR UPDATE验证**:执行带有`FOR UPDATE`的查询语句来验证锁定机制。 - **临时表验证**:创建临时表空间并在其上创建临时表进行验证。 通过...

    Oracle数据库学习指南

    18.基于成本的优化器一般错误概念和问题 19.Delphi 3_0中连接数据库的三种方式 20.远程数据库的访问 21.监控数据库性能的SQL 22.简单实现数据库表空间的备份或迁移 23.简析REDO LOGFILE 24.理解和使用...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    Access 微软 Access是一种桌面数据库,只适合数据量少的应用,在处理少量 数据和单机访问的数据库时是很好的,效率也很高 小型企业 三、 Oracle数据库概述 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以...

    南京12580面试题

    - 伪列如ROWNUM、ROWID、ORA_ROWSCN等,它们不是实际列,但在查询时提供特定信息。 19. **delete与truncate的区别**: - `delete` 删除数据但保留表结构和索引,记录会被标记为已删除,可能占用空间。 - `...

    oracle基础练习

    Oracle数据库是世界上最流行的数据库管理系统之一,它提供了丰富的功能和语法来管理数据。以下是一些关于Oracle基础练习的关键知识点: 1. **查询表结构**: 使用`DESC table_name`命令可以查看表的列名、数据类型和...

    ORACLE性能优化31条

    使用LIMIT或ROWNUM限制返回的记录数,减少网络传输和内存消耗。 26. 适当使用临时表: 在复杂查询中,临时表可以用于存储中间结果,提高性能。 27. 保持数据库和客户端软件的更新: 最新的版本通常包含性能改进...

    oracle基础知识

    Oracle是一种广泛使用的多模型数据库管理系统,在企业级应用中占据重要地位。了解Oracle的基础知识对于数据库管理员(DBA)和开发人员至关重要。 **Oracle体系结构概述** - **逻辑存储结构**:包括表空间(Tablespace...

    30个Oracle语句优化规则详解

    使用LIMIT或ROWNUM限制查询返回的行数,减少网络传输和客户端处理的压力。 14. 避免在WHERE子句中使用函数 函数通常会导致无法使用索引,除非它是索引表达式的一部分。 15. 使用物化视图 物化视图可以预先计算并...

    Oracle考试必备知识

    2. **Oracle进程**:Oracle在运行时会创建多个后台进程,每个进程都有特定的功能,例如控制进程、数据写入进程等。 #### 三、Oracle表空间管理 1. **创建表空间**:用于存储数据库对象,如表、索引等。 ```sql ...

    DB2学习记录

    Oracle数据库实现了许多非标准的SQL方言和扩展特性,如`CONNECT BY`递归查询、`(+)`外连接操作符、`DUAL`表、`ROWNUM`伪列、`ROWID`伪列以及`MINUS`操作符等。这些特性在Oracle中非常常用,但在DB2中则不支持。然而...

    北大青鸟Oracle ppt2

    Oracle数据库是世界上最流行的数据库管理系统之一,尤其在企业级应用中占据重要地位。北大青鸟的Oracle教程主要关注SQL查询和函数,以及Oracle数据库的基本概念。本篇内容将深入讲解Oracle数据库的架构、主要查询...

    Oracle学习笔记

    Oracle是世界上最广泛使用的数据库管理系统之一,它提供了丰富的功能和强大的性能。以下是一些关于Oracle学习的基础知识点: 1. **查询表结构**:使用`DESC table_name`命令可以查看Oracle数据库中表的结构,包括...

Global site tag (gtag.js) - Google Analytics