Return to Database

Oracle

Spread the love


Problemi e risposte sul DBMS più in auge del momento.

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:

  1. Recupero da un cursore dopo che l’ultima riga è stata recuperata e viene resitituito l’errore ORA-01403.
  2. Se il cursore è stato aperto con la clausola FOR UPDATE, il recupero tentato dopo che un COMMIT è stato emesso, restituirà l’errore.
  3. Si sono ricollegati (binding) tutti i segnaposto (placeholders) nell’istruzione SQL, quindi si è tentato un recupero prima di rieseguire la dichiarazione.

 Azioni:

  1. Assicurarsi che il programma non lanci un recupero dopo che l’ultima riga è stata recuperata – non ci sono più righe da poter prelevare.
  2. Assicurarsi che il programma Non emetta un COMMIT all’interno di un ciclo di recupero su un cursore che è stato aperto FOR UPDATE.
  3. 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.

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.