Antes de perceber que existia um procedimento para revalidar objetos (SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS), escrevi o meu próprio. Agora, tento substituí-lo pelo padrão, mas parece que a chamada para SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS destrói o cursor sobre o qual estou fazendo o loop. Exemplo de procedimento antigo:
db2 -td@ +c "BEGIN FOR v AS c1 CURSOR FOR SELECT SCHEMANAME FROM NYA.VALIDATION_SCHEMAS DO CALL TOOLBOX.COMPILE_SCHEMA2(v.schemaname); END FOR; END @"
DB20000I The SQL command completed successfully.
Exemplo usando ADMISN_REVALIDATE_DB_OBJECTS
db2 "CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS(object_schema=>'TMP')"
Return Status = 0
db2 "CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS(object_schema=>'TMP')"
Return Status = 0
Tentando usar isso em um loop sobre um cursor:
db2 -td@ +c "BEGIN FOR v AS c1 CURSOR FOR SELECT SCHEMANAME FROM NYA.VALIDATION_SCHEMAS DO CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS(object_schema=>v.schemaname); END FOR; END @"
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0501N The cursor specified in a FETCH statement or CLOSE statement is not
open or a cursor variable in a cursor scalar function reference is not open.
SQLSTATE=24501
Observe que não ajuda conectar o esquema:
db2 -td@ +c "BEGIN FOR v AS c1 CURSOR FOR SELECT SCHEMANAME FROM NYA.VALIDATION_SCHEMAS DO CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS(object_schema=>'TMP')
[...]
também produz um erro. Tentei variações de loop sobre um cursor:
BEGIN
DECLARE s VARCHAR(128);
DECLARE v_at_end INTEGER default 0;
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE C1 CURSOR for
SELECT SCHEMANAME FROM NYA.VALIDATION_SCHEMAS;
DECLARE CONTINUE HANDLER FOR not_found SET v_at_end = 1 ;
OPEN C1;
fetch_loop:
LOOP
FETCH FROM C1 INTO s;
IF v_at_end <>0 THEN LEAVE fetch_loop; END IF;
CALL SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS(object_schema=>s);
END LOOP;
CLOSE C1;
END
@
Mas também não funciona. Alguma pista, o que precisa ser feito para poder chamar ADMIN_REVALIDATE_DB_OBJECTS em um loop?
Portanto, o cursor deve ser declarado
WITH HOLD
para que permaneça válido entre os commits.