问题描述
嗨,
我正在浏览汤姆的书,发现 “快照太旧” 部分。在 “创建小的撤消表空间” 一节中,并运行下面的块。
下面的块生成错误消息 “快照太旧”。根据我的理解,列值在第一个查询之后位于游标c中。在循环中,完成值的提取。由于值是旧的并且已经存储在cursor中,因此循环将简单地获取存储在cursor中的值。错误是如何引发的。请解释一下。
操作 $ tkyte % ORA11GR2> 声明
光标c是
选择/* first_rows */ object_name
从t
按object_id排序;
l_object_name t.object_name % 类型;
l_rowcnt数: = 0;
开始
打开c;
循环
将c取为l_object_name;
当c % 未找到时退出;
dbms_lock.sleep( 0.01 );
l_rowcnt := l_rowcnt 1;
结束循环;
关闭c;
异常
当其他人那么
dbms_output.put_line ('rowched = '| | l_rowcnt );
加薪;
结束;
/
获取的行 = 301
声明
*
第1行的错误:
ORA-01555: 快照太旧: 带名称的回滚段号46
“_ SYSSMU46_2555494716 $” 太小
ORA-06512: 在第21行
在上述块之前,此块是从其他会话运行的
开始
for x in ( select rowid rid从t )
循环
更新设置object_name = 更低 (object_name),其中rowid = x.rid;
提交;
结束循环;
结束;
/
我正在浏览汤姆的书,发现 “快照太旧” 部分。在 “创建小的撤消表空间” 一节中,并运行下面的块。
下面的块生成错误消息 “快照太旧”。根据我的理解,列值在第一个查询之后位于游标c中。在循环中,完成值的提取。由于值是旧的并且已经存储在cursor中,因此循环将简单地获取存储在cursor中的值。错误是如何引发的。请解释一下。
操作 $ tkyte % ORA11GR2> 声明
光标c是
选择/* first_rows */ object_name
从t
按object_id排序;
l_object_name t.object_name % 类型;
l_rowcnt数: = 0;
开始
打开c;
循环
将c取为l_object_name;
当c % 未找到时退出;
dbms_lock.sleep( 0.01 );
l_rowcnt := l_rowcnt 1;
结束循环;
关闭c;
异常
当其他人那么
dbms_output.put_line ('rowched = '| | l_rowcnt );
加薪;
结束;
/
获取的行 = 301
声明
*
第1行的错误:
ORA-01555: 快照太旧: 带名称的回滚段号46
“_ SYSSMU46_2555494716 $” 太小
ORA-06512: 在第21行
在上述块之前,此块是从其他会话运行的
开始
for x in ( select rowid rid从t )
循环
更新设置object_name = 更低 (object_name),其中rowid = x.rid;
提交;
结束循环;
结束;
/
专家解答
游标是指向结果集的指针。打开光标标志着您打算查看该时间点的数据。它没有查询返回的值。只有当您从游标中获取数据时,您才能获得值。
这就是为什么打开光标是即时的: 它没有得到任何数据!
例如,如果您创建了一个休眠1秒的函数和一个10行表:
为t的每一行调用f的查询需要10s:
但是打开此查询的光标是即时的:
只有当您获取游标时,Oracle数据库才会执行查询并获取值:
所以如果在fetch时间Oracle数据库无法重建数据在您的时间opened光标 (因为撤消被覆盖或其他),你得到ORA-01555。
这就是为什么打开光标是即时的: 它没有得到任何数据!
例如,如果您创建了一个休眠1秒的函数和一个10行表:
create or replace function f (v int) return int as begin dbms_lock.sleep(1); return v; end; / drop table t purge; create table t as select rownum x from dual connect by level <= 10;复制
为t的每一行调用f的查询需要10s:
SQL> set timing on SQL> select f(x) from t; F(X) ---------- 1 2 3 4 5 6 7 8 9 10 10 rows selected. Elapsed: 00:00:10.46复制
但是打开此查询的光标是即时的:
SQL> var c refcursor; SQL> begin 2 open :c for 3 select f(x) from t; 4 end; 5 / PL/SQL procedure successfully completed. Elapsed: 00:00:00.31复制
只有当您获取游标时,Oracle数据库才会执行查询并获取值:
SQL> print :c; F(X) ---------- 1 2 3 4 5 6 7 8 9 10 10 rows selected. Elapsed: 00:00:10.31复制
所以如果在fetch时间Oracle数据库无法重建数据在您的时间opened光标 (因为撤消被覆盖或其他),你得到ORA-01555。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle DataGuard高可用性解决方案详解
孙莹
426次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
385次阅读
2025-04-15 17:24:06
墨天轮个人数说知识点合集
JiekeXu
364次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
357次阅读
2025-04-08 09:12:48
Oracle SQL 执行计划分析与优化指南
Digital Observer
329次阅读
2025-04-01 11:08:44
Oracle 19c RAC更换IP实战,运维必看!
szrsu
296次阅读
2025-04-08 23:57:08
风口浪尖!诚通证券扩容采购Oracle 793万...
Roger的数据库专栏
293次阅读
2025-03-24 09:42:53
切换Oracle归档路径后,不能正常删除原归档路径上的归档文件
dbaking
287次阅读
2025-03-19 14:41:51
oracle定时任务常用攻略
virvle
286次阅读
2025-03-25 16:05:19
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
272次阅读
2025-04-15 14:48:05