Таблицы секционирования диапазона с данными в DB2 LUW - PullRequest
0 голосов
/ 10 января 2020

Прежде всего, мой вопрос будет, если есть способ автоматического генерирования разделов (например, интервал в Oracle для разбиения диапазона) при вставке данных в многораздельную таблицу в DB2?

На На данный момент у меня есть схема с несколькими сотнями таблиц, которые не разделены. И я полагаю, чтобы разделить их. Мои шаги будут:

  • переименовать все таблицы в OLD_table_name
  • выполнить DDL для этих таблиц, но уже разбитые (по типу данных столбца load_id int)
  • выполнить для все, вставьте в table_name select * from OLD_table_name

... и вот оно начинается. (Конечно, процесс должен выполняться автоматически, и я не знаю, какие значения содержат столбец load_id + они будут все различаться для всех таблиц, в противном случае можно было бы просто сгенерировать операторы alter и выполнить их). Поэтому я бы go для курсора.

На данный момент у меня есть решение, которое работает, но мне оно не нравится:

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

Кроме того, я попробовал более элегантный (на мой взгляд) вариант, но не сделал t sucseed:

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

Буду очень признателен за любую подсказку.

1 Ответ

0 голосов
/ 11 января 2020

Попробуйте что-то вроде этого:

--#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
@
...