Отсоедините и прикрепите раздел db2 версии 10.5, что приводит к ошибке sqlstate 55007 - PullRequest
0 голосов
/ 30 января 2019

У меня есть процедура db2, которая отделяет раздел во временной таблице, а затем присоединяет его обратно.Когда я выполняю отсоединение, удаление и присоединение из быстрого SQL, он работает отлично, но когда я выполняю его из хранимой процедуры, я вижу эту ошибку.

Объект "udbadm.table_name" таблицы типов не может быть изменен, потому чтов настоящее время он используется тем же процессом подачи заявки.Пожалуйста посоветуй.Ниже моя хранимая процедура.

Отредактировал код для включения dbms_alert.sleep (120);Видение ошибки В контексте, где недопустимо нулевое значение, было указано нулевое значение. Версия 22004

db2 равна 10.5Я выполняю это из быстрого sql, но при вызове из линейного процессора как db2 => вызов OSL_CLNUP_MNTHLY_SBLDGR_DET (98,56, '08 / 31/2018 ', 5) я получил ту же ошибку.

DROP SPECIFIC PROCEDURE OSLD02.OSL_CLNUP_MNTHLY_SBLDGR_DET
;
  CREATE PROCEDURE OSLD02.OSL_CLNUP_MNTHLY_SBLDGR_DET(IN    
                                          IN_ID_BUS_PROCSS SMALLINT,
                                                IN IN_ID_RUN SMALLINT,
                                                IN IN_DT_EOP DATE,
                                                IN IN_BATCH_SIZE INTEGER)
SPECIFIC OSLD02.OSL_CLNUP_MNTHLY_SBLDGR_DET
MODIFIES SQL DATA
NOT DETERMINISTIC
NULL CALL
LANGUAGE SQL EXTERNAL ACTION
INHERIT SPECIAL REGISTERS

 BEGIN

--------------------------------------------------------------------------    ---------------------------------------
-------------------- Declarations
--------------------------------------------------------------------------   ---------------------------------------
declare v_id_task_log    integer;
declare v_cnt_deleted    integer;
declare v_cnt_initial    integer;
declare v_count integer;
declare v_cd_acctg_purp character(10);
declare v_month_eop integer;
declare SQLCODE int default 0; 
declare v_sqlcode int;
declare v_partitionName character(20);
declare v_lowValue character(10);
declare v_highValue character(10);
declare v_detachStmt varchar(512);    
declare v_dropTable varchar(512);   
declare SQL_STMT varchar(512);   
declare v_exist int;
declare v_stagingSchemaTable varchar(512);
DECLARE v_outmessage VARCHAR(32672);
 DECLARE v_outstatus integer default 0;
 DECLARE v_seconds INTEGER default 300;
 declare wait_until timestamp;
declare detach_complete_flg character(2) default 'N';
declare loop_limit int default 0;

declare global temporary table session.detail_tmp
( partition character(10), start character(30), end character(30) ) on    
  commit preserve rows with replace not logged;

 BEGIN

 DECLARE C1 CURSOR WITH HOLD FOR
 select   DATAPARTITIONNAME, LOWVALUE, HIGHVALUE
 from syscat.DATAPARTITIONS  where tabname='SBLDGR_DET'
 and  (SUBSTR(HIGHVALUE, 2,LOCATE(',',HIGHVALUE)-3)
,SUBSTR(HIGHVALUE, LOCATE(',',HIGHVALUE)+1) ) in (
 select  CD_ACCTG_PURP, mo_eop
 from SBLDGR_DET
 where mo_eop< cast (month(IN_DT_EOP) as char(2))
 group by CD_ACCTG_PURP, mo_eop
 having count(*)>0
 )
with ur;

OPEN C1;--
set v_sqlcode=0;--

L1: LOOP
 FETCH C1 INTO v_partitionName, v_lowValue,v_highValue;
 IF SQLCODE<> 0 THEN 
 LEAVE L1; 
 END IF;

set v_detachStmt = 'ALTER TABLE SBLDGR_DET DETACH PARTITION '   
 ||v_partitionName|| ' INTO TABLE OSLSTG.SL_DET_'||v_partitionName;
 EXECUTE IMMEDIATE v_detachStmt ;
 commit;


 while (loop_limit < 10000 and detach_complete_flg = 'N') DO
call dbms_alert.sleep(60);

 IF EXISTS (SELECT 1 FROM SYSCAT.DATAPARTITIONS WHERE TABSCHEMA='OSLSTG'
     AND 
         TABNAME='SL_DET_'|| v_partitionName AND STATUS=' ')    
THEN             
 set detach_complete_flg = 'Y'; 
 END IF; 

 set loop_limit = loop_limit + 1;
 end while;

 set v_dropTable = 'drop table OSLSTG.SL_DET_'||v_partitionName; 
 EXECUTE IMMEDIATE v_dropTable ;
commit;

 SET SQL_STMT   = 'ALTER TABLE sbldgr_det ADD    
PARTITION '||v_partitionName||' STARTING FROM (' || v_lowValue|| ' )
ENDING AT (' || v_highValue|| ')';
 EXECUTE IMMEDIATE SQL_STMT;   
commit;

END LOOP L1;

 CLOSE   C1;--

 END
 ;

END
;

commit;

1 Ответ

0 голосов
/ 31 января 2019

В вашем коде есть ряд проблем.Я не собираюсь предлагать вам полное решение, только некоторые примечания.

1) Если вы commit во время обработки курсора, вы должны DECLARE CURSOR с предложением WITH HOLD.

2) Следующая обработка курсора некорректна.

WHILE (v_sqlcode = 0) DO
  FETCH C1 INTO v_partitionName, v_lowValue,v_highValue;
  set v_sqlcode=sqlcode;
  set v_detachStmt = 'ALTER TABLE SBLDGR_DET DETACH PARTITION'
    ||v_partitionName||' INTO TABLE OSLSTG.SL_DET_'||v_partitionName;
  EXECUTE IMMEDIATE v_detachStmt;
  ...
END WHILE;

Вы по-прежнему пытаетесь обработать данные, даже если вы получили код END OF CURSOR после FETCH.Вы должны проверить SQLCODE сразу после FETCH.Используйте что-то вроде этого:

L1: LOOP
  FETCH C1 INTO v_partitionName, v_lowValue,v_highValue;
  IF SQLCODE<>0 THEN LEAVE L1; END IF;
  ...
END LOOP L1;

3) Вы должны сделать что-то вроде ниже.

После:

EXECUTE IMMEDIATE v_detachStmt;
commit;

Вы должны реализовать:

-- Check in loop (sleep, let's say N sec, after each check) 
-- until you get a row with the following statement
-- (construct your table name dynamically):

SELECT 1 
FROM SYSCAT.DATAPARTITIONS
WHERE TABSCHEMA='OSLSTG' AND TABNAME='SL_DET_v_partitionName' AND STATUS=''
WITH UR;

Подробнее смотрите в теме Отсоединение разделов данных .

...