0% encontró este documento útil (0 votos)
2 vistas16 páginas

Chuleta PL SQL

El documento es una guía sobre PL/SQL que cubre estructuras básicas, funciones SQL, JOINs, manejo de excepciones y validaciones. Incluye ejemplos prácticos, ejercicios resueltos y patrones comunes en programación. Es un material de apoyo para el examen de Oracle SQL Developer.

Cargado por

196misteryos4
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
2 vistas16 páginas

Chuleta PL SQL

El documento es una guía sobre PL/SQL que cubre estructuras básicas, funciones SQL, JOINs, manejo de excepciones y validaciones. Incluye ejemplos prácticos, ejercicios resueltos y patrones comunes en programación. Es un material de apoyo para el examen de Oracle SQL Developer.

Cargado por

196misteryos4
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

B A S E S D E D AT O S · 1 º D AW

Chuleta PL/SQL
Procedimientos, Funciones, JOINs y Validaciones

Estructuras básicas Funciones SQL JOINs Excepciones Validaciones

Material de apoyo para examen · RA5


Oracle · SQL Developer

1
Índice

1 Estructuras básicas (procedimiento, función, variables, IF, bucles)

2 Operadores y condiciones (para WHERE e IF)

3 Funciones de SQL (cadenas, números, fechas, conversión)

4 Conectar varias tablas: JOINs

5 Tratamiento de excepciones

6 Los 3 ejercicios resueltos del examen

7 Ejemplos de validaciones típicas

8 Patrones útiles que se repiten

9 Errores típicos a revisar

10 Chuleta rápida de sintaxis

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 .

CREATE OR REPLACE PROCEDURE NOMBRE_PROC (PPARAM1 NUMBER, PPARAM2 VARCHAR2)


AS -- AS o IS, da igual
V_VARIABLE NUMBER; -- variables (opcional)
BEGIN
-- instrucciones
EXCEPTION -- opcional
-- captura de errores
END;
/

-- cómo ejecutarlo:
EXECUTE NOMBRE_PROC(5, 'texto');

Función
Calcula y devuelve un valor con RETURN . Se usa dentro de otras expresiones.

CREATE OR REPLACE FUNCTION NOMBRE_FUNC (PPARAM DATE)


RETURN NUMBER -- tipo del valor que devuelve (SOLO en funciones)
IS
V_RESULTADO NUMBER; -- variables (opcional)
BEGIN
-- instrucciones
RETURN V_RESULTADO; -- SIEMPRE hay que devolver algo
END;
/

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

-- mismo tipo que una columna de una tabla:


V_SALARIO [Link]%TYPE;
-- una fila entera de una tabla:
V_FILA EMPLE%ROWTYPE; -- luego V_FILA.EMP_NO, V_FILA.SALARIO...

IF — condicionales

Simple

IF condición THEN
instrucciones;
END IF;

Doble (if / else)

IF condición THEN
instrucciones;
ELSE
otras instrucciones;
END IF;

Múltiple (varias condiciones)

IF condición1 THEN
instrucciones1;
ELSIF condición2 THEN -- ojo: ELSIF junto, no "ELSE IF"
instrucciones2;
ELSE
instrucciones3;
END IF;

Bucles

FOR (cuando sabes cuántas vueltas)

FOR i IN 1..10 LOOP -- i va de 1 a 10


DBMS_OUTPUT.PUT_LINE(i);
END LOOP;

-- al revés (de 10 a 1):


FOR i IN REVERSE 1..10 LOOP ... END LOOP;

La variable i se crea sola, no la declaras tú, y no se puede usar fuera del bucle.

WHILE (mientras se cumpla la condición)

WHILE V_CONTADOR <= 10 LOOP


V_CONTADOR := V_CONTADOR + 1;
END LOOP;

4
LOOP (con salida manual)

LOOP
instrucciones;
EXIT WHEN condición; -- sale cuando se cumple
END LOOP;

2. Operadores y condiciones

Se usan en el WHERE de las SELECT y en los IF .

Comparación

Operador Significado Ejemplo

= Igual WHERE SEXO = 'H'

!= <> Distinto (las dos formas valen) WHERE SEXO != 'H'

< > Menor / Mayor WHERE EDAD > 65

<= >= Menor o igual / Mayor o igual WHERE SALARIO >= 600

Condiciones especiales

Condición Significado Ejemplo

IS NULL Está vacío / es nulo. Nunca uses = NULL WHERE HABITACION IS NULL

IS NOT NULL NO está vacío WHERE TELEFONO IS NOT NULL

IN (...) Está dentro de una lista de valores WHERE SEXO IN ('H','M')

NOT IN (...) NO está en la lista WHERE OFICIO NOT IN ('JEFE')

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%'

Lógicos (unir condiciones)

Operador Significado Ejemplo

AND Se tienen que cumplir las dos EDAD > 18 AND SEXO = 'H'

OR Basta con que se cumpla una SEXO = 'H' OR SEXO = 'M'

NOT Niega la condición NOT (EDAD > 18)

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

Funciones de cadenas de texto

Función Qué hace Ejemplo → resultado

5
UPPER(t) Pasa a MAYÚSCULAS UPPER('hola') → 'HOLA'

LOWER(t) Pasa a minúsculas LOWER('HOLA') → 'hola'

INITCAP(t) Primera letra de cada palabra en mayúscula INITCAP('pepe pérez') → 'Pepe Pérez'

LENGTH(t) Cuenta cuántos caracteres tiene LENGTH('hola') → 4

SUBSTR(t,i,n) Extrae n caracteres desde la posición i (empieza en 1) SUBSTR('HOLA',1,2) → 'HO'

INSTR(t,b) Posición donde aparece "b" (0 si no está) INSTR('hola','l') → 3

REPLACE(t,a,b) Cambia "a" por "b" REPLACE('hola','o','0') → 'h0la'

TRIM(t) Quita espacios de los lados TRIM(' hi ') → 'hi'

LPAD(t,n,c) Rellena por la izquierda hasta n caracteres LPAD('5',3,'0') → '005'

RPAD(t,n,c) Rellena por la derecha RPAD('5',3,'0') → '500'

a || b Concatena (une) textos 'Ho' || 'la' → 'Hola'

Funciones numéricas

Función Qué hace Ejemplo → resultado

ROUND(n,d) Redondea a d decimales ROUND(3.567,1) → 3.6

TRUNC(n,d) Corta decimales (no redondea) TRUNC(3.567,1) → 3.5

MOD(a,b) Resto de dividir a entre b MOD(10,3) → 1

ABS(n) Valor absoluto (sin signo) ABS(-5) → 5

POWER(a,b) a elevado a b POWER(2,3) → 8

SQRT(n) Raíz cuadrada SQRT(16) → 4

CEIL(n) Redondea hacia arriba CEIL(3.2) → 4

FLOOR(n) Redondea hacia abajo FLOOR(3.8) → 3

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

Función Qué hace

SYSDATE La fecha y hora de hoy (del sistema)

f1 - f2 Resta de fechas → devuelve el número de días entre ellas

f + n / f - n Suma/resta n días a una fecha

TO_CHAR(f,'formato') Convierte fecha a texto con un formato concreto

TO_DATE(t,'formato') Convierte texto a fecha

ADD_MONTHS(f,n) Suma n meses a la fecha

MONTHS_BETWEEN(f1,f2) Meses entre dos fechas

LAST_DAY(f) Último día del mes de esa fecha

EXTRACT(YEAR FROM f) Saca el año (o MONTH, DAY) de una fecha

6
Formatos de TO_CHAR / TO_DATE más usados

Formato Qué da Ejemplo (jueves 04/06/2026)

'DD/MM/YYYY' Día/Mes/Año '04/06/2026'

'YYYY' Año (4 cifras) '2026'

'MM' Mes (2 cifras) '06'

'DD' Día del mes '04'

'D' Día de la semana en número '4' (lunes=1 ... domingo=7)

'DAY' Nombre del día 'JUEVES'

¡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;

Cómo pasar una fecha a un procedimiento/función

-- Lo más seguro: con TO_DATE indicando el formato


EXECUTE MI_PROC(TO_DATE('10/06/2026','DD/MM/YYYY'));

-- La fecha de hoy:
EXECUTE MI_PROC(SYSDATE);

Conversión de tipos

Función Qué hace

TO_CHAR(x) Pasa número o fecha a texto

TO_NUMBER(t) Pasa texto a número

TO_DATE(t,'fmt') Pasa texto a fecha

Funciones para tratar NULL

Función Qué hace Ejemplo

NVL(x, valor) Si x es NULL, devuelve "valor"; si no, x NVL(SALARIO, 0)

NVL2(x, a, b) Si x NO es null → a; si es null → b NVL2(COMISION,'sí','no')

COALESCE(a,b,c) Devuelve el primero que no sea null COALESCE(TFNO1,TFNO2)

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).

Funciones de grupo (agregación)

Función Qué hace

COUNT(*) Cuenta filas. Siempre devuelve un número (0 si no hay nada), nunca da error.

SUM(col) Suma los valores de la columna

AVG(col) Media

MAX(col) / MIN(col) Valor mayor / menor

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.

La idea con alias


A cada tabla se le pone una letra (alias) para abreviar y para distinguir columnas que se llaman igual en varias tablas.

SELECT [Link], [Link] -- E = EMPLE, D = DEPART


FROM EMPLE E
JOIN DEPART D ON E.DEPT_NO = D.DEPT_NO; -- columna que comparten

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

Tipo Qué devuelve

JOIN (INNER) Solo las filas que tienen pareja en las dos tablas

LEFT JOIN Todas las de la izquierda, aunque no tengan pareja en la derecha

RIGHT JOIN Todas las de la derecha, aunque no tengan pareja en la izquierda

Conectar 3 tablas
Se van encadenando los JOIN, uno detrás de otro. Cada uno une la nueva tabla con alguna de las anteriores.

-- Ejemplo con la BD de la residencia:


-- queremos el nombre del residente, su diagnóstico y quién se lo hizo
SELECT [Link], [Link], [Link]
FROM RESIDENTES R
JOIN REVISIONES V ON [Link] = V.DNI_RESIDENTE -- une RESIDENTES con REVISIONES
JOIN PERSONAL P ON V.COD_REALIZA = [Link]; -- une REVISIONES con PERSONAL

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.

JOIN dentro de una SELECT INTO (en PL/SQL)

SELECT MIN([Link]) INTO V_HAB


FROM HABITACIONES H
JOIN RESIDENTES R ON [Link] = [Link]
WHERE [Link] = 2 AND [Link] = 1 AND [Link] = PSEXO;

5. Tratamiento de excepciones

Las excepciones sirven para controlar errores y parar el procedimiento de forma limpia.

8
Cómo funcionan (3 pasos)

CREATE OR REPLACE PROCEDURE EJEMPLO (PDNI VARCHAR2)


AS
CONTADOR NUMBER;
MI_ERROR EXCEPTION; -- 1) DECLARAR la excepción
BEGIN
SELECT COUNT(*) INTO CONTADOR FROM RESIDENTES WHERE DNI = PDNI;

IF CONTADOR > 0 THEN


RAISE MI_ERROR; -- 2) LANZAR el error → salta directo al EXCEPTION
END IF;

-- ...resto del código (NO se ejecuta si saltó el error)...

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.

Excepciones predefinidas (no hay que declararlas)

Excepción Cuándo salta

NO_DATA_FOUND Un SELECT ... INTO no devuelve ninguna fila

TOO_MANY_ROWS Un SELECT ... INTO devuelve más de una fila

OTHERS Cualquier otro error (comodín, ponlo el último)

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:

CREATE OR REPLACE PROCEDURE VER (A VARCHAR2)


AS BEGIN DBMS_OUTPUT.PUT_LINE(A); END;
/

Y activa la salida con SET SERVEROUTPUT ON .

6. Los 3 ejercicios resueltos

Ejercicios del examen de la Residencia "Merecido Descanso". Tablas: RESIDENTES, REVISIONES, PERSONAL, HABITACIONES.

Ejercicio 1 — Función EX_DIA_CORRECTO


Enunciado: recibe una fecha y devuelve la misma fecha si: es posterior a hoy, no es fin de semana y no es agosto. Si no cumple, devuelve
NULL.

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:

EXECUTE VER(TO_CHAR(EX_DIA_CORRECTO(TO_DATE('10/06/2026','DD/MM/YYYY')))); -- devuelve fecha


EXECUTE VER(TO_CHAR(EX_DIA_CORRECTO(TO_DATE('13/06/2026','DD/MM/YYYY')))); -- NULL (sábado)
EXECUTE VER(TO_CHAR(EX_DIA_CORRECTO(TO_DATE('15/08/2026','DD/MM/YYYY')))); -- NULL (agosto)

Ejercicio 2 — Función EX_ASIGNAR_HABITACION


Enunciado: recibe el sexo y busca habitación en este orden: (1) individual vacía, (2) doble vacía, (3) doble con una cama ocupada por alguien
del mismo sexo. Si no encuentra nada, devuelve NULL.

CREATE OR REPLACE FUNCTION EX_ASIGNAR_HABITACION (PSEXO VARCHAR2)


RETURN VARCHAR2
IS
V_HAB [Link]%TYPE;
BEGIN
-- Paso 1: individual vacía (1 cama, 0 ocupadas)
SELECT MIN(HABITACION) INTO V_HAB
FROM HABITACIONES
WHERE NUMCAMAS = 1 AND NUMOCUPADAS = 0;

-- Paso 2: doble vacía (solo si la 1 no encontró nada)


IF V_HAB IS NULL THEN
SELECT MIN(HABITACION) INTO V_HAB
FROM HABITACIONES
WHERE NUMCAMAS = 2 AND NUMOCUPADAS = 0;
END IF;

-- 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;

RETURN V_HAB; -- si no encontró nada, V_HAB es NULL y devuelve NULL


END;
/

Usamos MIN(HABITACION) para quedarnos con una sola habitación (la primera). Si no hay ninguna, MIN devuelve NULL y no da error.

Ejercicio 3 — Procedimiento EX_ALTA_RESIDENTE


Enunciado: da de alta un residente con varias comprobaciones (DNI no repetido, al menos 70 años, fecha de ingreso válida, sexo H/M). Si todo
va bien lo inserta y le asigna habitación.

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.2) Tiene que tener al menos 70 años


EDAD := TRUNC((SYSDATE - PNACIMIENTO) / 365.25);
IF EDAD < 70 THEN RAISE ERROR_EDAD; 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.4) El sexo tiene que ser H o M


IF UPPER(PSEXO) NOT IN ('H','M') THEN RAISE ERROR_SEXO; 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');

-- 3.6) Le buscamos habitación. Si hay, actualizamos residente y habitación


V_HABITACION := EX_ASIGNAR_HABITACION(UPPER(PSEXO));
IF V_HABITACION IS NOT NULL THEN
UPDATE RESIDENTES SET HABITACION = V_HABITACION WHERE DNI = PDNI;
UPDATE HABITACIONES SET NUMOCUPADAS = NUMOCUPADAS + 1 WHERE HABITACION = V_HABITACION;
ELSE
VER('NO HAY CAMAS LIBRES');
END IF;

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:

EXECUTE EX_ALTA_RESIDENTE('Pepe Pérez', '50030222P', TO_DATE('01/06/1939','DD/MM/YYYY'),


TO_DATE('10/06/2026','DD/MM/YYYY'), 'H');

7. Ejemplos de validaciones típicas

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 PSALARIO NOT BETWEEN 600 AND 3500 THEN


VER('Salario fuera de rango');
END IF;

-- equivalente con AND:


IF PSALARIO < 600 OR PSALARIO > 3500 THEN ... END IF;

Validar que existe / no existe algo en una tabla

SELECT COUNT(*) INTO CONTADOR FROM DEPART WHERE DEPT_NO = PNUM;

IF CONTADOR = 0 THEN
VER('No existe'); -- no hay ninguno
ELSE
VER('Ya existe'); -- hay 1 o más
END IF;

Calcular la edad (años completos) a partir de la fecha de nacimiento

EDAD := TRUNC((SYSDATE - PNACIMIENTO) / 365.25);


-- el 365.25 tiene en cuenta los años bisiestos; TRUNC quita los decimales

Validar un DNI español (longitud + letra correcta)


La letra se calcula con el resto de dividir el número entre 23, y buscando esa posición en la cadena de letras oficial.

CREATE OR REPLACE FUNCTION VALIDA_DNI (PDNI VARCHAR2)


RETURN VARCHAR2
IS
V_NUMERO NUMBER;
V_LETRA CHAR(1);
V_CORRECTA CHAR(1);
LETRAS VARCHAR2(23) := 'TRWAGMYFPDXBNJZSQVHLCKE';
BEGIN
-- 1) Debe tener 9 caracteres (8 números + 1 letra)
IF LENGTH(PDNI) != 9 THEN RETURN 'DNI no válido (longitud)'; END IF;

-- 2) Separamos número (8 primeros) y letra (el 9º)


V_NUMERO := TO_NUMBER(SUBSTR(PDNI, 1, 8));
V_LETRA := UPPER(SUBSTR(PDNI, 9, 1));

-- 3) Calculamos la letra que le toca: resto entre 23 + 1 (SUBSTR empieza en 1)


V_CORRECTA := SUBSTR(LETRAS, MOD(V_NUMERO, 23) + 1, 1);

-- 4) Comparamos
IF V_LETRA = V_CORRECTA THEN
RETURN 'DNI correcto';
ELSE
RETURN 'Letra incorrecta, debería ser ' || V_CORRECTA;
END IF;
END;
/

Validar que un texto no está vacío

IF PNOMBRE IS NULL OR LENGTH(TRIM(PNOMBRE)) = 0 THEN


VER('El nombre no puede estar vacío');
END IF;

12
Validar un email básico (que contenga @)

IF INSTR(PEMAIL, '@') = 0 THEN -- INSTR=0 significa que no aparece


VER('Email no válido');
END IF;

-- con LIKE también:


IF PEMAIL NOT LIKE '%@%.%' THEN ... END IF;

Validar un teléfono (9 dígitos)

IF LENGTH(PTELEFONO) != 9 THEN
VER('El teléfono debe tener 9 dígitos');
END IF;

Validar el sexo (H o M)

IF UPPER(PSEXO) NOT IN ('H','M') THEN


VER('Sexo no válido');
END IF;

Validar una fecha (que no sea futura, [Link]. fecha de nacimiento)

IF PFECHA_NAC > SYSDATE THEN


VER('La fecha de nacimiento no puede ser futura');
END IF;

8. Patrones útiles que se repiten

Comprobar antes de insertar (evitar clave duplicada)

SELECT COUNT(*) INTO CONTADOR FROM DEPART WHERE DEPT_NO = PNUM;


IF CONTADOR = 0 THEN
INSERT INTO DEPART VALUES (PNUM, PNOMBRE, PLOC);
ELSE
VER('Ya existe ese departamento');
END IF;

Comprobar antes de borrar (que no tenga datos relacionados)

SELECT COUNT(*) INTO CONTADOR FROM EMPLE WHERE DEPT_NO = PNUM;


IF CONTADOR = 0 THEN
DELETE DEPART WHERE DEPT_NO = PNUM;
ELSE
VER('Tiene empleados, no se puede borrar');
END IF;

Generar el siguiente número (autonumérico manual)

SELECT NVL(MAX(EMP_NO), 0) + 1 INTO V_NUM FROM EMPLE;


-- coge el mayor número actual y le suma 1. Si la tabla está vacía, empieza en 1.

13
Recorrer las letras de una cadena (una a una)

FOR i IN 1..LENGTH(PTEXTO) LOOP


VER(SUBSTR(PTEXTO, i, 1)); -- saca el carácter de la posición i
END LOOP;

Mostrar la tabla de multiplicar de un número

FOR i IN 1..10 LOOP


VER(PNUM || ' x ' || i || ' = ' || (PNUM * i));
END LOOP;

Escribir los números pares entre dos valores

FOR i IN PNUM1..PNUM2 LOOP


IF MOD(i, 2) = 0 THEN -- si el resto entre 2 es 0, es par
VER(i);
END IF;
END LOOP;

Encontrar el mayor de tres números

IF PA >= PB AND PA >= PC THEN


VER('El mayor es ' || PA);
ELSIF PB >= PC THEN
VER('El mayor es ' || PB);
ELSE
VER('El mayor es ' || PC);
END IF;

SELECT INTO controlando que no falle

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;

9. Errores típicos a revisar

Repasa esta lista antes de entregar. Son los fallos que más se cometen.

Error / Síntoma Solución

Falta el / al final → error "Encountered the symbol BEGIN" Pon / en una línea sola al final de cada bloque PL/SQL

Escribir = NULL Es IS NULL / IS NOT NULL , nunca con =

Escribir IN NULL Es IS NULL (confundir IS con IN)

"column ambiguously defined" Pon el alias delante de la columna: [Link]

Declarar la variable antes del IS Las variables van entre el IS/AS y el BEGIN

VARCHAR2 sin tamaño en una variable Siempre con tamaño: VARCHAR2(5)

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

No ver los mensajes por pantalla Ejecuta SET SERVEROUTPUT ON al empezar

Intentar ejecutar CREATE y EXECUTE juntos Ejecútalos por separado (selecciona cada uno y dale a ▶)

ELSE IF separado En la alternativa múltiple es ELSIF (todo junto)

10. Chuleta rápida de sintaxis

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

CREATE OR REPLACE FUNCTION N (P1 NUMBER) Contar


RETURN NUMBER
IS
SELECT COUNT(*) INTO C
V NUMBER;
FROM tabla
BEGIN
WHERE ...;
RETURN V;
END;
/
Excepción propia

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

INSERT INTO t VALUES (...);


Bucle FOR UPDATE t SET c = v WHERE ...;
DELETE t WHERE ...;

FOR i IN 1..10 LOOP


...
END LOOP;

15
JOIN de 2 tablas Edad

SELECT A.x, B.y E := TRUNC(


FROM tabA A (SYSDATE - PNAC)/365.25
JOIN tabB B ON [Link] = [Link]; );

Antes de empezar la sesión

SET SERVEROUTPUT ON

Material de apoyo PL/SQL · RA5 · Bases de Datos 1º DAW · ¡Mucha suerte en el examen!

16

También podría gustarte