分离和附加分区 db2 版本 10.5 给出 sqlstate 55007 错误
Detach and attach partition db2 version 10.5 giving sqlstate 55007 error
我有一个 db2 过程,它将一个分区分离到临时 table,然后再附加回该分区。当我从快速 sql 执行分离、删除和附加时,它工作得很好,但是当我从存储过程执行它时,我看到这个错误。
无法更改类型 table 的对象 "udbadm.table_name",因为它当前正由同一应用程序进程使用。请指教。下面是我的存储过程。
编辑代码以包含 dbms_alert.sleep(120);查看错误 A null value was specified in a context where null value is not allowed.sqlstate 22004
db2 版本为 10.5。我正在从 rapid sql 执行此操作,但是当从线路处理器作为 db2 => call 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) 如果在游标处理过程中 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;
即使在 FETCH
之后获得了 END OF CURSOR
代码,您仍然尝试处理数据。
您必须在 FETCH
之后立即检查 SQLCODE
。使用这样的东西:
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;
查看 Detaching data partitions 主题了解更多详情。
我有一个 db2 过程,它将一个分区分离到临时 table,然后再附加回该分区。当我从快速 sql 执行分离、删除和附加时,它工作得很好,但是当我从存储过程执行它时,我看到这个错误。
无法更改类型 table 的对象 "udbadm.table_name",因为它当前正由同一应用程序进程使用。请指教。下面是我的存储过程。
编辑代码以包含 dbms_alert.sleep(120);查看错误 A null value was specified in a context where null value is not allowed.sqlstate 22004
db2 版本为 10.5。我正在从 rapid sql 执行此操作,但是当从线路处理器作为 db2 => call 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) 如果在游标处理过程中 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;
即使在 FETCH
之后获得了 END OF CURSOR
代码,您仍然尝试处理数据。
您必须在 FETCH
之后立即检查 SQLCODE
。使用这样的东西:
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;
查看 Detaching data partitions 主题了解更多详情。