Hi there
I made a simple partitioned table (like a federated original):
CREATE TABLE schema.home_table LIKE schema.remote_table
PARTITION BY RANGE(id) (
PARTITION dummy_partition STARTING 0 ENDING 0,
);
Next i try to create/refresh the data within the home partition with a stored procedure.
Creating a new table like the federated, catching the information i want and put it into the home table as a partition is no problem.
But at the moment i try to refresh the data with a new partition i get this error:
SQL20285N The statement or command is not allowed because the table named
"SCHEMA.HOME_TABLE_BACKUP" has detached dependents or the asynchronous
partition detach operation is not complete. Reason code = "2". SQLSTATE=55057
Now i wonder why this happens and hope you can help me here.
Here is the procedure:
CREATE PROCEDURE IPMS.RELOAD_TABLE_SP_EXT (IN source VARCHAR(261),IN destination VARCHAR(261),IN column_to_use VARCHAR(261), in id_to_use BIGINT) SPECIFIC TABLE_RELOAD_SP_EXT
P1: BEGIN ATOMIC
DECLARE create_temp_tbl VARCHAR(1000);
DECLARE drop_temp_tbl VARCHAR(1000);
DECLARE insert_data VARCHAR(1000);
DECLARE drop_backup_tbl VARCHAR(1000);
DECLARE name_ptn VARCHAR(1000);
DECLARE detach_ptn VARCHAR(1000);
DECLARE attach_ptn VARCHAR(1000);
DECLARE integrity_ptn VARCHAR(1000);
DECLARE temp_tbl_count INTEGER DEFAULT 0;
DECLARE ptn_count INTEGER DEFAULT 0;
DECLARE backup_tbl_count INTEGER DEFAULT 0;
DECLARE at_end SMALLINT DEFAULT 0;
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE stmt_string VARCHAR(1000);
DECLARE stmt VARCHAR(1000);
DECLARE result_cursor CURSOR WITH RETURN FOR stmt;
DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;
CASE UPPER(destination)
WHEN 'SCHEMA.HOME_TABLE' THEN
SET name_ptn = 'NEW_PARTITION_';
WHEN 'SCHEMA.OTHER_TABLE' THEN
SET name_ptn = 'ANOTHER_NEW_PARTITION_';
WHEN ...;
ELSE
SET name_ptn = 'unknown';
END CASE;
-- get ids as partition ranges:
SET stmt_string = 'SELECT DISTINCT COALESCE((SELECT DISTINCT ' || column_to_use || ' FROM ' || source || ' WHERE ' || column_to_use || ' = ' || id_to_use || '), ' || column_to_use || ') AS id FROM ' || source || ' WHERE ' || column_to_use || ' > 0 ORDER BY 1 DESC';
PREPARE stmt FROM stmt_string;
OPEN result_cursor;
-- loop through the ids and create new data on the home system:
fetch_loop: REPEAT
FETCH result_cursor INTO id_to_use;
SET create_temp_tbl = 'CREATE TABLE SCHEMA.' || name_ptn || id_to_use || '_temp like ' || source;
SET drop_temp_tbl = 'DROP TABLE SCHEMA.' || name_ptn || id_to_use || '_temp';
SET insert_data = 'INSERT INTO SCHEMA.' || name_ptn || id_to_use || '_temp SELECT * FROM ' || source || ' where ' || column_to_use || ' = ' || id_to_use || ' with ur';
SET drop_backup_tbl = 'DROP TABLE SCHEMA.' || name_ptn || id_to_use || '_backup';
SET detach_ptn = 'ALTER TABLE ' || destination || ' DETACH PARTITION ' || name_ptn || id_to_use || ' INTO SCHEMA.' || name_ptn || id_to_use || '_backup';
SET attach_ptn = 'ALTER TABLE ' || destination || ' ATTACH PARTITION ' || name_ptn || id_to_use || ' STARTING ' || id_to_use || ' ENDING ' || id_to_use || ' FROM TABLE SCHEMA.' || name_ptn || id_to_use || '_temp';
SET integrity_ptn = 'SET INTEGRITY FOR ' || destination || ' IMMEDIATE CHECKED';
-- lookup if temp table (new partition) exists and delete if it is so:
SELECT COUNT(*) INTO temp_tbl_count FROM SYSCAT.TABLES WHERE TABNAME = upper(substr(name_ptn || id_to_use || '_temp', locate('.', name_ptn || id_to_use || '_temp')+1));
IF (temp_tbl_count > 0) THEN
EXECUTE IMMEDIATE drop_temp_tbl;
END IF;
-- create new temp table and fill it with remote data:
EXECUTE IMMEDIATE create_temp_tbl;
EXECUTE IMMEDIATE insert_data;
-- lookup if backup table (old partition) exists and delete if it is so:
SELECT COUNT(*) INTO backup_tbl_count FROM SYSCAT.TABLES WHERE TABNAME = upper(substr(name_ptn || id_to_use || '_backup', locate('.', name_ptn || id_to_use || '_backup')+1));
IF (backup_tbl_count > 0) THEN
EXECUTE IMMEDIATE drop_backup_tbl;
END IF;
-- lookup if new partition name exists and detach if it is so:
SELECT count(*) INTO ptn_count FROM SYSCAT.DATAPARTITIONS WHERE TABSCHEMA = 'SCHEMA' AND TABNAME = upper(substr(destination, locate('.', destination)+1)) AND datapartitionname = name_ptn || id_to_use;
IF (ptn_count > 0) THEN
EXECUTE IMMEDIATE detach_ptn;
END IF;
-- attach new partition into home table and setting integrity:
EXECUTE IMMEDIATE attach_ptn;
EXECUTE IMMEDIATE integrity_ptn;
UNTIL at_end > 0
END REPEAT fetch_loop;
CLOSE result_cursor;
END P1
The calling is like this:
call schema.reload_table_sp_ext('schema.remote_table', 'schema.home_table', 'filter_id', 5)
filter_id: the column name for the ids/partition range
5: the id that should get refreshed
If you need more information please don't hesitate to write about it :-)