Problemi e risposte sul DBMS più in auge del momento.
Sommario
ORA-01002
Descrizione:
Recupero fuori sequenza (Fetch out sequence)
Descrizione
Questo errore significa che è stato tentato un recupero o prelievo (fetch) da un cursore che non è più valido. Si noti che durante un ciclo PL / SQL il cursore viene prelevato implicitamente, e quindi può anche causare questo errore. C’è una serie di possibili cause di questo errore, tra cui:
- Recupero da un cursore dopo che l’ultima riga è stata recuperata e viene resitituito l’errore ORA-01403.
- Se il cursore è stato aperto con la clausola FOR UPDATE, il recupero tentato dopo che un COMMIT è stato emesso, restituirà l’errore.
- Si sono ricollegati (binding) tutti i segnaposto (placeholders) nell’istruzione SQL, quindi si è tentato un recupero prima di rieseguire la dichiarazione.
Azioni:
- Assicurarsi che il programma non lanci un recupero dopo che l’ultima riga è stata recuperata – non ci sono più righe da poter prelevare.
- Assicurarsi che il programma Non emetta un COMMIT all’interno di un ciclo di recupero su un cursore che è stato aperto FOR UPDATE.
- Rieseguire l’istruzione dopo rebinding, quindi tentare di recuperare di nuovo.
Scenario
La mia applicazione spedisce SMS; in sostanza carico in una tabella di uno schema Oracle il numero a cui inviare l’SMS assieme al testo e ad altre informazioni che si trovano in un altro schema. Poi una logica di tipo Mirth effettua periodicamente la lettura del buffer, la scrittura nel sistema di spedizione e l’aggiornamento delle righe consegnate attivando un flag “spedito”.
L’errore avviene durante il caricamento del buffer, questo lo scheletro dell’applicazione:
CURSOR c_numbers IS SELECT numbers FROM tabella_appuntamenti
SAVEPOINT sp_sms_transfer;
-- POPOLO IL BUFFER
FOR r_sms IN
(
SELECT
{dati sul motivo della spedizione e sull'UO interessata all'avviso}
FROM
tabella_appuntamenti
)
LOOP BEGIN
INSERT INTO buffer
(
numero,
messaggio,
{altri dati per consistenza trasmissione}
)
SELECT
r_sms.numero,
r_sms.messaggio,
r_sms.{altri dati per consistenza trasmissione}
FROM
dual;
EXCEPTION
WHEN OTHERS THEN ROLLBACK TO sp_sms_transfer;
END;
END LOOP;
-- INFORMO LA SORGENTE DELL'AVVENUTA CONSEGNA AL SISTEMA DI SPEDIZIONE
FOR r_numeri IN c_numbers
LOOP BEGIN
INSERT INTO INVII
(numero, data)
VALUES
(r_numeri.numero, SYSDATE);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE
INVII
SET
data = SYSDATE
WHERE
1 = 1
AND numero = r_numeri.numero
END;
END LOOP;
Il problema è quando a causa di una eccezione il controllo del programma esce da un ciclo interrompendolo; come soluzione temporanea per sbloccare la situazione ho commentato la riga che esegue il rollback dall’interno del ciclo.
Commenti recenti