Vous êtes sur la page 1sur 41

ESCRIBIENDO ESTRUCTURAS

DE CONTROL
Controlando el Flujo de Ejecución
 Se puede cambiar la ejecución lógica de las sentencias dentro de un
bloque PL/SQL a través de Estructuras de Control.
 Un estructura de control consta de un punto de entrada y uno de salida.
 Estructuras de control de:
 Selección (Condicional).
 Expresiones CASE y Sentencias CASE
 Iteración
 Secuencia
Controlando el Flujo de Ejecución
 Las Estructuras de Selección verifican cierta condición, después
ejecutan cierta secuencia de expresiones dependiendo si la condición
resultó ser verdadera o falsa. Una condición es cualquier variable o
expresión que retorna un valor booleano (TRUE, FALSE o NULL).
 Expresiones CASE retornan un resultado basado en una o más
alternativas.
 Las Estructuras de Iteración ejecutan una secuencia de sentencias
repetidamente mientras la condición permanezca verdadera.
 Las Estructuras de Secuencia simplemente ejecutan una secuencia de
sentencias en el orden que ocurren.
Controles Condicionales o Selección:
IF

 Sintaxis:

IF condición THEN
setencias;
[ELSIF condición THEN
sentencias;]
[ELSE
sentencias;]
END IF;
Controles Condicionales o Selección:
IF
 condición: Es una variable Booleana o expresión que retorna TRUE,
FALSE o NULL.
 THEN: Asocia la expresión Booleana con la secuencia de instrucciones
que continúan.
 sentencias : Puede ser una o más sentencias PL/SQL o SQL. Las
sentencias son ejecutadas sólo si la condición es evaluada como TRUE.
 ELSIF: Es una palabra que introduce condiciones adicionales si la
primera condición retorna FALSE o NULL.
 ELSE: Introduce la cláusula por defecto que es ejecutada sólo si ninguno
de las condiciones anteriores es TRUE.
 END IF: Marca el fin de una sentencia IF.
Controles Condicionales o Selección:
IF Simple
 Ejemplo: la variable mi_edad es inicializada en 31.La condición de la
sentencia IF retorna FALSE, porque mi_edad no es menor que 11. Por
lo tanto el control nunca alcanza la cláusula THEN.

DECLARE
mi_edad number:=31;
BEGIN
IF mi_edad < 11 THEN
DBMS_OUTPUT.PUT_LINE(' Yo soy un niño');
END IF;
END;
/
Controles Condicionales o Selección:
IF Simple
 Ejemplo: la condición usa el operador AND y por lo tanto esta
condición es evaluada como TRUE sólo si ambas condiciones son
evaluadas como TRUE.

DECLARE
mi_edad number:=11;
mi_nombre varchar2(20):= 'Luis'
BEGIN
IF mi_edad < 11 AND mi_nombre = 'Luis' THEN
DBMS_OUTPUT.PUT_LINE(' Yo soy un niño que se llama Luis';
END IF;
END;
Controles Condicionales o Selección:
IF THEN ELSE
 Ejemplo: se evalúa la condición y si retorna TRUE se mostrará el
mensaje Yo soy un niño, si la condición retorna FALSE entonces el
bloque mostrará el mensaje Yo no soy un niño.

DECLARE
mi_edad number:=31;
BEGIN
IF mi_edad < 11 THEN
DBMS_OUTPUT.PUT_LINE(' Yo soy un niño');
ELSE
DBMS_OUTPUT.PUT_LINE(‘ Yo no soy un niño‘);
END IF;
END;
Controles Condicionales o Selección:
IF-ELSIF-ELSE

DECLARE
myage number:=31;
BEGIN
IF myage < 11 THEN
DBMS_OUTPUT.PUT_LINE('Yo soy un niño ');
ELSIF myage < 20 THEN
DBMS_OUTPUT.PUT_LINE(' Yo soy joven ');
ELSIF myage < 30 THEN
DBMS_OUTPUT.PUT_LINE(' Yo estoy en mis veintes');
ELSIF myage < 40 THEN
DBMS_OUTPUT.PUT_LINE(' Yo estoy en mis treintas');
ELSE
DBMS_OUTPUT.PUT_LINE(' Yo siempre seré joven ');
END IF;
END;
/
Controles Condicionales o Selección:
IF-ELSIF-ELSE
 En el ejemplo anterior: la cláusula IF ahora contiene múltiples ELSIF
cláusulas y un ELSE. Observe que la cláusula ELSIF puede tener
múltiples condiciones de cláusulas ELSE. La condición para ELSIF
son seguidas por la cláusula THEN que es ejecutada si la condición del
ELSIF retorna TRUE. Cuando se tienen múltiples cláusulas ELSIF, si
la primera condición es FALSE o NULL el control cambia a la
siguiente cláusula ELSIF. Las condiciones son evaluadas una a una
desde el comienzo. Si todas la condiciones son FALSE o NULL, las
sentencias in la cláusula ELSE son ejecutadas. La cláusula final ELSE
es opcional.
Valores Nulos en sentencia IF
 Ejemplo: en el ejemplo la variable mi_edad es declarada pero no
inicializada. La condición en la sentencia IF retorna NULL y no TRUE
o FALSE. En este caso, el control se entrega a la sentencia ELSE.

DECLARE
mi_edad number;
BEGIN
IF mi_edad < 11
THEN
DBMS_OUTPUT.PUT_LINE(' Yo soy un niño ');
ELSE
DBMS_OUTPUT.PUT_LINE(' Yo no soy un niño ');
END IF;
END;
/
Expresiones CASE

 Una estructura condicional CASE permite evaluar una expresión y


retornar un valor.
 CASE retorna un resultado basado sobre una o más alternativas
 Para seleccionar el resultado CASE usa expresiones. El valor retornado
por esas expresiones es usada para seleccionar una de las múltiples
alternativas.
Expresiones CASE
 Sintaxis:
CASE selector
WHEN expresión1 THEN resultado1
WHEN expresión2 THEN resultado2
...
WHEN expresiónN THEN resultadoN
[ELSE resultadoN+1]
END;
/

 Para retornar el resultado, la expresión CASE usa un selector y una


expresión cuyo valor es usado para retornar uno de las diferentes
alternativas.
 El selector es seguido de una o más cláusulas WHEN que son chequeadas
secuencialmente.
Expresiones CASE
 El valor del selector determina que resultado se retorna.
 Si el valor del selector es igual al valor de la expresión de la cláusula
WHEN ésta es ejecutada y el resultado es retornado.
 Las cláusulas WHEN contiene condiciones de búsqueda que devuelven
un valor Booelano.
Expresiones CASE
 Ejemplo: el selector calidad determina que la variable valoracion
tendrá el valor ‘Excelente’, ya que la variable calidad se inicializa en
‘A’.
DECLARE
calidad varchar2(1):='A';
valoracion varchar2(20);
BEGIN
valoracion:=
CASE calidad
WHEN 'A' THEN ' Exelente'
WHEN 'B' THEN ' Muy bueno'
WHEN 'C' THEN ' Bueno'
ELSE 'No existe calidad'
END;
DBMS_OUTPUT.PUT_LINE ('Calidad: '|| calidad || ' Valoración ' || valoracion);
END;
/
Expresiones de Búsqueda CASE
 No existe una expresión de testeo
 La cláusula WHEN contiene una expresión que resulta en un valor

Booleano.
Ejemplo:
DECLARE
calidad varchar2(1):='C';
calidad_2 varchar2(1):='C';
valoracion varchar2(20);
BEGIN
valoracion:=
CASE
WHEN calidad = 'A' THEN ' Exelente'
WHEN calidad_2 IN('B','C') THEN ' Bueno'
ELSE 'No existe calidad'
END;
DBMS_OUTPUT.PUT_LINE ('Calidad: '|| calidad_2 || ' Valoración: ' || valoracion);
END;
Expresiones de Búsquedas CASE
 Ejemplo: la variable salida tomará el valor 'Tengo menos de 40' ya
que mi_ edad ha sido inicializada en 31.

DECLARE
mi_edad number:=31;
salida varchar2(40);
BEGIN
salida:=
CASE
WHEN mi_edad <= 20 then 'Tengo menos de 20'
WHEN mi_edad <= 30 then 'Tengo menos de 30'
WHEN mi_edad <= 40 then 'Tengo menos de 40'
WHEN mi_edad <= 50 then 'Tengo menos de 50'
ELSE 'Se me olvidó mi edad fuera de rango'
END;
DBMS_OUTPUT.PUT_LINE(salida);
END;
/
Sentencias CASE
DECLARE
deptid NUMBER;
deptnombre VARCHAR2(20);
emps NUMBER;
jefeid NUMBER:= 108;
BEGIN
CASE jefeid
WHEN 108 THEN
SELECT department_id, department_name
INTO deptid, deptnombre FROM departments
WHERE manager_id=108;
SELECT count(*) INTO emps FROM employees
WHERE department_id=deptid;
WHEN 200 THEN ………………...
END CASE;
DBMS_OUTPUT.PUT_LINE (‘Tú trabajas en el departamento '|| deptname||
' El total es de '||emps ||' empleados en este departamento');
END;
/
Sentencias CASE
 En el ejemplo anterior, se evalúa el valor de la variable jefeid, si es 108
ejecutará las sentencias SELECT, si es 200 ejecutará las otras
sentencias si las hubiera. teniendo presente las siguientes reglas:
 Recordemos que con IF se pueden tener N números de sentencias
PL/SQL en la cláusula THEN y también en la cláusula ELSE. De la
misma manera se pueden incluir sentencias utilizando CASE.
Diferencias entre CASE
 Expresiones CASE:
 Evalúan la condición y retorna un valor.
 Terminan con END.
 Sentencias CASE:
 Evalúan la condición y realiza una acción.
 La sentencia puede ser un bloque completo PL/SQL.
 Terminan con END CASE.
Controlando NULOS
 Al trabajar con valores Nulos, se pueden evitar algunos errores
comunes teniendo presente las siguientes reglas:
 Comparaciones simples que involucran nulos siempre retornan NULL.
 Aplicando el operador lógico NOT para un retorno Nulo (NOT NULL).
 En sentencias de control condicionales, si la condición retorna NULL, la
secuencia de sentencias asociadas no son ejecutadas.
Controlando Nulos
 Ejemplo: la condición retorna NULL no TRUE, por lo tanto la
secuencias de sentencias después del THEN no serán ejecutadas, se
ejecutarán las sentencias después del ELSE.

DECLARE
x NUMBER:= 5;
y NUMBER:= NULL;
BEGIN
IF x != y THEN
DBMS_OUTPUT.PUT_LINE('x es distinto de y');
ELSE
DBMS_OUTPUT.PUT_LINE('x es distinto de y pero la comparación es NULL');
END IF;
END;
/
Controlando Nulos
 Ejemplo: la condición retorna NULL no TRUE, por lo tanto la
secuencias de sentencias después del THEN no serán ejecutadas.

DECLARE
a NUMBER:= NULL;
b NUMBER:= NULL;
BEGIN
IF a = b THEN
DBMS_OUTPUT.PUT_LINE('a es igual a b');
ELSE
DBMS_OUTPUT.PUT_LINE('a es distinto de b pero la comparación es NULL');
END IF;
END;
/
Controlando Nulos
 Ejemplo: la condición pregunta si los valores de las variables son
Nulos o no. Como ambas variables han sido inicializadas NULAS la
sentencia que se ejecutará es después del THEN del ELSIF.
DECLARE
a number:= NULL;
b number:=NULL;
BEGIN
IF a IS NOT NULL AND b IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE('a ni b son nulos');
ELSIF
a IS NULL AND b IS NULL THEN
DBMS_OUTPUT.PUT_LINE('a y b son nulos');
END IF;
END;
/
Tablas de Lógica
Condición simple Booleana con un operador de comparación

AND TRUE FALSE NULL OR TRUE FALSE NULL NOT

TRUE TRUE FALSE NULL TRUE TRUE TRUE TRUE TRUE FALSE

FALSE FALSE FALSE FALSE FALSE TRUE FALSE NULL FALSE TRUE

NULL NULL FALSE NULL NULL TRUE NULL NULL NULL NULL
Controles de Iteración (Bucles):
Sentencia LOOP

for
loop

while
 Los Bucles repiten una sentencia o secuencia de sentencias múltiples
veces. Son usados principalmente para ejecutar sentencias en forma
repetitiva hasta que se cumpla una condición de salida.
 La condición de salida debe existir, de lo contrario el loop será infinito.
 Podemos distinguir tres tipos Bucles:
 LOOP (Básico)
 FOR
 WHILE
Controles de Iteración (Bucles):
Bucle LOOP
 La forma simple de una sentencia LOOP, es el bucle básico o infinito.
Las sentencias van entre las palabras LOOP y END LOOP.
 Cada vez que el flujo de ejecución alcanza o llega a la sentencia END
LOOP el control es retornado a la correspondiente sentencia LOOP
correspondiente.
 Un bucle básico permite la ejecución de sus sentencias a lo menos una
vez.
 Se puede usar la sentencia EXIT para terminar el loop. El control pasa
a la siguiente sentencia después de la sentencia END LOOP.
 Si a la sentencia EXIT se agrega una Condición WHEN significa que
el LOOP se ejecutará hasta que se cumpla la condición.
 Sintaxis:
LOOP
sentencia1;
...
EXIT [WHEN condición];
END LOOP;
Controles de Iteración (Bucles):
Bucle LOOP
Ejemplo:

DECLARE
countryid locations.country_id%TYPE := 'CA';
loc_id locations.location_id%TYPE;
contador NUMBER(2) := 1;
new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO loc_id FROM locations
WHERE country_id = countryid;
LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((loc_id + contador), new_city, countryid);
contador := contador + 1;
EXIT WHEN contador > 3;
END LOOP;
END;
/
Controles de Iteración (Bucles):
Bucles WHILE
 El bucle WHILE permite que las sentencias se repiten mientras la
condición sea verdadera (TRUE).
 La condición en evaluada al comienzo de casa iteración. El loop
termina cuando la condición es FALSE o NULL.
 Sintaxis:

WHILE condición LOOP


sentencia1;
sentencia2;
...
END LOOP;

 condición: es una variable Booleana o expresión.


 sentencia: pueden ser uno o más sentencias PL/SQL o SQL.
Controles de Iteración (Bucles):
Bucles WHILE
Ejemplo:

DECLARE
countryid locations.country_id%TYPE := 'CA';
loc_id locations.location_id%TYPE;
new_city locations.city%TYPE := 'Montreal';
contador NUMBER := 1;
BEGIN
SELECT MAX(location_id) INTO loc_id FROM locations
WHERE country_id = countryid;
WHILE contador <= 3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((loc_id + contador), new_city, countryid);
contador:= contador + 1;
END LOOP;
END;
/
Controles de Iteración (Bucles):
Bucles FOR
 Las iteraciones se efectúan un número finito y conocido de veces.
 El contador no se declara, éste es declarado implícitamente.
 La sintáxis ‘valor_mínimo .. valor_máximo’ es requerida.
 Los límites de una iteración (valor_mínimo y valor_máximo) pueden
ser literales, variables o expresiones, pero que deben evaluarse como
números enteros.
 Sintaxis:
FOR contador IN [REVERSE]
valor_mínimo..valor_máximo LOOP
sentencia1;
sentencia2;
...
END LOOP;
Controles de Iteración (Bucles):
Bucles FOR
 contador: es un entero declarado implícitamente (sólo involucra al
loop y posteriosteriormente se elimina) cuyo valor incrementa o
disminuya de manera automáticamente en uno en cada iteración
del loop hasta que se alcanza el valor_mínimo o valor_máximo.
 REVERSE: causa que el contador disminuya con cada iteración desde el
valor_máximo al valor_mínimo.
 valor_mínimo: específica el valor inferior del rango de valores del contador.
 valor_maximo: especifica el valor superior del rango de valores del contador.
Controles de Iteración (Bucles):
Bucles FOR
Ejemplo:

DECLARE
countryid locations.country_id%TYPE := 'CA';
loc_id locations.location_id%TYPE;
new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO loc_id
FROM locations
WHERE country_id = countryid;
FOR i IN 1..3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((loc_id + i), new_city, countryid );
END LOOP;
END;
/
Controles de Iteración (Bucles):
Bucles FOR
Ejemplo:

DECLARE
inferior NUMBER:=1;
superior NUMBER:=100;
loc_id locations.location_id%TYPE;
BEGIN
SELECT MAX(location_id) INTO loc_id
FROM locations
WHERE country_id = countryid;
FOR i IN inferior..superior LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((loc_id + i), new_city, countryid );
END LOOP;
END;
/
Pautas para el uso de Bucles
 Usar bucles básico cuando las sentencias contenidas dentro del bucle
deben ser ejecutas a lo menos una vez.
 Usar bucle WHILE si la condición tiene que ser evaluada al comienzo
de cada iteración.
 Usar bucle FOR si el número de iteraciones es conocido
Bucles Anidados y Etiquetas
 Los loops anidados tienen múltiples niveles.
 El uso de etiquetas permiten distinguir entre bloques y loops.
 Salir al loop externo con la sentencia EXIT que referencia la etiqueta.
Bucles Anidados y Etiquetas
DECLARE
contador NUMBER;
total_done VARCHAR2(3):='NO';
inner_done VARCHAR2(3):='YES';
BEGIN
<<loop_externo>>
LOOP
contador := contador+1;
EXIT WHEN contador>10;
<<loop_interno>>
LOOP
total_done:='YES';
EXIT loop_externo WHEN total_done = 'YES';
-- Sale de ambos loops
EXIT WHEN inner_done = 'YES';
-- Sale solamente del loop interno
END LOOP loop_interno;
END LOOP loop_externo;
END;
Controles de Secuencia:
Sentencias GOTO y NULL
 Ocasionalmente podría ser útil el uso de una sentencia de este tipo.
 La sentencia GOTO obliga a saltar a una etiqueta del programa en
forma incondicional.
 Cuando es ejecutada la sentencia GOTO ésta transfiere el control a la
sentencia o bloque etiquetada.
 Una sentencia GOTO no puede saltar dentro de una sentencia IF,
LOOP o un sub-bloque.
 GOTO no se puede utilizar dentro del bloque de excepciones para salir
de él.
 La sentencia NULL especifica explícitamente inacción.
 La sentencia NULL pasa el control del programa a la siguiente
sentencia.
Controles de secuencia:
Sentencias GOTO y NULL
Ejemplos:

BEGIN

<<actualiza>>
BEGIN
UPDATE employees SET…

END;

GOTO <<<actualiza>>

END;
Controles de secuencia:
Sentencias GOTO y NULL
Ejemplo No Válido:

DECLARE
done BOOLEAN;
BEGIN

FOR i IN 1..50 LOOP
IF done THEN GOTO fin_loop;
END IF;

<<fin_loop>> -- Ilegal
END LOOP; -- Esta no es una sentencia ejecutable
END;
Controles de secuencia:
Sentencias GOTO y NULL
Ejemplos:

EXCEPTION
WHEN zero_divide THEN
Rollback;
WHEN value_error THEN
INSERT INTO errores VALUES…
Commit;
WHEN others THEN
NULL;
END;

Vous aimerez peut-être aussi