处理 DB2 中存储过程或 SQL 中的每一行
Posted
技术标签:
【中文标题】处理 DB2 中存储过程或 SQL 中的每一行【英文标题】:Process Each row in stored procedure or SQL in DB2 【发布时间】:2018-01-18 16:58:23 【问题描述】:我基本上来自 Oracle 背景并尝试创建一个 SQL 代码或存储过程,它将为每个处于重组挂起状态的表执行 REORG
我已经想出办法来获取下面给出的这些表格的列表
SELECT 'CALL SYSPROC.ADMIN_CMD(''REORG TABLE', substr(rtrim(TABSCHEMA)||'.'||rtrim(TABNAME),1,20) ||''')', ';'来自 SYSIBMADM.ADMINTABINFO,其中 REORG_PENDING = 'Y' AND TABSSCHEMA=CURRENT SCHEMA
现在我的要求是为找到的每一行将这个结果集作为 DB2 SQL 命令运行,我没有使用 shell 脚本或批处理文件的选项,它必须使用 SQL 或存储过程来完成。我尝试创建 proc 但有很多问题,有人可以帮忙
【问题讨论】:
【参考方案1】:没有必要为此编写存储过程,除非您有特殊要求。您可以通过以下方式要求 Db2 完成工作:
CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS('table', current schema, NULL)
您可以阅读有关该功能的信息here。
否则,如果您确实对重组有特殊要求,使用游标查找完全限定表名可能更简单,即使用游标填充数组并迭代该数组以进行重组.
在生产环境中使用离线重组要格外小心,因此您可能需要内置一些防御性代码来防止导致服务中断。
否则,您可以使用"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
@
【讨论】:
mao,这是一个很大的帮助,非常感谢。还有一个问题,有什么方法可以在执行过程时打印每个表名的值,即过程执行应该给出每个表名的输出 您可以添加逻辑以将进度插入另一个表(最好通过自主存储过程完成),这将允许另一个进程查询该表的进度。或者,如果您想等到作业结束,请使用 dbms_output.put_line()。 是的,我已经通过创建一个临时表来跟踪它来解决这个问题。谢谢。 是否有任何文件说明哪些活动会导致表格进入重组待定状态?我知道更改数据类型是其中之一,但是我不确定是什么其他原因导致了这种情况,找不到关于此的适当文档。连续更改表格 3 次会导致这种情况吗?以上是关于处理 DB2 中存储过程或 SQL 中的每一行的主要内容,如果未能解决你的问题,请参考以下文章