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.