Stored procedures pl/sql中过程执行的循环结果
我想制作一个存储过程来检查ORACLEDB表并为它们收集统计数据。 到目前为止,我已经做到了这一点,现在我想知道如何在同一个循环中捕获每一行的执行结果Stored procedures pl/sql中过程执行的循环结果,stored-procedures,plsql,Stored Procedures,Plsql,我想制作一个存储过程来检查ORACLEDB表并为它们收集统计数据。 到目前为止,我已经做到了这一点,现在我想知道如何在同一个循环中捕获每一行的执行结果 declare comm varchar2(200); cursor c1 is select owner, table_name, num_rows, last_analyzed from dba_tables where num_rows>=500000 and owner not in
declare
comm varchar2(200);
cursor c1 is
select owner, table_name, num_rows, last_analyzed from dba_tables
where num_rows>=500000
and owner not in ('SYS','SYSTEM')
and last_analyzed <= sysdate -7
order by 3 desc;
begin
FOR V1 IN C1 LOOP
comm:= 'EXEC DBMS_STATS.gather_table_stats( '''||V1.OWNER||''','''||V1.TABLE_NAME||''' , estimate_percent => DBMS_STATS.auto_sample_size);';
EXECUTE IMMEDIATE comm;
end loop;
end;
我试过了,现在就可以了。。。。谢谢你的回复
declare
comm varchar2(200);
cursor c1 is
select owner, table_name, num_rows, last_analyzed from dba_tables
where num_rows>=500000
and owner not in ('SYS','SYSTEM')
and last_analyzed <= sysdate -7
order by 3 desc;
begin
FOR V1 IN C1 LOOP
begin
comm := 'begin DBMS_STATS.gather_table_stats( '''||V1.OWNER||''','''||V1.TABLE_NAME||''' , estimate_percent => DBMS_STATS.auto_sample_size); end;';
--dbms_output.put_line('begin DBMS_STATS.gather_table_stats( '''||V1.OWNER||''' , '''||V1.TABLE_NAME||''' , estimate_percent => DBMS_STATS.auto_sample_size); end;') ;
EXECUTE IMMEDIATE comm ;
dbms_output.put_line( V1.TABLE_NAME || '------Ok------') ;
exception
when others then
dbms_output.put_line(V1.TABLE_NAME || '------Not ok------' || 'SQLERRM: '|| SQLERRM || ' Format error stack : '||dbms_utility.format_error_stack) ;
end;
end loop;
end;
从纯粹的语法角度来看,您的代码可以是这样的:
begin
for r in (
select t.owner, t.table_name, t.num_rows
from dba_tables t
left join dba_external_tables x
on x.owner = t.owner and x.table_name = t.table_name
where t.owner not in ('SYS','SYSTEM')
and t.temporary = 'N'
and x.table_name is null
and t.num_rows >= 500000
and t.last_analyzed <= sysdate -7
)
loop
begin
dbms_stats.gather_table_stats(r.owner, r.table_name);
exception
when others then
dbms_output.put_line('Error gathering stats on table '|| r.owner||'.'||r.table_name||': '|| sqlerrm);
end;
end loop;
end;
我排除了外部表和临时表,并跳过了失败
然而,我不确定这是一个好方法
是否确实要为每个其他架构中的每个表收集统计信息
对于没有任何统计信息的表,会发生什么情况
是否确实要对每个表使用默认方法选项设置?有些表可能有精心编制的直方图和扩展的统计列组,或者它们可能故意完全避免使用直方图
是否会有大量的表格需要花费数小时才能处理?如果是这样,您准备好让脚本运行几天了吗?您可以尝试使用EXECUTE IMMEDIATE comm RETURNING field1进入v_field1。;您希望该语句返回什么值?另外,EXEC是一个SQL*Plus调用:executeimmediate不喜欢它。您需要将调用框架化为一个匿名PL/SQL块:begindbms_stats.gather_table_stats。。。;终止我希望为每个执行立即行输出成功完成,比如:PL/SQL过程。安装soapbox!只是好奇,为什么要整理桌子呢。强迫一张表上的统计数据在3周内未分析,而强迫一张表上的统计数据在2周内未分析,这真的有什么区别吗。它们都将在相同的脚本运行中完成。如果没有任何区别,我的一个癖好就不合适了。哦,好吧,离开soapbox。对于没有stats num_行且上次分析的表为空的表呢?您真的需要临时表和外部表的统计信息吗?为什么要使用executeimmediate,而不是像通常那样调用dbms_stats,即调用dbms_输出的方式?