Chuleta PL SQL
Chuleta PL SQL
Chuleta PL/SQL
Procedimientos, Funciones, JOINs y Validaciones
1
Índice
5 Tratamiento de excepciones
2
1. Estructuras básicas
Bloque anónimo
Se crea y ejecuta al momento, no se guarda. Útil para probar cosas.
DECLARE
-- aquí declaras variables (opcional)
V_NUM NUMBER := 0;
BEGIN
-- aquí van las instrucciones
DBMS_OUTPUT.PUT_LINE('Hola');
EXCEPTION
-- aquí capturas errores (opcional)
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error');
END;
/
Procedimiento
Hace cosas (INSERT, UPDATE, mostrar mensajes...). No devuelve valor. Se ejecuta con EXECUTE .
-- cómo ejecutarlo:
EXECUTE NOMBRE_PROC(5, 'texto');
Función
Calcula y devuelve un valor con RETURN . Se usa dentro de otras expresiones.
Diferencia clave: la función lleva RETURN tipo en la cabecera y RETURN valor dentro. El procedimiento no devuelve nada. Todo lo
demás es casi igual.
3
Declarar variables
-- entre IS/AS y BEGIN. Una por línea, NO se pueden separar por comas.
V_IMPORTE NUMBER(6,2); -- 6 dígitos, 2 decimales
V_NOMBRE VARCHAR2(30); -- siempre hay que dar tamaño
V_CONTADOR NUMBER := 0; -- inicializada a 0
V_FIJO CONSTANT NUMBER := 100; -- constante, no cambia
IF — condicionales
Simple
IF condición THEN
instrucciones;
END IF;
IF condición THEN
instrucciones;
ELSE
otras instrucciones;
END IF;
IF condición1 THEN
instrucciones1;
ELSIF condición2 THEN -- ojo: ELSIF junto, no "ELSE IF"
instrucciones2;
ELSE
instrucciones3;
END IF;
Bucles
La variable i se crea sola, no la declaras tú, y no se puede usar fuera del bucle.
4
LOOP (con salida manual)
LOOP
instrucciones;
EXIT WHEN condición; -- sale cuando se cumple
END LOOP;
2. Operadores y condiciones
Comparación
<= >= Menor o igual / Mayor o igual WHERE SALARIO >= 600
Condiciones especiales
IS NULL Está vacío / es nulo. Nunca uses = NULL WHERE HABITACION IS NULL
BETWEEN a AND b Entre dos valores (incluidos) WHERE EDAD BETWEEN 18 AND 65
LIKE Patrón de texto. % =varios caracteres, _ =uno WHERE NOMBRE LIKE 'A%'
AND Se tienen que cumplir las dos EDAD > 18 AND SEXO = 'H'
Truco con LIKE: 'A%' empieza por A · '%Z' termina en Z · '%ar%' contiene "ar" · '_a%' tiene una "a" en la 2ª posición.
3. Funciones de SQL
5
UPPER(t) Pasa a MAYÚSCULAS UPPER('hola') → 'HOLA'
INITCAP(t) Primera letra de cada palabra en mayúscula INITCAP('pepe pérez') → 'Pepe Pérez'
Funciones numéricas
MOD es tu amigo: MOD(n,2)=0 → el número es par. MOD(n,2)=1 → impar. También se usa para la letra del DNI.
Funciones de fecha
6
Formatos de TO_CHAR / TO_DATE más usados
¡OJO con el 'D'! En tu Oracle (español) lunes=1, martes=2, miércoles=3, jueves=4, viernes=5, sábado=6, domingo=7. Por eso el fin de
semana es '6' y '7' . Compruébalo siempre con SELECT TO_CHAR(SYSDATE,'D'), TO_CHAR(SYSDATE,'DAY') FROM DUAL;
-- La fecha de hoy:
EXECUTE MI_PROC(SYSDATE);
Conversión de tipos
Patrón clásico: NVL(MAX(EMP_NO),0) + 1 → genera el siguiente número aunque la tabla esté vacía (porque MAX de tabla vacía es NULL, y
NVL lo convierte en 0).
COUNT(*) Cuenta filas. Siempre devuelve un número (0 si no hay nada), nunca da error.
AVG(col) Media
7
4. Conectar varias tablas (JOINs)
Un JOIN sirve para coger datos de varias tablas a la vez, uniéndolas por una columna que tienen en común.
Error "column ambiguously defined": ocurre cuando una columna existe en las dos tablas ([Link]. HABITACION ) y Oracle no sabe de cuál.
Solución: poner el alias delante → [Link] .
Tipos de JOIN
JOIN (INNER) Solo las filas que tienen pareja en las dos tablas
Conectar 3 tablas
Se van encadenando los JOIN, uno detrás de otro. Cada uno une la nueva tabla con alguna de las anteriores.
Cómo pensarlo: mira qué columna comparten dos tablas y únelas por ahí. RESIDENTES y REVISIONES comparten el DNI. REVISIONES y
PERSONAL comparten el código de quien realiza. Vas enlazando como una cadena.
5. Tratamiento de excepciones
Las excepciones sirven para controlar errores y parar el procedimiento de forma limpia.
8
Cómo funcionan (3 pasos)
EXCEPTION
WHEN MI_ERROR THEN -- 3) CAPTURAR y mostrar mensaje
VER('Ya existe ese DNI');
END;
/
Lo bueno del RAISE: cuando se lanza, el procedimiento salta al EXCEPTION y termina ahí. No tienes que hacer nada más para "acabar" el
procedimiento.
EXCEPTION
WHEN NO_DATA_FOUND THEN VER('No hay datos');
WHEN TOO_MANY_ROWS THEN VER('Hay varias filas');
WHEN OTHERS THEN VER('Error inesperado');
El procedimiento VER: es un atajo para mostrar mensajes. Créalo una vez al principio de la sesión:
Ejercicios del examen de la Residencia "Merecido Descanso". Tablas: RESIDENTES, REVISIONES, PERSONAL, HABITACIONES.
9
CREATE OR REPLACE FUNCTION EX_DIA_CORRECTO (PFECHA DATE)
RETURN DATE
IS
BEGIN
-- Si NO cumple alguna condición → NULL
IF PFECHA <= SYSDATE -- no es posterior a hoy
OR TO_CHAR(PFECHA, 'D') IN ('6','7') -- sábado o domingo
OR TO_CHAR(PFECHA, 'MM') = '08' THEN -- agosto
RETURN NULL;
ELSE
RETURN PFECHA; -- todo OK
END IF;
END;
/
Probar:
-- Paso 3: doble con 1 cama ocupada por alguien del mismo sexo
IF V_HAB IS NULL THEN
SELECT MIN([Link]) INTO V_HAB
FROM HABITACIONES H
JOIN RESIDENTES R ON [Link] = [Link]
WHERE [Link] = 2 AND [Link] = 1 AND [Link] = PSEXO;
END IF;
Usamos MIN(HABITACION) para quedarnos con una sola habitación (la primera). Si no hay ninguna, MIN devuelve NULL y no da error.
10
CREATE OR REPLACE PROCEDURE EX_ALTA_RESIDENTE
(PNOMBRE VARCHAR2, PDNI VARCHAR2, PNACIMIENTO DATE, PINGRESO DATE, PSEXO CHAR)
AS
CONTADOR NUMBER;
EDAD NUMBER;
V_HABITACION VARCHAR2(5);
ERROR_DNI EXCEPTION;
ERROR_EDAD EXCEPTION;
ERROR_ING EXCEPTION;
ERROR_SEXO EXCEPTION;
BEGIN
-- 3.1) El DNI no puede existir ya
SELECT COUNT(*) INTO CONTADOR FROM RESIDENTES WHERE DNI = PDNI;
IF CONTADOR > 0 THEN RAISE ERROR_DNI; END IF;
-- 3.3) La fecha de ingreso tiene que ser válida (usamos la función del ej. 1)
IF EX_DIA_CORRECTO(PINGRESO) IS NULL THEN RAISE ERROR_ING; END IF;
-- 3.5) Todo bien → damos de alta (nombre con formato título, sexo en mayúsculas)
INSERT INTO RESIDENTES (DNI, NOMBRE, FECHA_NAC, FECHA_ING, SEXO, TFNO_FAMILIAR, HABITACION, CUOTA_MES)
VALUES (PDNI, INITCAP(PNOMBRE), PNACIMIENTO, PINGRESO, UPPER(PSEXO), NULL, NULL, NULL);
VER('ALTA REALIZADA');
EXCEPTION
WHEN ERROR_DNI THEN VER('ERROR, YA EXISTE EL DNI');
WHEN ERROR_EDAD THEN VER('ERROR, DEMASIADO JOVEN');
WHEN ERROR_ING THEN VER('FECHA DE INGRESO INCORRECTA');
WHEN ERROR_SEXO THEN VER('SEXO NO VALIDO');
END;
/
Probar:
Trozos de código listos para adaptar a lo que te pidan. Casi todos los ejercicios son combinaciones de estos.
11
Validar que un valor está en un rango
IF CONTADOR = 0 THEN
VER('No existe'); -- no hay ninguno
ELSE
VER('Ya existe'); -- hay 1 o más
END IF;
-- 4) Comparamos
IF V_LETRA = V_CORRECTA THEN
RETURN 'DNI correcto';
ELSE
RETURN 'Letra incorrecta, debería ser ' || V_CORRECTA;
END IF;
END;
/
12
Validar un email básico (que contenga @)
IF LENGTH(PTELEFONO) != 9 THEN
VER('El teléfono debe tener 9 dígitos');
END IF;
Validar el sexo (H o M)
13
Recorrer las letras de una cadena (una a una)
BEGIN
SELECT SALARIO INTO V_SAL FROM EMPLE WHERE APELLIDO = PAPELL;
VER('Gana ' || V_SAL);
EXCEPTION
WHEN NO_DATA_FOUND THEN VER('No existe ese empleado');
WHEN TOO_MANY_ROWS THEN VER('Hay varios con ese apellido');
END;
Repasa esta lista antes de entregar. Son los fallos que más se cometen.
Falta el / al final → error "Encountered the symbol BEGIN" Pon / en una línea sola al final de cada bloque PL/SQL
Declarar la variable antes del IS Las variables van entre el IS/AS y el BEGIN
14
Cada IF sin su END IF; Todo IF se cierra con END IF;
Función sin RETURN Una función SIEMPRE devuelve un valor con RETURN
Olvidar INTO en un SELECT dentro de PL/SQL En PL/SQL el SELECT guarda en variables: SELECT ... INTO v ...
Usar SELECT * dentro de PL/SQL Selecciona columnas concretas en variables, o usa MIN/MAX/COUNT
Comparar texto que puede venir en minúsculas Normaliza con UPPER() en los dos lados
Poner el parámetro entre comillas ( 'PINGRESO' ) Sin comillas: PINGRESO . Las comillas lo convierten en texto literal
Aplicar TO_DATE a algo que ya es DATE Si el parámetro ya es DATE, úsalo directo, sin TO_DATE
Intentar ejecutar CREATE y EXECUTE juntos Ejecútalos por separado (selecciona cada uno y dale a ▶)
Bucle WHILE
Procedimiento
WHILE cond LOOP
CREATE OR REPLACE PROCEDURE N (P1 NUMBER) ...
AS END LOOP;
V NUMBER;
BEGIN
... SELECT INTO
END;
/
SELECT col INTO V
FROM tabla
WHERE ...;
Función
IF -- declarar:
MI_ERR EXCEPTION;
-- lanzar:
IF cond THEN
RAISE MI_ERR;
...
-- capturar:
ELSIF cond2 THEN
WHEN MI_ERR THEN ...
...
ELSE
...
END IF;
INSERT / UPDATE / DELETE
15
JOIN de 2 tablas Edad
SET SERVEROUTPUT ON
Material de apoyo PL/SQL · RA5 · Bases de Datos 1º DAW · ¡Mucha suerte en el examen!
16