Sesion07- Estructuras de control (Oracle)
description
Transcript of Sesion07- Estructuras de control (Oracle)
/* Sesión06 – Estructuras de controlEstudiante: José Luis Toro AlcarrazCurso: Base de Datos Avanzado IICorreo:[email protected]*/
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 CASE3) Sentencias LOOP4) 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 -- InstruccionesELSIF (expresion) THEN -- InstruccionesELSE -- InstruccionesEND 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.');
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:
DECLAREV_NUMERO1 NUMBER(4,2):=5;V_NUMERO2 NUMBER(4,2);
BEGINIF 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:
DECLAREv_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.');
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) LOOPb) WHILEc) 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 cicloDECLARE
v_cont_n NUMBER:=0;BEGIN
Dbms_output.put_line('Inicio del Loop : ' || TO_CHAR(sysdate,'HH24:MI:SS'));
LOOPDbms_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 -- InstruccionesEND LOOP;
Ejemplo:
-- Mostrar los números del 1 al 20 si son pares o imparesDECLARE
v_cont_n NUMBER:=1;BEGIN
WHILE v_cont_n <= 20 LOOPIF 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 -- InstruccionesEND LOOP;
Ejemplo:
-- Mostrar los números múltiplos de 3 y/o 5 entre el 1 y el 100 usando FORBEGIN
FOR i IN 1..100 LOOPIF MOD(i,3) = 0 AND MOD(i,5) = 0 THEN
Dbms_output.put_line(i || ' es múltiplo de 3 y de 5.');
ELSIF MOD(I,3) = 0 THENDbms_output.put_line(i || ' es múltiplo de 3.');
ELSIF MOD(I,5) = 0 THENDbms_output.put_line(i || ' es múltiplo de 5.');
ELSEDbms_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 50DECLARE
v_num NUMBER(3);BEGIN FOR v_cont IN 50..100 LOOP
if MOD(v_cont,13) =0 thenv_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;/
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;/
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) LOOPDBMS_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;/