Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle Execute Instant wird nicht ohne Fehler ausgeführt

Der Grund, warum Ihr Code nichts tut, ist folgender:

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

Sie testen auf c1%ROWCOUNT bevor Sie einen Abruf ausgeführt haben. Sein Wert ist also 0; Ich vermute p_SCBCount ist an diesem Punkt nicht null (weil Sie es im DECLARE-Block auf einen Wert initialisiert haben), sodass test als wahr ausgewertet wird und das Programm beendet wird.

Alternativ ist das Problem folgendes:

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

Wir können den FOR ... IN nicht verwenden mit einem expliziten Cursor. Sie haben den Cursor geöffnet. Dann das FOR versucht, es erneut zu öffnen, was ORA-06511: PL/SQL: cursor already open auslöst . Wenn Sie diesen Fehler nicht sehen, müssen Sie einen Ausnahmehandler haben, der ihn unterdrückt (z. B. WHEN others then null; ).

Grundsätzlich ist die äußere Schleife völlig unnötig und Sie sollten sie verwerfen.

Eine explizite Schleifensteuerung ist selten erforderlich:Verwenden Sie einfach den FOR ... IN konstruieren und Oracle den Ablauf kontrollieren lassen.

Auch unnötig ist das ganze dynamische SQL. SQL arbeitet mit Variablen, also müssen Sie nur statisches SQL schreiben, das auf die Cursorattribute verweist:

 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); 

Ich bin mir über den Zweck von c1%ROWCOUNT <> p_SCBCount nicht sicher . Meine Vermutung ist, dass es überflüssig ist, weil die FOR LOOP steuert die Fänge präzise. Tatsächlich vermute ich, dass Sie es hinzugefügt haben, um die Nebenwirkungen der verschachtelten Schleifen zu vermeiden. und ich vermute, Sie haben die verschachtelten Schleifen nur eingeführt, weil Ihr ursprünglicher Code geschleudert wurde PLS-00376: illegal EXIT/CONTINUE statement; it must appear inside a loop (nur eine wilde Vermutung).

Wenn es jedoch dazu dient, eine echte Geschäftslogik zu implementieren, können Sie es irgendwie in die Schleife einfügen.