Mostrando las entradas para la consulta loop ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas
Mostrando las entradas para la consulta loop ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas

jueves, 18 de septiembre de 2014

Bucles

En programación, un Bucle es un tipo de estructura de control que permite repetir una o más sentencias múltiples veces. Todos los bucles se ejecutan mientras se cumpla una determinada condición , mientras esa condición sea verdadera, el bucle seguirá ejecutándose.

En PL/SQL tenemos a nuestra disposición los siguientes  bucles:
  • LOOP
  • WHILE
  • FOR

LOOP
El bucle LOOP, se repite tantas veces como sea necesario hasta que se fuerza su salida con la instrucción EXIT. Las sentencias dentro del bucle se ejecutarán durante un número indefinido de veces. Este tipo de bucle se denomina bucle incondicional.

LOOP
    -- Instrucciones
      IF (expresion) THEN
    -- Instrucciones
    EXIT;
      END IF;
   END LOOP;


WHILE
Un tipo de bucle más común son los bucles condicionales.  El bucle WHILE, se repite mientras  que se cumpla cierta condición.

WHILE (condicion) LOOP
      -- Instrucciones
  END LOOP;

FOR
El bucle FOR, se repite tanta veces como le indiquemos en  las variables de contador. Este contador deberá ser una variable de tipo numérico que sea capaz de contener los valores comprendidos entre limite_inferior y limite_superior, los cuales deberán ser expresiones numéricas, ya sean constantes (1,10…) o funciones (ROUND(max,0), ASCII(‘A’)…) .

FOR contador IN [REVERSE] inicio..final LOOP
       -- Instrucciones
 END LOOP;

En el caso de especificar REVERSE el bucle se recorre en sentido inverso.

LOOPS en 11G
En la versión 11g  podemos cancelar la iteración del loop actual y pasar a la siguiente, sin abortar el loop. Puede usarse simplemente CONTINUE o CONTINUE WHEN. En este último caso podremos evitar el uso de la sentencia IF para controlar la condición de salida de la iteración.

BEGIN
   LOOP
     ...
    CONTINUE WHEN condicion;  --vuelve al comienzo del loop
    -- si condicion=true, esta parte no se ejecuta
    ...
   END LOOP;
 END;

La ventaja de de usar este código  es que cualquier sentencia que se encuentre dentro del bucle entre el CONTINUE y el END LOOP no será ejecutada. Al no validar un caso termina el registro y pasa al siguiente registro del contador. Así facilitamos código y mejoramos el tiempo de lecturas. 

LOOP
  EXIT WHEN condicion;
  i:=i+1;
 
  var1 := getdata(i);
  CONTINUE WHEN NOT var1;

  var2 := convertdata(i);
  CONTINUE WHEN NOT var2;
  ....
  procesoRegistro(i);
 
END LOOP;

jueves, 22 de enero de 2015

Crear Bucle en un bloque de Oracle Forms

Cuando creamos un formulario podemos tener un Bloque de Datos donde podremos diseñar un Bloque Tabular con varios listados de columnas de información. Este tipo de diseño se hace de forma que se quiera consultar y actualizar información por varios registros al mismo tiempo.



Para realizar un proceso que trabaje con todos los registros consultados en pantalla debemos crear un bucle o loop. Con el bucle podremos realizar cualquier tarea por cada registro del bloque de datos. Para ello podemos usar el siguiente script el cual lo podemos ubicar en un proceso de nuestro formulario.

BEGIN

FIRST_RECORD;

 LOOP

     /*-- INGRESAR CODIGO POR REGISTRO --*/
                            
   IF :SYSTEM.LAST_RECORD = 'TRUE' THEN
     EXIT;
   ELSE
     NEXT_RECORD;
   END IF;

 END LOOP;

 END;

Los procedimientos empaquetados restringidos (PER) afectan a la navegación dentro del formulario. En ellos se incluyen los built-ins que mueven el foco de la aplicación de un ítem a otro como por ejemplo: Con el comando FIRST_RECORD indicamos al formulario ubicarse en el primer registro. Cada vez que el bucle regrese debemos colocarle NEXT_RECORD antes de finalizar el loop para que pase al siguiente registro. 

Con  LAST_RECORD sabremos si nos ubicaremos en el ultimo registro es por ello que lo usamos  dentro de una condicional para saber de que si estamos en el ultimo registro con EXIT salimos del bucle.

miércoles, 26 de marzo de 2014

Inventory API - Para asignar articulos a almacenes de inventarios

El día de hoy quiero compartir un script donde uso un API para asignar artículos a almacenes de inventarios. Es un ejemplo sencillo con un articulo pero puede utilizarse una tabla temporal que ayude cargar masivamente varios artículos. Sin duda es muy útil si necesita realizar una asignación a varios artículos y varios almacenes.

/* Script de API para asginar artiuclos de inventarios */
  
DECLARE
   g_user_id         fnd_user.user_id%TYPE     := NULL;
   l_appl_id         fnd_application.application_id%TYPE;
   l_resp_id         fnd_responsibility_tl.responsibility_id%TYPE;
   l_api_version     NUMBER  := 1.0;
   l_init_msg_list   VARCHAR2 (2)    := fnd_api.g_false;
   l_commit          VARCHAR2 (2)   := fnd_api.g_false;
   x_message_list    error_handler.error_tbl_type;
   x_return_status   VARCHAR2 (2);
   x_msg_count       NUMBER:= 0;
   l_error_msg       VARCHAR2(1000);
   l_organization_id   NUMBER  := 0;
   
BEGIN

   SELECT fa.application_id
     INTO l_appl_id
     FROM fnd_application fa
    WHERE fa.application_short_name = 'INV';

   SELECT fr.responsibility_id
     INTO l_resp_id
     FROM fnd_application fa, fnd_responsibility_tl fr
    WHERE fa.application_short_name = 'INV'
      AND fa.application_id = fr.application_id
      AND UPPER (fr.responsibility_name) = 'INVENTORY';
     
       SELECT organization_id
       into l_organization_id
        FROM mtl_parameters
        WHERE ORGANIZATION_CODE ='P7U';--almacén a asignar

   fnd_global.apps_initialize (g_user_id, l_resp_id, l_appl_id);
   
   FOR r1 IN (
            SELECT inventory_item_id FROM mtl_system_items_B
WHERE SEGMENT1||'.'||SEGMENT2||'.'||SEGMENT3||'.'||SEGMENT4='&inventory_item'
AND ORGANIZATION_ID IN ( SELECT organization_id
        FROM mtl_parameters
     WHERE master_organization_id = organization_id
       AND nvl(ATTRIBUTE11, 'N') = 'Y')        
            )---ejemplo cargamos un articulo, puede usar una tabla temporal
   LOOP
   --El API  se activa por cada articulo ingresado para asignar
 ego_item_pub.assign_item_to_org (p_api_version        => l_api_version,
                                  p_inventory_item_id  => r1.inventory_item_id,
                                    p_organization_id  => l_organization_id,
                                    x_return_status    => x_return_status,
                                    x_msg_count        => x_msg_count
                                   );
   COMMIT;
   
l_error_msg := 'Status: ' || x_return_status||' for inventory item id : '||r1.inventory_item_id;
   DBMS_OUTPUT.put_line (l_error_msg);
   
       IF (x_return_status <> fnd_api.g_ret_sts_success)
       THEN
          DBMS_OUTPUT.put_line ('Error Messages :');--Mensajes de errores del api
          error_handler.get_message_list (x_message_list => x_message_list);

          FOR j IN 1 .. x_message_list.COUNT
          LOOP
             DBMS_OUTPUT.put_line (x_message_list (j).MESSAGE_TEXT);
          END LOOP;
       END IF;
   END LOOP;
   DBMS_LOCK.SLEEP(6);   --se coloca una espera de 6 segundos para procesar
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('Exception Occured :');
      DBMS_OUTPUT.put_line (SQLCODE || ':' || SQLERRM);

END;