包含 DB2 LUW 中数据的范围分区表
Range partitioning tables with data in DB2 LUW
首先我的问题是,在将数据插入 DB2 中的分区 table 时,是否有自动生成分区的方法(如 Oracle 中用于范围分区的间隔)?
目前我有一个包含数百个 table 的架构,这些架构未分区。我想把它们分开。
我的步骤是:
- 将所有 table 重命名为 OLD_table_name
- 为那些 table 执行 DDL 但已经分区(按 load_id 列 int 数据类型)
- 全部执行,插入table_name select * from OLD_table_name
...从这里开始。
(当然这个过程必须是自动的,我不知道哪些值包含 load_id 列 + 它们对于所有 table 都是不同的,否则可以生成简单的 alter 语句和处决他们)。
因此我会选择游标。
目前我有有效的解决方案,但我不喜欢它:
BEGIN
FOR CL AS MYCURS INSENSITIVE CURSOR FOR
select distinct 'alter table '||tb_nm||'
add partition PART_'||lpad(load_id,5,0)||'
starting from '||load_id||'
ending at '||load_id v_alt
from (
select load_id,'Table_01' tb_nm from Table_01
union
select load_id ,'Table_02'from Table_02
union
....
/*I have generated this union statements for whole set of tables*/)
do
execute immediate v_alt;
end for;
end
此外,我尝试了一些更优雅(在我看来)的变体,但没有成功:
BEGIN
DECLARE v_stmnt VARCHAR(1000);
DECLARE v_check_val int;
DECLARE v_prep_stmnt STATEMENT;
for i as (select table_name
from sysibm.tables
where TABLE_SCHEMA ='shema_name'
)
do
SET v_stmnt = 'set ? = (SELECT distinct(load_id) FROM '||table_name||')';
PREPARE v_prep_stmnt FROM v_stmnt;
/*and here I stuck. I assume there must be possibility to run next execute as well in loop, but
all my attempts were not succsesfull*/
--EXECUTE v_prep_stmnt into v_check_val ;
end for;
END
非常感谢任何提示。
尝试这样的事情:
--#SET TERMINATOR @
SET SERVEROUTPUT ON@
BEGIN
DECLARE L_TABSCHEMA VARCHAR(128) DEFAULT 'SCHEMA_NAME';
DECLARE L_COLNAME VARCHAR(128) DEFAULT 'LOAD_ID';
DECLARE L_VALUE INT;
DECLARE L_STMT VARCHAR(1024);
DECLARE SQLSTATE CHAR(5);
DECLARE C1 CURSOR FOR S1;
FOR I AS
SELECT TABNAME
FROM SYSCAT.COLUMNS
WHERE TABSCHEMA = L_TABSCHEMA AND COLNAME = L_COLNAME
DO
PREPARE S1 FROM 'SELECT DISTINCT(' || L_COLNAME || ') FROM ' || L_TABSCHEMA || '."' || I.TABNAME ||'"';
OPEN C1;
L1: LOOP
FETCH C1 INTO L_VALUE;
IF SQLSTATE<>'00000' THEN LEAVE L1; END IF;
SET L_STMT =
'alter table ' || L_TABSCHEMA || '."' || I.TABNAME || '" '
||'add partition PART_' || lpad(L_VALUE, 5, 0) || ' starting from ' || L_VALUE || ' ending at ' || L_VALUE;
--CALL DBMS_OUTPUT.PUT_LINE(L_STMT);
EXECUTE IMMEDIATE L_STMT;
END LOOP;
CLOSE C1;
END FOR;
END
@
首先我的问题是,在将数据插入 DB2 中的分区 table 时,是否有自动生成分区的方法(如 Oracle 中用于范围分区的间隔)?
目前我有一个包含数百个 table 的架构,这些架构未分区。我想把它们分开。 我的步骤是:
- 将所有 table 重命名为 OLD_table_name
- 为那些 table 执行 DDL 但已经分区(按 load_id 列 int 数据类型)
- 全部执行,插入table_name select * from OLD_table_name
...从这里开始。 (当然这个过程必须是自动的,我不知道哪些值包含 load_id 列 + 它们对于所有 table 都是不同的,否则可以生成简单的 alter 语句和处决他们)。 因此我会选择游标。
目前我有有效的解决方案,但我不喜欢它:
BEGIN
FOR CL AS MYCURS INSENSITIVE CURSOR FOR
select distinct 'alter table '||tb_nm||'
add partition PART_'||lpad(load_id,5,0)||'
starting from '||load_id||'
ending at '||load_id v_alt
from (
select load_id,'Table_01' tb_nm from Table_01
union
select load_id ,'Table_02'from Table_02
union
....
/*I have generated this union statements for whole set of tables*/)
do
execute immediate v_alt;
end for;
end
此外,我尝试了一些更优雅(在我看来)的变体,但没有成功:
BEGIN
DECLARE v_stmnt VARCHAR(1000);
DECLARE v_check_val int;
DECLARE v_prep_stmnt STATEMENT;
for i as (select table_name
from sysibm.tables
where TABLE_SCHEMA ='shema_name'
)
do
SET v_stmnt = 'set ? = (SELECT distinct(load_id) FROM '||table_name||')';
PREPARE v_prep_stmnt FROM v_stmnt;
/*and here I stuck. I assume there must be possibility to run next execute as well in loop, but
all my attempts were not succsesfull*/
--EXECUTE v_prep_stmnt into v_check_val ;
end for;
END
非常感谢任何提示。
尝试这样的事情:
--#SET TERMINATOR @
SET SERVEROUTPUT ON@
BEGIN
DECLARE L_TABSCHEMA VARCHAR(128) DEFAULT 'SCHEMA_NAME';
DECLARE L_COLNAME VARCHAR(128) DEFAULT 'LOAD_ID';
DECLARE L_VALUE INT;
DECLARE L_STMT VARCHAR(1024);
DECLARE SQLSTATE CHAR(5);
DECLARE C1 CURSOR FOR S1;
FOR I AS
SELECT TABNAME
FROM SYSCAT.COLUMNS
WHERE TABSCHEMA = L_TABSCHEMA AND COLNAME = L_COLNAME
DO
PREPARE S1 FROM 'SELECT DISTINCT(' || L_COLNAME || ') FROM ' || L_TABSCHEMA || '."' || I.TABNAME ||'"';
OPEN C1;
L1: LOOP
FETCH C1 INTO L_VALUE;
IF SQLSTATE<>'00000' THEN LEAVE L1; END IF;
SET L_STMT =
'alter table ' || L_TABSCHEMA || '."' || I.TABNAME || '" '
||'add partition PART_' || lpad(L_VALUE, 5, 0) || ' starting from ' || L_VALUE || ' ending at ' || L_VALUE;
--CALL DBMS_OUTPUT.PUT_LINE(L_STMT);
EXECUTE IMMEDIATE L_STMT;
END LOOP;
CLOSE C1;
END FOR;
END
@