处理存储过程中的每一行或DB2中的SQL

时间:2018-01-18 16:58:23

标签: db2

我基本上来自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或存储过程来完成。我尝试创建过程但很多问题,有人可以帮助

1 个答案:

答案 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
@