我基本上来自Oracle后台,并尝试创建一个SQL代码或存储过程,它将为处于reorg pending状态的每个表执行REORG
我已经找到了获取此类表格列表的方法,如下所示
SELECT' CALL SYSPROC.ADMIN_CMD('' REORG TABLE',substr(rtrim(TABSCHEMA)||'。' || rtrim(TABNAME) ,1,20)||''')',';'来自SYSIBMADM.ADMINTABINFO,其中REORG_PENDING =' Y' AND TABSCHEMA = CURRENT SCHEMA
现在我的要求是将此结果集作为DB2 SQL命令运行,对于找到的每一行,我没有选择使用shell脚本或批处理文件,必须使用SQL或存储过程来完成。我尝试创建过程但很多问题,有人可以帮助
答案 0 :(得分:0)
除非您有特殊要求,否则没有必要为此目的编写代码。您可以通过以下方式要求Db2完成工作:
CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS('table', current schema, NULL)
您可以阅读该功能here。
否则,如果每个reorg都有特殊要求,使用游标查找完全限定表名称可能更简单,即使用游标填充数组并迭代该数组以进行重组
在生产环境中使用离线重组非常小心,因此您可能希望内置一些防御性代码以防止导致服务中断。
否则,您可以使用"Receiving procedure result sets in SQL routines"
文档中提到的技术处理从存储过程返回的结果集此外,如果您的Db2数据库是为支持Oracle兼容性而创建的,则可以使用Oracle PLSQL语法并仅添加ADMIN_CMD()内容。在这种情况下,您不必使用Db2的ANSI SQLPL样式。
这是一个使用游标和数组的愚蠢裸骨示例,还有很多其他方法可以做到这一点,包括更优雅的方式:
--#SET TERMINATOR @
create or replace type reorg_list as VARCHAR(1024) array[]
@
create or replace procedure sp_reorgpending ()
language sql
specific sp_reorgpending
begin
declare v_sqlcode integer default 0;
declare v_stmt varchar(1024);
declare v_tabname varchar(1024);
declare tables_to_reorg reorg_list;
declare v_counter integer;
declare c1 cursor with hold for select rtrim(tabschema)||'.'||rtrim(tabname) from SYSIBMADM.ADMINTABINFO where REORG_PENDING = 'Y' AND TABSCHEMA=CURRENT SCHEMA;
declare continue handler for not found set v_sqlcode=100;
set v_counter=0;
open c1;
fetch c1 into v_tabname;
while ( v_sqlcode = 0 ) do
set v_counter = v_counter + 1 ;
set tables_to_reorg[v_counter] = v_tabname;
fetch c1 into v_tabname;
end while;
close c1;
while ( v_counter > 0 ) do
set v_stmt='reorg table '||tables_to_reorg[v_counter] ;
call admin_cmd(v_stmt);
set v_counter = v_counter -1 ;
end while;
return 0;
end
@