Oracle
 sql >> Database >  >> RDS >> Oracle

oracle execute immediato non in esecuzione senza alcun errore

Il motivo per cui il tuo codice non fa nulla è questo:

OPEN c1;
 LOOP
  EXIT WHEN c1%NOTFOUND;   
  EXIT WHEN (c1%ROWCOUNT <> p_SCBCount);

Stai testando c1%ROWCOUNT prima di aver eseguito un recupero. Quindi il suo valore è 0; Immagino p_SCBCount non è zero a quel punto (perché l'hai inizializzato su un valore nel blocco DECLARE) in modo che test restituisca true e il programma esca.

In alternativa il problema è questo:

OPEN c1;
 LOOP
   ...
   FOR i in c1 LOOP

Non possiamo usare FOR ... IN con un cursore esplicito. Hai aperto il cursore. Quindi il FOR prova ad aprirlo di nuovo che lancia ORA-06511: PL/SQL: cursor already open . Se non visualizzi questo errore devi avere un gestore di eccezioni che lo sopprima (ad es. WHEN others then null; ).

Fondamentalmente il ciclo esterno non è completamente necessario e dovresti scartarlo.

Il controllo esplicito del ciclo è raramente necessario:basta usare FOR ... IN costruire e lasciare che Oracle controlli il flusso.

Inoltre non è necessario tutto l'SQL dinamico. SQL funziona con le variabili, quindi devi solo scrivere SQL statico che fa riferimento agli attributi del cursore:

 FOR i in (SELECT crs_cust.CUSTOMER_ID AS CUSTOMER_ID
                 , subset.NEW_CUSTOMER_REFERENCE_ID AS CUSTOMER_REF_ID 
           FROM CRS_CUSTOMERS crs_cust 
           INNER JOIN  DAY0_SUBSET subset
           ON crs_cust.CUSTOMER_ID=subset.CURRENT_CUSTOMER_ID )
 LOOP
     UPDATE CRS_CUSTOMERS 
     SET REF_ID = i.CUSTOMER_REF_ID
     WHERE CUSTOMER_ID = i.CUSTOMER_ID; 
     p_TotalUpdatedCRS := p_TotalUpdatedCRS + 1;

     UPDATE CRS_REVIEWS
     SET REF_ID =  i.CUSTOMER_REF_ID
     WHERE CUSTOMER_ID =  i.CUSTOMER_ID; 

     UPDATE CRS_EVENT 
     SET REF_ID = i.CUSTOMER_REF_ID 
     WHERE UNIQUE_ID = i.CUSTOMER_ID;

     UPDATE ALERT_HEADER 
     SET CUSTOMER_SOURCE_REF_ID = i.CUSTOMER_REF_ID 
     WHERE CUSTOMER_ID = i.CUSTOMER_ID; 
END LOOP;
DBMS_OUTPUT.PUT_LINE ('The total updates to CRS table = ' || p_TotalUpdatedCRS); 

Non sono sicuro dello scopo di c1%ROWCOUNT <> p_SCBCount . La mia impressione è che sia superfluo, perché il FOR LOOP controlla i recuperi con precisione. In effetti, sospetto che tu l'abbia aggiunto per evitare gli effetti collaterali dei loop nidificati; e sospetto che tu abbia introdotto i loop annidati solo perché il codice originale è stato lanciato PLS-00376: illegal EXIT/CONTINUE statement; it must appear inside a loop (solo un'ipotesi folle).

Tuttavia, se serve per implementare una vera logica aziendale, puoi aggiungerla al ciclo in qualche modo.