El documento presenta los objetivos de la sesión 06 sobre estructuras de control en PL/SQL. Explica el uso de las estructuras condicionales IF y CASE, así como los bucles LOOP, WHILE y FOR. También cubre la sentencia GOTO. Finalmente, proporciona ejemplos de problemas y su solución utilizando estas estructuras de control.
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
Sesion07- Estructuras de control (Oracle)
1. /*
Sesión06 – Estructuras de control
Estudiante: José Luis Toro Alcarraz
Curso: Base de Datos Avanzado II
Correo:i201010865@cibertec.edu.pe
*/
Objetivos de la sesión.
Usar adecuadamente las estructuras de control IF.
Usar adecuadamente las estructuras de control LOOP.
1) Control de Flujo en bloques PL/SQL (Estructuras de control)
2) Uso de CASE
3) Sentencias LOOP
4) Sentencia GOTO
1) Control de Flujo en bloques PL/SQL (Estructuras de control)
En PL/SQL solo disponemos de la estructura condicional IF. Su sintaxis se muestra a continuación:
IF (expresion) THEN
-- Instrucciones
ELSIF (expresion) THEN
-- Instrucciones
ELSE
-- Instrucciones
END IF;
a) Sentencia IF – THEN – ELSE
Es similar a la estructura de la sentencia IF de otros lenguajes.
Permite a PL/SQL realizar acciones en forma selectiva, dependiendo de las condiciones
que se cumplen.
Las cláusulas ELSIF y ELSE son opcionales, y puede haber tantas cláusulas ELSIF como
se desee.
Ejemplo:
DECLARE
v_comision number(4,2):=10;
BEGIN
IF v_comision IS NULL THEN
dbms_output.put_line('La comisión es nula');
ELSIF v_comision > 0 THEN
dbms_output.put_line('Comisión es mayor a cero');
ELSIF v_comision < 0 THEN
dbms_output.put_line('Comisión es negativa');
ELSE
dbms_output.put_line('Comisión es cero.');
2. END IF;
END;
/
Recomendaciones:
Cualquier comparación simple que contenga un valor nulo retorna NULL como resultado.
Una comparación IS NULL retorna como resultado TRUE o FALSE.
La negación de un valor nulo retorna NULL como resultado, puesto que los valores nulos
son indeterminados.
Ejemplo2:
DECLARE
V_NUMERO1 NUMBER(4,2):=5;
V_NUMERO2 NUMBER(4,2);
BEGIN
IF V_NUMERO1<> V_NUMERO2 THEN
dbms_output.put_line('SON DIFERENTES');
ELSE
dbms_output.put_line('SON IGUALES');
END IF;
END;
/
Nota: Un aspecto a tener en cuenta es que la instrucción condicional anidada es ELSIF y no
"ELSE IF".
2) Uso de CASE
La instrucción CASE permite realizar una ejecución condicional, al igual que la instrucción IF, sin
embargo la instrucción CASE se adapta especialmente bien a las condiciones que implican
numerosas opciones diferentes. Además el uso del CASE puede mejorar el rendimiento durante la
ejecución.
Ejemplo1:
DECLARE
v_comision number(4,2);
BEGIN
CASE
WHEN v_comision IS NULL THEN
dbms_output.put_line('La comisión es nula');
WHEN v_comision > 0 THEN
dbms_output.put_line('Comisión es mayor a cero');
WHEN v_comision < 0 THEN
dbms_output.put_line('Comisión es negativa');
ELSE
dbms_output.put_line('Comisión es cero.');
3. END CASE;
END;
/
Ejemplo2:
DECLARE
v_comision number(4,2);
BEGIN
CASE v_comision
WHEN NULL THEN
dbms_output.put_line('La comisión es nula');
WHEN 10 THEN
dbms_output.put_line('Comisión es diez');
WHEN 20 THEN
dbms_output.put_line('Comisión es veinte');
ELSE
dbms_output.put_line('Comisión no es ni 10 ni 20.');
END CASE;
END;
/
3) Sentencias LOOP
En PL/SQL tenemos a nuestra disposición los siguientes iteradores o bucles:
a) LOOP
b) WHILE
c) FOR
a) Bucle LOOP.
El bucle LOOP, se repite tantas veces como sea necesario hasta que se fuerza su salida con la
instrucción EXIT. Su sintaxis es la siguiente.
LOOP
-- Instrucciones
IF (expresion) THEN
-- Instrucciones
EXIT;
END IF;
END LOOP;
Ejemplo:
-- Mostrar el valor de un contador en cada ciclo
DECLARE
v_cont_n
NUMBER:=0;
BEGIN
Dbms_output.put_line('Inicio del Loop : ' || TO_CHAR(sysdate,'HH24:MI:SS'));
4. LOOP
Dbms_output.put_line('El contador es : ' || v_cont_n);
v_cont_n := v_cont_n + 1;
EXIT WHEN v_cont_n = 20;
END LOOP;
Dbms_output.put_line('Fin del Loop : ' || TO_CHAR(sysdate,'HH24:MI:SS'));
END;
/
b) Bucle WHILE.
El bucle WHILE, se repite mientras que se cumpla la expresión su sintaxis es la siguiente.
WHILE (expresion) LOOP
-- Instrucciones
END LOOP;
Ejemplo:
-- Mostrar los números del 1 al 20 si son pares o impares
DECLARE
v_cont_n
NUMBER:=1;
BEGIN
WHILE v_cont_n <= 20 LOOP
IF MOD(v_cont_n,2) = 0 THEN
Dbms_output.put_line(v_cont_n || ' es par.');
ELSE
Dbms_output.put_line(v_cont_n || ' es impar.');
END IF;
v_cont_n := v_cont_n + 1;
END LOOP;
END;
/
c) Bucle FOR.
El bucle FOR, se repite tanta veces como le indiquemos en los identificadores inicio y final.
En el caso de especificar REVERSE el bucle se recorre en sentido inverso.
FOR contador IN [REVERSE] inicio..final LOOP
-- Instrucciones
END LOOP;
Ejemplo:
-- Mostrar los números múltiplos de 3 y/o 5 entre el 1 y el 100 usando FOR
BEGIN
FOR i IN 1..100 LOOP
IF MOD(i,3) = 0 AND MOD(i,5) = 0 THEN
Dbms_output.put_line(i || ' es múltiplo de 3 y de 5.');
5. ELSIF MOD(I,3) = 0 THEN
Dbms_output.put_line(i || ' es múltiplo de 3.');
ELSIF MOD(I,5) = 0 THEN
Dbms_output.put_line(i || ' es múltiplo de 5.');
ELSE
Dbms_output.put_line(i || ' no es múltiplo ni de 3 ni de 5.');
END IF;
END LOOP;
END;
/
4) Sentencia GOTO.
PL/SQL dispone de la sentencia GOTO. La sentencia GOTO desvía el flujo de ejecución a una
determinada etiqueta. En PL/SQL las etiquetas se indican del siguiente modo: << etiqueta >>
Ejemplo1:
DECLARE
FLAG NUMBER;
BEGIN
FLAG :=1 ;
IF (FLAG = 1) THEN
GOTO PASO2;
END IF;
<<PASO1>>
DBMS_OUTPUT.PUT_LINE('EJECUCION DE PASO 1');
<<PASO2>>
DBMS_OUTPUT.PUT_LINE('EJECUCION DE PASO 2');
END;
/
Ejemplo2:
-- Encontramos el primer múltiplo de 13 mayor que 50
DECLARE
v_num NUMBER(3);
BEGIN
FOR v_cont IN 50..100 LOOP
if MOD(v_cont,13) =0 then
v_num := v_cont;
dbms_output.new_line;
GOTO bloque1;
End If;
END LOOP;
<<BLOQUE1>>
dbms_output.put_line(' Primer múltiplo de 13 : ' || v_num);
END;
/
6. Algunos problemas:
Problema1: programa actualiza la comisión de un empleado. El programa debe recibir el código
del empleado, a ese empleado le deben asignar como comisión el 5% de toda las ventas que ha
realizado.
SQL>
DECLARE
V_EMPNO EMP.EMPNO%TYPE:=7900;
V_TOTAL NUMBER(10,2);
BEGIN
SELECT SUM(TOTAL) INTO V_TOTAL
FROM ORD
WHERE EMPNO=V_EMPNO;
UPDATE EMP
SET COMM = V_TOTAL*0.05
WHERE EMPNO=V_EMPNO;
END;
/
Problema2: Modifica el problema anterior sabiendo que si el total de ventas es menor a 3000 no
asigno comisión, sin son entre 3000 y 5000 comisionas el 3%, si vendes más de 5000 es el 5%.
SQL>
DECLARE
V_EMPNO EMP.EMPNO%TYPE:=7900;
V_TOTAL NUMBER(10,2);
V_PORCENTAJE NUMBER(4,2);
BEGIN
SELECT SUM(TOTAL) INTO V_TOTAL
FROM ORD
WHERE EMPNO=V_EMPNO;
IF V_TOTAL < 3000 THEN
V_PORCENTAJE:=0;
ELSIF V_TOTAL >= 3000 AND V_TOTAL <= 5000 THEN
V_PORCENTAJE:=0.03;
ELSE
V_PORCENTAJE:=0.05;
END IF;
UPDATE EMP
SET COMM = V_TOTAL*V_PORCENTAJE
WHERE EMPNO=V_EMPNO;
END;
/
7. Problema3: Imprimir el calendarios del mes de marzo del 2012.
SQL>
DECLARE
V_FECHA DATE:=TRUNC(SYSDATE,'MM');
BEGIN
WHILE V_FECHA <= LAST_DAY(SYSDATE) LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(V_FECHA,'DAY DD MONTH YYYY'));
V_FECHA:=V_FECHA + 1;
END LOOP;
END;
/
Problema4: Programa que reciba una cadena y que imprima la cadena invertía.
SQL>
DECLARE
V_CADENA VARCHAR2(50):='CIBERTEC';
V_REVERSA VARCHAR2(50);
V_POSICION NUMBER(2);
BEGIN
V_POSICION:=LENGTH(V_CADENA);
WHILE V_POSICION >=1 LOOP
V_REVERSA:=V_REVERSA || SUBSTR(V_CADENA,V_POSICION,1);
V_POSICION := V_POSICION - 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(V_REVERSA);
END;
/