暂无图片
oracle 存储过程是否支持多层游标循环
我来答
分享
Edward
2021-04-21
oracle 存储过程是否支持多层游标循环
暂无图片 10M

需求:
1、想做个自动查找HW表的存储过程,定时查找高水位表并进行相应的回收。

实现:
1、写了个存储过程,分成两个游标循环,第一个循环查找表并执行HW的回收;
2、在存储过程中第二个循环查询由于第一步回收表导致表上的索引失效,执行重建索引。

问题:
存储过程编写完成后,执行时第一个游标循环执行了,第二个没有执行。见标记黄色的位置

create PROCEDURE Clean_HW_Table
as
S_SQL VARCHAR2(2000);
t_tablename varchar2(255);
t_index_name varchar2(2000);
CURSOR c1 IS SELECT
D.TABLE_NAME
FROM DBA_TABLES D
WHERE D.BLOCKS > 10
AND ROUND(D.NUM_ROWS / D.BLOCKS, 2) < 5
AND d.OWNER =(SELECT SYS_CONTEXT (‘USERENV’, ‘SESSION_USER’) ur FROM DUAL)
AND d.TABLE_NAME not like ‘VT%’;
BEGIN
BEGIN
FOR x IN c1
LOOP
t_tablename := x.TABLE_NAME;
S_SQL :=‘alter table ‘||t_tablename ||’ deallocate unused’;
EXECUTE IMMEDIATE S_SQL;
S_SQL :=‘alter table ‘||t_tablename ||’ move’;
EXECUTE IMMEDIATE S_SQL;
dbms_stats.gather_table_stats(‘EAS1’,t_tablename, estimate_percent => 100,cascade=>TRUE, method_opt => ‘FOR ALL COLUMNS SIZE AUTO’,degree =>6);
END LOOP;
END;
BEGIN
FOR LINE2 IN (SELECT owner, index_name
FROM dba_indexes
WHERE owner =(SELECT SYS_CONTEXT (‘USERENV’, ‘SESSION_USER’) ur FROM DUAL)
AND status NOT IN (‘VALID’, ‘N/A’)
ORDER BY owner, index_name
) LOOP
t_index_name:= ‘alter index ’ || LINE2.OWNER ||’.’|| LINE2.index_name || ’ rebuild online nologging’;
DBMS_OUTPUT.PUT_LINE (t_index_name);
EXECUTE IMMEDIATE t_index_name;
END LOOP;
END;

EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE (‘NO_DATA_FOUND’);
RETURN;
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE (‘OTHERS’);
RETURN;
END;
/

我来答
添加附件
收藏
分享
问题补充
4条回答
默认
最新
你好我是李白

一个begin跟一个end就可以了。

begin

for ... loop
...
end loop

for ... loop
...
end loop

end;
/

复制
暂无图片 评论
暂无图片 有用 1
打赏 0
cqiwen

你这个应该把重建索引的写在第一个begin end 的循环体中,即收集好统计信息后,马上重建对应表的索引,这样才能1V1对应上你要重建哪一个表的索引,否则如果前面要收缩高水位的表很多,则可能在收缩完成所有表之前,导致这些表的索引全部失效,影响正常生产。

暂无图片 评论
暂无图片 有用 0
打赏 0
Edward

create or replace PROCEDURE Clean_HW_Table
as
S_SQL VARCHAR2(2000);
t_table_name varchar2(255);
t_index_name varchar2(2000);
CURSOR c1 IS SELECT
D.TABLE_NAME
FROM DBA_TABLES D
WHERE D.BLOCKS > 10
AND ROUND(D.NUM_ROWS / D.BLOCKS, 2) < 5
AND d.OWNER =(SELECT SYS_CONTEXT (‘USERENV’, ‘SESSION_USER’) ur FROM DUAL)
AND d.TABLE_NAME not like ‘VT%’;
BEGIN
FOR x IN c1
LOOP
t_table_name := x.TABLE_NAME;
S_SQL :=‘alter table ‘||t_table_name ||’ deallocate unused’;
EXECUTE IMMEDIATE S_SQL;
S_SQL :=‘alter table ‘||t_table_name ||’ move’;
EXECUTE IMMEDIATE S_SQL;
dbms_stats.gather_table_stats(‘EAS1’,t_table_name, estimate_percent => 100,cascade=>TRUE, method_opt => ‘FOR ALL COLUMNS SIZE AUTO’,degree =>6);
END LOOP;
FOR LINE2 IN (SELECT owner, index_name
FROM dba_indexes
WHERE owner =(SELECT SYS_CONTEXT (‘USERENV’, ‘SESSION_USER’) ur FROM DUAL)
AND status NOT IN (‘VALID’, ‘N/A’)
ORDER BY owner, index_name
) LOOP
t_index_name:= ‘alter index ’ || LINE2.OWNER ||’.’|| LINE2.index_name || ’ rebuild online nologging’;
DBMS_OUTPUT.PUT_LINE (t_index_name);
EXECUTE IMMEDIATE t_index_name;
END LOOP;

EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE (‘NO_DATA_FOUND’);
RETURN;
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE (‘OTHERS’);
RETURN;
END;
各位老师,目前的问题是第二段重建索引不执行,是那里写的不对吗?

暂无图片 评论
暂无图片 有用 0
打赏 0
DarkAthena

只要游标里有数据,就是可以执行的,所以你先把第二个游标拿出来直接查下,看看是不是有数据。另外你这里写了几个异常处理,全部都是正常返回,如果第一个游标的循环里,某一条已经报错了,当然第二个循环就不会再跑了,所以建议你先把这些异常处理都拿掉,看看有些什么错

暂无图片 评论
暂无图片 有用 1
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
分析Oracle归档日志用什么工具?
回答 2
已采纳
可以用toad工具,操作相对简单些,图形化工具
zabbix-server log报找不到这个odbc驱动,文件是存在的,然后使用isql 也能登录 ldd这个文件也是正常的 ldconfig 也正常
回答 2
已采纳
缺少环境变量配置,试试配置下oracle环境变量cat/etc/sysconfig/zabbixserverexportORACLEHOME/usr/lib/oracle/11.2/client64e
oracle11g执行logmnr如何进行停止
回答 9
我再追问一下,这个日志是做什么用的,为什么会引起系统资源全部占用
oracle rman备份文件1个月就被删除了。
回答 3
已采纳
看看系统日志是否有文件删除记录,如果是外挂存储或者磁盘,还要看是否存储或者别的服务器定时删除文件
数据库服务器开了防火墙后,weblogic就连接不上了,怎么办?
回答 1
开放oracle监听端口,使得应用可以访问
有人知道为什么ALTER TABLE tablename ENABLE TABLE LOCK 为啥没反应么
回答 1
Oracle吗?是没有反应还是一直不反回结果。用下面语句查查有没有锁该表的会话呢?selectc.owner,c.objectname,c.objecttype,b.sid,b.serial,b.st
Oracle 在主库做增量修复dg,有新增数据文件,备库一般是用哪种命令?
回答 3
我理解楼主的意思是,dg同步断开了,日志不全了,需要利用增量的方法来重建adg。
plsql添加sqltools插件
回答 1
1、确认目录没错,在plugins下,不是上一级或下一级;2、这个插件是32位的,最好用32位的plsqldev;3、还是不行的话,换个plsql或者重新下载一次
oracle索引
回答 1
已采纳
可以,指定schema,指定表空间即可
如何确定已经安装的是olap 还是oltp
回答 2
已采纳
没有具体信息体现,业务复杂度,现在大部分已经混合OLAP和OLTP模式了;主要是安装数据库时选的模版,还是在使用过程中业务需求决定的;