sql >> Base de Datos >  >> RDS >> Oracle

oracle ejecuta inmediatamente no se ejecuta sin ningún error

La razón por la que su código no hace nada es esta:

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

Estás probando para c1%ROWCOUNT antes de haber ejecutado una búsqueda. Entonces su valor es 0; Supongo que p_SCBCount no es cero en ese punto (porque lo inicializó a algún valor en el bloque DECLARE) para que la prueba se evalúe como verdadera y el programa salga.

Alternativamente, el problema es este:

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

No podemos usar FOR ... IN con un cursor explícito. Has abierto el cursor. Entonces el FOR intenta abrirlo de nuevo, lo que arroja ORA-06511: PL/SQL: cursor already open . Si no ve este error, debe tener un controlador de excepciones que lo suprima (p. ej., WHEN others then null; ).

Básicamente, el bucle externo es completamente innecesario y debe descartarlo.

El control de bucle explícito rara vez es necesario:solo use FOR ... IN construya y deje que Oracle controle el flujo.

También es innecesario todo el SQL dinámico. SQL funciona con variables, por lo que solo necesita escribir SQL estático que haga referencia a los atributos del cursor:

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

No estoy seguro del propósito de c1%ROWCOUNT <> p_SCBCount . Mi corazonada es que es superfluo, porque el FOR LOOP controla las búsquedas con precisión. De hecho, sospecho que lo agregó para evitar los efectos secundarios de los bucles anidados; y sospecho que solo introdujo los bucles anidados porque su código original lanzó PLS-00376: illegal EXIT/CONTINUE statement; it must appear inside a loop (solo una suposición descabellada).

Sin embargo, si sirve para implementar alguna lógica comercial genuina, puede agregarla al ciclo de alguna manera.