PLSQL
PLSQL
PL/SQL
Universitat de Lleida
Contenidos
PL/SQL I 1
2. el bloque pl/sql 7
ESTRUCTURA: 7
zona de declaración: DE VARIABLES Y CONSTANTES 8
ZONA DE PROCESO 11
zona de excepciones 12
4. sentencias de control 31
Sentencia if 31
Bucle infinito: 32
Bucles condicionales: 33
Bucles numéricos: 34
5. sentencias de dml 36
6. cursores 40
manejo de cursores 41
BUCLES SOBRE cursores 41
ejemplo de cursores 42
7. REGISTROS Y TABLAS 47
registros pl/sql 47
TABLAS en pl/sql, Arrays 49
8. sentencias transaccionales 56
VERSIÓN 1 i
INDEX PL/SQL
9. control de errores 59
Tipos de excepciones: 59
Ejecución de excepciones 60
funciones 61
Ejemplos y tratamiento 61
RESUMEN 66
EVALUACIÓN 68
PL/SQL II 70
RESUMEN 119
EVALUACIÓN 121
ii VERSIÓN 1
PL/SQL INDEX
VERSIÓN 1 iii
INDEX PL/SQL
iv VERSIÓN 1
PL/SQL
PL/SQL I
VERSIÓN 1 1
PL/SQL
INTRODUCCIÓN
2 VERSIÓN 1
PL/SQL
CONTENIDO
2. EL BLOQUE PL/SQL
ZONA DE DECLARACIÓN: DECLARACIÓN DE VARIABLES Y
CONSTANTES
ZONA DE PROCESO
ZONA DE EXCEPCIONES
4. SENTENCIAS DE CONTROL
5. SENTENCIAS DE DML
6 CURSORES
MANEJO DE CURSORES
BUCLES SOBRE CURSORES
EJEMPLO DE CURSORES
7. REGISTROS Y TABLAS
REGISTROS PL/SQL
TABLAS EN PL/SQL
8. SENTENCIAS TRANSACCIONALES
9 CONTROL DE ERRORES
10 RESUMEN
VERSIÓN 1 3
PL/SQL
OBJETIVOS
EXPECTATIVAS
• ··························································································································
························································································································
• ··························································································································
························································································································
• ··························································································································
························································································································
4 VERSIÓN 1
PL/SQL
IMPORTANTE
• Procedimientos y funciones
Nos permite utilizar técnicas procedurales como bucles, control de flujo, tratamiento de
variables y control de errores en el procesamiento de las filas devueltas en una
SELECT.
NOTA
VERSIÓN 1 5
PL/SQL
NOTA
Dispone de:
NOTA
6 VERSIÓN 1
PL/SQL
2. EL BLOQUE PL/SQL
IMPORTANTE
• Sección declarativa.
• Sección de excepciones.
ESTRUCTURA:
[DECLARE]
Variable
VERSIÓN 1 7
PL/SQL
BEGIN
[EXCEPTION]
Control de excepciones
NOTA
Las variables son utilizadas para guardar valores devueltos por una consulta o
almacenar cálculos intermedios.
8 VERSIÓN 1
PL/SQL
Var1 number(59);
Var2 Var1%TYPE;
Var3 tabla.identificador%TYPE;
Se puede también declarar una fila variable cuyos campos tienen el mismo nombre y
tipo que las columnas de una tabla o fila recuperada de un cursor:
registro tabla%ROWTYPE
TIPOS DE DATOS.
VERSIÓN 1 9
PL/SQL
Date - Fechas
NOTA
10 VERSIÓN 1
PL/SQL
ZONA DE PROCESO
En esta zona es donde se escriben todas las sentencias ejecutables: sentencias DML,
asignaciones, manejo de cursores, bucles, etc.
Es importante recordar que todas las SELECT ejecutadas dentro de un bloque PL/SQL
llevan asociado un INTO.
Una SELECT que no devuelva datos o que devuelva más de uno provoca un ERROR,
saltando la ejecución directamente al EXCEPTION.
ASIGNACIÓN DE VALORES
Las dos formas que existen para asignar valores a variables de memoria, son:
xprom:=xtotal/xcant;
SELECT SUM(valor),
COUNT(valor)
INTO xtotal,xcant
FROM ventas
WHERE fecha=sysdate;
VERSIÓN 1 11
PL/SQL
COMENTARIOS
ZONA DE EXCEPCIONES
Es sección no obligatoria. Esta sección termina con un END, que finaliza el bloque
PL/SQL.
DUP_VAL_ON_INDEX ORA–00001 –1
12 VERSIÓN 1
PL/SQL
EJERCICIO
EJERCICIO Nº 1
• Definir una variable, y, del mismo tipo que el campo hiredate, de la tabla
EMP, de la base de datos DEMO.
VERSIÓN 1 13
PL/SQL
EJERCICIO
EJERCICIO Nº 2
14 VERSIÓN 1
PL/SQL
IMPORTANTE
♦ CHR Chr(x)
VERSIÓN 1 15
PL/SQL
16 VERSIÓN 1
PL/SQL
SQL> SELECT LPAD (‘Short String’, 20, ‘XY’) Cadena FROM dual;
SQL> SELECT REPLACE (‘This and That’, ’Th’, ’B’) Cadena FROM dual;
> 23de
VERSIÓN 1 17
PL/SQL
> 11
FUNCIONES NUMÉRICAS
18 VERSIÓN 1
PL/SQL
♦ LN LN (x)
VERSIÓN 1 19
PL/SQL
> 15.7
> 17-DEC-80
FUNCIONES DE FECHA
20 VERSIÓN 1
PL/SQL
♦ SYSDATE SYSDATE
> 17-JAN-1981
ADD_MONTHS(LAST_DAY(hiredate),5),
FROM emp
> 28-FEB-1982
VERSIÓN 1 21
PL/SQL
FUNCIONES DE CONVERSIÓN
CONVERSIONES IMPLÍCITAS
CONVERSIONES EXPLÍCITAS
22 VERSIÓN 1
PL/SQL
'NLS_DATE_LANGUAGE = American')
FROM DUAL;
> 15/01/1989,11:00:00
FROM emp
FROM DUAL;
> -10000
VERSIÓN 1 23
PL/SQL
FORMATOS NUMÉRICOS
, 9,999 comma
. 99.99 period
24 VERSIÓN 1
PL/SQL
FORMATOS DE FECHA:
IYY, IY, I Last three, two or one digits of the ISO year
Y,YYY (Four Y's with comma) put a comma in the year (1,995)
YEAR, SYEAR Year spelled out (S prefixes BC dates with a minus sign)
RR Last two digits of year in another century (allows for year 2000)
BC, AD BC or AD indicator
MONTH Name of month spelled out (upper case - month is upper case)
VERSIÓN 1 25
PL/SQL
MI Minute (0-59)
SS Second (0-60)
FUNCIONES DE GRUPO
26 VERSIÓN 1
PL/SQL
OTRAS FUNCIONES
compara2, valor2…
predeterminado)
VERSIÓN 1 27
PL/SQL
♦ USER USER
OPCIONES
28 VERSIÓN 1
PL/SQL
>ENAME COMMISSION
---------- -----------------
ALLEN 300
WARD 500
MARTIN 1400
BLAKE NOT APPLICABLE
TURNER 0
JAMES NOT APPLICABLE
'PROCEDURE','R','FUNCTION','F'),TYPE,LINE;
VERSIÓN 1 29
PL/SQL
PRÁCTICA
EJERCICIO Nº 3
-Crear una tabla empleado como copia de la tabla emp. El nuevo nombre será
emp + nº de usuario.
-Modificar los registros de la tabla creada de modo que en lugar del nombre del
empleado aparezca el nombre del empleado terminado en @ para aquellos
empleados llamados JONES cuyo curso es el el 2
EJERCICIO Nº 4
EJERCICIO Nº 5
30 VERSIÓN 1
PL/SQL
4. SENTENCIAS DE CONTROL
SENTENCIA IF
ELSE sentencias_ejecutables; ]
END IF;
SQL> DECLARE
v_NumberSeats rooms.number_seats%TYPE;
v_Comment VARCHAR2(35);
BEGIN
/* Recibe el número de asientos de la sala identificada por ID 99999.
Almacena resultado en v_NumberSeats. */
SELECT number_seats
INTO v_NumberSeats
FROM rooms
WHERE room_id = 99999;
IF v_NumberSeats < 50 THEN
v_Comment := 'Fairly small';
ELSIF v_NumberSeats < 100 THEN
v_Comment := 'A little bigger';
ELSE
v_Comment := 'Lots of room';
VERSIÓN 1 31
PL/SQL
END IF;
END;
/
BUCLE INFINITO:
LOOP
sentencias_ejecutables;
END LOOP;
SQL> DECLARE
ranking_level NUMBER(3) := 1;
BEGIN
IF max_rank_in >= 1
THEN
LOOP
set_rank (ranking_level);
ranking_level := ranking_level + 1;
EXIT WHEN ranking_level > max_rank_in;
END LOOP;
END IF;
END;
32 VERSIÓN 1
PL/SQL
BUCLES CONDICIONALES:
WHILE condición
LOOP
sentencias_ejecutables;
END LOOP;
SQL> DECLARE
v_Counter BINARY_INTEGER := 1;
BEGIN
v_Counter := v_Counter + 1;
END LOOP;
END;
VERSIÓN 1 33
PL/SQL
BUCLES NUMÉRICOS:
LOOP
sentencias_ejecutables;
END LOOP;
SQL> DECLARE
v_Counter NUMBER := 7;
BEGIN
VALUES (v_Counter);
VALUES (v_Counter);
END LOOP;
34 VERSIÓN 1
PL/SQL
VALUES (v_Counter);
END;
EJERCICIO
EJERCICIO 7
• Introducir una fila por cada día del mes actual de tal forma que el resultado
final sea algo parecido a esto:
DÍAS
1
2
3
4
5
...
29
30
VERSIÓN 1 35
PL/SQL
5. SENTENCIAS DE DML
IMPORTANTE
SELECT INTO
INSERT
UPDATE
DELETE
♦ Para procesar sentencias DML, Oracle abre un cursor implícito por cada
sentencia SQL que tenga que procesar. Nos referiremos a él como SQL%.
NOTA
36 VERSIÓN 1
PL/SQL
DECLARE
v_StudentRecord students%ROWTYPE;
v_Department classes.department%TYPE;
v_Course classes.course%TYPE;
BEGIN
SELECT *
INTO v_StudentRecord
FROM students
WHERE id = 10000;
FROM classes
END;
VERSIÓN 1 37
PL/SQL
BEGIN
UPDATE emp
IF SQL%NOTFOUND THEN
END IF;
END;
EJERCICIO
EJERCICIO 8
• Utilizar la tabla DEPT y un registro para recuperar los datos de dicha tabla.
38 VERSIÓN 1
PL/SQL
EJERCICIO
EJERCICIO 9
• Crear un bloque PL/SQL que modifique la tabla EMP de tal forma aquellos
empleados cuyo número de empleado sea –1 pasen a tener como job
‘CLERK’.
VERSIÓN 1 39
PL/SQL
6. CURSORES
El conjunto de filas resultantes de una consulta con la sentencia SELECT, puede estar
compuesto por ninguna, una o varias filas, dependiendo de la condición que define la
consulta.
IMPORTANTE
♦ Declaración:
♦ Para recuperar los datos de un cursor primero hay que abrirlo (OPEN),
luego leerlo (FETCH), y por último cerrarlo (CLOSE).
40 VERSIÓN 1
PL/SQL
MANEJO DE CURSORES
• Abre el cursor.
VERSIÓN 1 41
PL/SQL
Se realiza la lectura y se ejecutan las sentencias del bucle hasta que no haya
más filas.
• Cierra el cursor.
LOOP
sentencias_ejecutables;
END LOOP;
EJEMPLO DE CURSORES
Nombre:CVENTAS.
42 VERSIÓN 1
PL/SQL
BEGIN
IS SELECT articulo,valor
FROM ventas
WHERE fecha=cfecha
xarticulo ventas.articulo%TYPE;
xvalor ventas.valor%TYPE;
BEGIN
OPEN cventas(xfecha);
(xfecha,xarticulo,xvalor);
COMMIT;
END LOOP;
CLOSE cventas;
END;
END;
VERSIÓN 1 43
PL/SQL
Para llamar al procedimiento ventas5 en una fecha dada, se puede escribir, por
ejemplo:
ventas5(to_date('15/11/95','DD/MM/YY')
ventas5(sysdate).
A continuación detallaremos las sentencias usadas en este procedimiento:
DECLARE cursor
xarticulo ventas.articulo%TYPE;
OPEN cventas(xfecha);
Lee la siguiente fila de datos del cursor cventas y pasa los datos de la consulta
a las variables xarticulo y xvalor.
44 VERSIÓN 1
PL/SQL
Garantiza la salida del ciclo antes de la última repetición, en caso que para una
fecha dada se hayan efectuado menos de 5 ventas, ya que en esta situación la
consulta del cursor devuelve menos de 5 filas.
VALUES(xfecha,xarticulo,xvalor);
COMMIT;
END LOOP;
CLOSE cventas;
EJERCICIO
EJERCICIO 10
VERSIÓN 1 45
PL/SQL
EJERCICIO
EJERCICIO 11
• Crear una tabla de totales por departamentos con dos campos: uno para los
números de departamento y otro numérico para meter los totales por
departamento.
EJERCICIO
EJERCICIO 12
• Contar cuántos empleados hay de cada tipo de job. Utilizar un cursor para
obtener los distintos tipos de trabajo, y otro cursor parametrizado en el cual
se le pasa el trabajo recuperado con el cursor anterior.
46 VERSIÓN 1
PL/SQL
7. REGISTROS Y TABLAS
REGISTROS PL/SQL
IMPORTANTE
.....
Una vez declarado un registro es necesario definir una variable de este tipo.
Se puede asignar un registro a otro del mismo tipo o sus campo individualmente, con
la condición de que ambos sean del mismo tipo.
VERSIÓN 1 47
PL/SQL
EJEMPLO:
DECLARE
Field1 NUMBER,
Field2 VARCHAR2(5));
Field1 NUMBER,
Field2 VARCHAR2(5));
v_Rec1 t_Rec1Type;
v_Rec2 t_Rec2Type;
BEGIN
v_Rec1 := v_Rec2;
/* Estos campos, son del mismo tipo, por los que la asignación sería
legal. */
v_Rec1.Field1 := v_Rec2.Field1;
v_Rec2.Field2 := v_Rec2.Field2;
END;
48 VERSIÓN 1
PL/SQL
IMPORTANTE
♦ Una tabla PL/SQL es similar a una tabla de base de datos pero como si
tuviera dos columnas una de ellas es el índice y la otra el valor.
VERSIÓN 1 49
PL/SQL
INDEX BY BINARY_INTEGER;
DECLARE
TYPE t_LastNameTable IS TABLE OF students.last_name%TYPE
INDEX BY BINARY_INTEGER;
v_LastNames t_LastNameTable;
v_Index BINARY_INTEGER;
BEGIN
-- Inserta filas en la tabla.
v_LastNames(43) := 'Mason';
v_LastNames(50) := 'Junebug';
50 VERSIÓN 1
PL/SQL
v_LastNames(47) := 'Taller';
-- Asigna 43 a v_Index.
v_Index := v_LastNames.FIRST;
-- Asigna 50 a v_Index.
v_Index := v_LastNames.LAST;
END;
/
TABLAS DE REGISTROS
DECLARE
TYPE t_StudentTable IS TABLE OF students%ROWTYPE
INDEX BY BINARY_INTEGER;
/* Cada elemento de v_Students es un registro */
v_Students t_StudentTable;
BEGIN
/* Obtiene el registro record con id = 10,001
lo almacena en v_Students(10001) */
SELECT *
INTO v_Students(10001)
FROM students
WHERE id = 10001;
v_Students(10001).first_name := 'Larry';
DBMS_OUTPUT.PUT_LINE(v_Students(10001).first_name);
END;
/
VERSIÓN 1 51
PL/SQL
52 VERSIÓN 1
PL/SQL
EJERCICIO
EJERCICIO 13
• Recuperar los datos con un registro y mostrar por pantalla cada una de las
filas recuperadas en el cursor de la siguiente manera:
SMITH
------>CLERK 800
JAMES
------>CLERK 950
ADAMS
------>CLERK 1100
PEPE
------>CLERK 1300 750
PEDRO PEREZ
------>CLERK
Pedro Perez
------>CLERK
VERSIÓN 1 53
PL/SQL
EJERCICIO
EJERCICIO 14
54 VERSIÓN 1
PL/SQL
EJERCICIO
EJERCICIO 15
Empno - number(4),
sal – number(7, 2) ,
VERSIÓN 1 55
PL/SQL
8. SENTENCIAS TRANSACCIONALES
IMPORTANTE
• Savepoint:
Marcas que pone el usuario durante la transacción para deshacer los cambios
por partes en vez de deshacer toda la transacción.
SAVEPOINT <nombre_del_punto_salvaguarda>;
• Commit:
COMMIT [WORK];
• Rollback:
56 VERSIÓN 1
PL/SQL
DECLARE
v_NumIterations NUMBER;
BEGIN
-- Loop from 1 to 500, inserting these values into temp_table.
-- Commit every 50 rows.
FOR v_LoopCounter IN 1..500 LOOP
INSERT INTO temp_table (num_col) VALUES (v_LoopCounter);
v_NumIterations := v_NumIterations + 1;
IF v_NumIterations = 50 THEN
COMMIT;
v_NumIterations := 0;
END IF;
END LOOP;
END;
PRÁCTICA
EJERCICIO 16
Codigo - number(4),
Mensaje – varchar2(80)
b) Actualizar los vendedores con una comisión mayor que 350$ con un
incremento del 15% de su salario. Si la operación afecta a más de
tres empleados, deshacer la transacción, en cualquier otro caso
validar la transacción. Introducir en la tabla TEMP la operación que
se ha realizado.
VERSIÓN 1 57
PL/SQL
PRÁCTICA
EJERCICIO 17
• Dentro del mismos bloque PL/SQL actualizar los empleados con una
comisión mayor de 350 $ con un incremento del 15% de su salario. Si la
operación afecta a más de tres empleados, deshacer la transacción, en
cualquier otro caso validar dicha transacción.
58 VERSIÓN 1
PL/SQL
9. CONTROL DE ERRORES
IMPORTANTE
THEN SENTENCIAS;
NOTA
TIPOS DE EXCEPCIONES:
EXCEPCIONES PREDEFINIDAS:
NO_DATA_FOUND,
TOO_MANY_ROWS,
DUP_VAL_ON_INDEX....
VERSIÓN 1 59
PL/SQL
Mediante:
NOTA
EJECUCIÓN DE EXCEPCIONES
RAISE <nombre_excepción>;
60 VERSIÓN 1
PL/SQL
FUNCIONES
La función SQLCODE nos devuelve el número de error producido. Sólo tiene valor
cuando ocurre un error ORACLE
La función SQLERRM nos devuelve el mensaje del error del valor actual del
SQLCODE.
NOTA
Su sintaxis es:
EJEMPLOS Y TRATAMIENTO
VERSIÓN 1 61
PL/SQL
REM
REM
DECLARE
err_msg VARCHAR2(100);
BEGIN
LOOP
THEN
BEGIN
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
NULL;
END;
END IF;
END LOOP;
END;
62 VERSIÓN 1
PL/SQL
DECLARE
pe_ratio NUMBER(3,1);
BEGIN
INTO pe_ratio
FROM stocks
COMMIT;
COMMIT;
...
ROLLBACK;
VERSIÓN 1 63
PL/SQL
DECLARE
insufficient_privileges EXCEPTION;
------------------------------------------------------
-------------------------------------------------------
BEGIN
...
EXCEPTION
Maneja el error
...
END;
DECLARE
...
null_salary EXCEPTION;
64 VERSIÓN 1
PL/SQL
BEGIN
...
raise_salary(:emp_number, :amount);
EXCEPTION
...
END;
PRÁCTICA
EJERCICIO 18
• Crear un bloque PL/SQL con una única sentencia SELECT sobre la tabla
EMPLEADOS, de tal forma que va a ir recuperando el salario del empleado
del trabajo que se introduzca por teclado.
VERSIÓN 1 65
PL/SQL
10. RESUMEN
• Procedimientos y funciones
SELECT INTO
INSERT
UPDATE
DELETE
# Para procesar sentencias DML, Oracle abre un cursor implícito por cada
sentencia SQL que tenga que procesar. Nos referiremos a él como SQL%.
66 VERSIÓN 1
PL/SQL
# Declaración de un cursor:
Para recuperar los datos de un cursor primero hay que abrirlo (OPEN),
luego leerlo (FETCH), y por último cerrarlo (CLOSE).
# Una tabla PL/SQL es similar a una tabla de base de datos pero como si
tuviera dos columnas una de ellas es el índice y la otra el valor.
VERSIÓN 1 67
PL/SQL
11. EVALUACIÓN
a) Siempre
c) Nunca
a) En la zona declarativa
declare a number:=2;
resultado varchar2(20);
begin
select decode(a,3,'Menor',4,'Siguiente',5,'Mayor','Otro') into resultado
from dual;
dbms_output.put_line(resultado);
end;
/
a) No compilaría porque en la declaración no puede asignarse
una variable a un número
b) Mayor
c) Otro
68 VERSIÓN 1
PL/SQL
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
...............................................................................................................
VERSIÓN 1 69
PL/SQL
PL/SQL II
70 VERSIÓN 1
PL/SQL
INTRODUCCIÓN
PL/SQL sólo puede contener órdenes DML y no DDL. Sin embargo esta
restricción se supera a partir de la versión 2.1 con el paquete
DBMS_SQL. Este paquete implementa código PL/SQL y SQL dinámico,
al que se llama desde otros bloques PL/SQL.
VERSIÓN 1 71
PL/SQL
CONTENIDO:
1. PROCEDIMIENTOS Y FUNCIONES
PROCEDIMIENTOS
FUNCIONES
SUBPROGRAMAS LOCALES.
PAQUETES (PACKAGES)
3. DISPARADORES (TRIGGERS)
CREACIÓN DE DISPARADORES
4. PL/SQL DINÁMICO
CONCEPTO
MÉTODOS DE IMPLEMENTACIÓN
5. EJERCICIO DE DESARROLLO
6. RESUMEN
7. EVALUACIÓN
72 VERSIÓN 1
PL/SQL
OBJETIVOS
EXPECTATIVAS
• ··························································································································
························································································································
• ··························································································································
························································································································
• ··························································································································
························································································································
VERSIÓN 1 73
PL/SQL
IMPORTANTE
NOTA
74 VERSIÓN 1
PL/SQL
PROCEDIMIENTOS
CREACIÓN DE PROCEDIMIENTOS
Bloque PL/SQL
Su estructura es semejante a:
tmpVar NUMBER;
/******************************************************************************
NAME: PROCEDIMIENTO
PURPOSE: To calculate the desired information.
REVISIONS:
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 10/09/99 1. Created this procedure.
******************************************************************************/
BEGIN
tmpVar := 0;
EXCEPTION
Null;
Null;
END PROCEDIMIENTO;
/
VERSIÓN 1 75
PL/SQL
NOTA
• Un procedimiento termina con END o con END seguido del nombre del
procedimiento.
NOTA
76 VERSIÓN 1
PL/SQL
BORRADO
EJECUCIÓN
IMPORTANTE
NOTA
VERSIÓN 1 77
PL/SQL
78 VERSIÓN 1
PL/SQL
PRÁCTICA
EJERCICIO 1
EJERCICIO 2
VERSIÓN 1 79
PL/SQL
FUNCIONES
CREACIÓN DE FUNCIONES
RETURN tipo_dato IS O AS
Bloque PL/SQL
Su estructura es semejante a:
tmpVar NUMBER;
/******************************************************************************
NAME: FUNCION
PURPOSE: To calculate the desired information.
REVISIONS:
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 10/09/99 1. Created this function.
******************************************************************************/
BEGIN
tmpVar := 0;
EXCEPTION
Null;
Null;
RETURN tmpVar;
END FUNCION;
80 VERSIÓN 1
PL/SQL
NOTA
Los argumentos OUT o IN OUT son válidos dentro de las funciones pero se
usan raramente.
BORRADO
EJECUCIÓN
IMPORTANTE
VERSIÓN 1 81
PL/SQL
• Una función se puede invocar desde una sentencia SELECT, WHERE, HAVING,
cláusula VALUES de un INSERT y SET de un UPDATE.
• Debe de ser una función de fila única (devuelven un único valor). No pueden ser ni
registros ni tablas.
• Los tipos de datos: BOOLEAN, RECORD o TABLE no están permitidos (no son
tipo SQL).
NOTA
82 VERSIÓN 1
PL/SQL
SUBPROGRAMAS LOCALES.
IMPORTANTE
PRÁCTICA
EJERCICIO 3
• Crear una función que nos permita realizar una consulta del salario del
empleado de la tabla EMP que se le pasa como parámetro desde SQL* (se
le pasa el número del empleado). Si la consulta ha sido satisfactoria la
función devuelve un SI, en caso contrario devuelve un NO.
VERSIÓN 1 83
PL/SQL
EJERCICIO 4
• Utilizar una sentencia SELECT sobre la tabla EMP que nos permita ver los
campos empno, ename y el salario de los empleados. Si el empleado tiene
una salario múltiplo de 5 y mayor de 1500 mostrar su salario multiplicado por
15, en caso contrario su salario permanece invariable.
EJERCICIO 5
• Utilizar una SELECT para extraer de la tabla EMP cada uno de los
empleados y su máximo jefe.
EJERCICIO 6
84 VERSIÓN 1
PL/SQL
• DATABASE LINK
• FUNCTION
• INDEX
• PACKAGE
• PACKAGE BODY
• PROCEDURE
• SEQUENCE
• SYNONYM
• TABLE
• TRIGGER
• VIEW
• FUNCTION
• PACKAGE
• PACKAGE BODY
• PROCEDURE
VERSIÓN 1 85
PL/SQL
IMPORTANTE
SET SERVEROUTPUT ON
DBMS_OUTPUT.PUT (Texto);
86 VERSIÓN 1
PL/SQL
DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE (varchar2)
DBMS_OUTPUT.PUT_LINE (number)
DBMS_OUTPUT.PUT_LINE (date)
NOTA
VERSIÓN 1 87
PL/SQL
NOTA
NOTA
Para que no nos dé un error debido a que el buffer es muy pequeño, conviene
inicializarlo mediante el comando:
88 VERSIÓN 1
PL/SQL
PAQUETES (PACKAGES)
IMPORTANTE
Estructura de un paquete:
VERSIÓN 1 89
PL/SQL
Variable Pública
PÚBLICA
Zona de Especificación
Variable Privada
PRIVADA
Cuerpo del paquete
CREACIÓN DE PAQUETES
Declaración variable
Declaración cursor
Declaración excepción
Declaración procedimiento
Declaración función
END Nombre_paquete
90 VERSIÓN 1
PL/SQL
Declaración variable
Declaración cursor
Declaración excepción
Código del procedimiento
Código de la función
[BEGIN Código de inicialización del paquete]
END Nombre_paquete
EXEC[UTE] Nombre_paquete.Nombre_función ó
Nombre_procedimiento
NOTA
NOMBRE_PAQUETE.NOMBRE_OBJETO
VERSIÓN 1 91
PL/SQL
• Siempre es posible declarar una variable en un bloque PL/SQL del mismo tipo que
uno que figure dentro del package:
DECLARE
V_hist ClassPackage.t_lista;
NOTA
Dentro del cuerpo del paquete se puede hacer referencia a los objetos sin
necesidad del "."
DECLARE
FUNCTION value_ok (date_in IN DATE)
RETURN BOOLEAN IS
BEGIN
RETURN date_in <= SYSDATE; Date Version
END;
92 VERSIÓN 1
PL/SQL
NOTA
select
'alter '||
' '||
object_name||
' compile'||
from
user_objects
where
status = 'INVALID'
VERSIÓN 1 93
PL/SQL
• No se puede utilizar una función que está dentro de un paquete en una sentencia
SQL. Es necesario indicar el nivel de depuración.
END PAQUETE;
/
PL/SQL
VERSIÓN 1 95
PL/SQL
TmpVar NUMBER;
BEGIN
tmpVar := 0;
EXCEPTION
Null;
Null;
RETURN tmpVar;
END MyFuncName;
TmpVar NUMBER;
BEGIN
tmpVar := 0;
EXCEPTION
Null;
Null;
END MyProcName;
END PAQUETE;
96 VERSIÓN 1
PL/SQL
PRÁCTICA
EJERCICIO 7
• Crear un paquete con los siguientes elementos: una tabla para almacenar
registros con los campos nombre, salario, un procedimiento
pr_insertar(nombre, salario) y un índice.
EJERCICIO 8
VERSIÓN 1 97
PL/SQL
EJERCICIO 9
• Crear un paquete con tres funciones que se van a llamar (las tres)
fu_recupera.
EJERCICIO 10
• Realizar una consulta en SQL* sobre la tabla EMP de forma que extraiga los
empleados cuya comisión sea mayor que el valor devuelto por la función
fu_media_comision.
98 VERSIÓN 1
PL/SQL
DISPARADORES (TRIGGERS)
IMPORTANTE
VERSIÓN 1 99
PL/SQL
$ El aviso automático a otros programas de que hay que llevar a cabo una
determinada acción, cuando se realiza un cambio en la tabla.
Tipos de disparadores:
$ Disparadores de fila: Se activan una vez por cada fila afectada por la orden que
provocó el disparo.
Clasificación:
*BEFORE
Según el momento en el que salta el disparador
* AFTER
* INSERT
Según el tipo de operación que provoca su actuación * UPDATE
* DELETE
* Sentencia
Según las veces que se ejecuta el cuerpo del disparador
* Fila
100
NOTA VERSIÓN 1
CREACIÓN DE DISPARADORES
DISPARADORES DE SENTENCIA
BLOQUE PL/SQL
DISPARADORES DE FILA
VERSIÓN 1 101
PL/SQL
NOTA
Aunque no surga un error de compilación, hay que tener en cuenta que :OLD no
está definido para las órdenes INSERT, así como no lo estará :NEW para el
DELETE.
NOTA
A pesar de que :NEW y :OLD sean tratados sintácticamente como registros del
tipo tabladisparo%Rowtype, en realidad no son registros (por tanto no se
pueden asignar como registros completos); sino que son variables de
acoplamiento.
ACTIVACIÓN DE DISPARADORES
102 VERSIÓN 1
PL/SQL
IMPORTANTE
♦ Una tabla mutante es una tabla que está modificándose actualmente por
una orden DML (INSERT, UPDATE, DELETE).
VERSIÓN 1 103
PL/SQL
Supongamos un trigger for each row que se dispara cuando se modifiquen datos de
una tabla. El trigger a su vez realiza una modificación sobre la misma tabla. Esto
provoca que la tabla quede mutante por la incosistencia de la información en ese
instante y da un error por pantalla.
NOTA
Si una operación INSERT afecta a una única fila, entonces los disparadores de
fila previo y posterior por dicha fila no tratarán a la tabla como mutante.
tmpVar NUMBER;
BEGIN
tmpVar := 0;
:NEW.SequenceColumn := tmpVar;
104 VERSIÓN 1
PL/SQL
:NEW.CreatedDate := Sysdate;
:NEW.CreatedUser := User;
EXCEPTION
Null;
END DISPARADOR;
PRÁCTICA
EJERCICIO 11
EJERCICIO 12
VERSIÓN 1 105
PL/SQL
EJERCICIO 13
EJERCICIO 14
EJERCICIO 15
106 VERSIÓN 1
PL/SQL
EJERCICIO 16
• Sustituir el trigger de fila por dos, uno antes de modificar (for each row) y
otro after (de sentencia) y un paquete que solucione el error de la tabla
mutante.
VERSIÓN 1 107
PL/SQL
CONCEPTO
IMPORTANTE
Las órdenes SQL Dinámicas tienen muy pocas restricciones, porque si se desea, la
orden completa SQl se puede determinar en el momento de la ejecución, en lugar de
en la compilación.
NOTA
Desventajas:
108 VERSIÓN 1
PL/SQL
• Procedure DBMS_SQL.BIND_VARIABLE
• Procedure DBMS_SQL.DEFINE_COLUMN
columna_variable IN <column_datatype>);
VERSIÓN 1 109
PL/SQL
• FUNCTION DBMS_SQL.FETCH_ROWS
• PROCEDURE DBMS_SQL.COLUMN_VALUE
• PROCEDURE DBMS_SQL.CLOSE_CURSOR
Cierra el cursor.
MÉTODOS DE IMPLEMENTACIÓN
IMPORTANTE
• Ejecución de consultas
110 VERSIÓN 1
PL/SQL
Estructura de la orden:
• Cerrar el cursor
(CLOSE_CURSOR)
Estructura de la orden:
• Cerrar el cursor
(CLOSE_CURSOR)
112 VERSIÓN 1
PL/SQL
EJECUCIÓN DE CONSULTAS
Estructura de la orden:
VERSIÓN 1 113
PL/SQL
• Cerrar el cursor
(CLOSE_CURSOR)
114 VERSIÓN 1
PL/SQL
VERSIÓN 1 115
PL/SQL
NOTA
Procurar siempre cerrar todos los cursores una vez ejecutada la sentencia,
incluso a través de las excepciones.
NOTA
El símbolo de doble guión hace que se considere como comentario todo lo que
sigue, hasta encontrar un carácter de avance de linea. Sin embargo, dado que
el bloque completo se encuentra en una cadena, todo el resto del bloque sería
considerado un comentario.
116 VERSIÓN 1
PL/SQL
PRÁCTICA
EJERCICIO 17
P Primary Key
U Unique Key
R Foreign Key
C Check constraint
EJERCICIO 18
EJERCICIO 19
VERSIÓN 1 117
PL/SQL
2.- Mediante un cursor Modificar dicha tabla y subir el sueldo a los empleados
que pertenezcan al departamento SALES
3.- Crear una función que devuelva la media de sueldo de los empleados que
tengan el mismo puesto (JOB) pasándole como parámetro en formato texto
dicho cargo.
4.- Crear un disparador tal que cuando modifiquemos el sueldo del presidente,
se encargue de recalcular el resto de los sueldos de todos los empleados en el
mismo porcentaje.
5.- Crear un procedimiento que actualice la fecha HIREDATE al primer día del
siguiente mes del día de la semana que coincida con la fecha anterior.
6.- Crear un procedimiento dinámico que borre todos los objetos de la base de
datos del tipo que nosotros le pasemos como parámetro del usuario que está
conectado.
118 VERSIÓN 1
PL/SQL
17. RESUMEN
VERSIÓN 1 119
PL/SQL
# Una tabla mutante es una tabla que está modificándose actualmente por
una orden DML (INSERT, UPDATE, DELETE).
Ejecución de consultas
120 VERSIÓN 1
PL/SQL
a) START procedimiento
b) EXEC procedimiento
c) RUN procedimiento
18. EVALUACIÓN
VERSIÓN 1 121
PL/SQL
11 Un disparador ..
a) Permite argumentos
a) Una tabla que se altera cuando dos usuarios modifican los datos de
una tabla a la vez.
a) NO_DATA_FOUND
b) TOO_MANY_ROWS
c) VALUE_ERROR
122 VERSIÓN 1
PL/SQL
VERSIÓN 1 123
PL/SQL
ANEXO 1: SQL*PLUS
La herramienta que nos proporciona ORACLE para interactuar con la base de datos se
llama SQL*Plus. Básicamente, es un intérprete SQL con algunas opciones de edición
y formateo de resultados.
• Usuario/Clave
Para poder acceder a una base de datos gestionada por ORACLE debemos
ser un usuario autorizado de la misma y conocer la palabra clave,
password, asociada al usuario.
1 CONEXIÓN
$ sqlplus usuario/passwd
$ sqlplus usuario/passwd@servicio
124 VERSIÓN 1
PL/SQL
Otra circunstancia que hay que tener en cuenta a la hora de conectarnos a SQL*Plus
es el modo establecido por el DBA para la autentificación del usuario de la base de
datos. La primera posibilidad es que recaiga sobre el SGBD Oracle la autentificación
de los usuarios, por lo que tendremos que darle nuestro nombre de usuario y la
palabra de paso. Pero existe la posibilidad de que el SGBD Oracle deje en manos del
Sistema Operativo esta responsabilidad. Así, no será necesario demostrarle al SGBD
Oracle quién somos ya que el SO se ha encargado previamente de comprobar que
todo es correcto. En este segundo caso, el comando de conexión con SQL*Plus debe
omitir el nombre de usuario y la palabra clave, pero manteniendo el resto de esta
manera:
$ sqlplus /@servicio
Una vez que hemos conseguido entrar en SQL*Plus nos presenta el prompt y espera
la inserción de sentencias SQL. Todas las sentencias deben acabar con un ';'. Una
sentencia puede continuar en varias líneas, que SQL*Plus va numerando. Si
queremos anular la sentencia actual podemos hacerlo colocando un '.' como único
carácter en una línea. Si queremos volver a ejecutar la última sentencia se puede
hacer con el comando '/'. Si queremos ejecutar las sentencias que almacena un fichero
.sql podemos hacerlo anteponiendo el símbolo '@' al nombre del fichero.
2 POSIBILIDADES DE EDICIÓN
La sentencia en el buffer puede ser recuperada para ejecutarla de nuevo con los
comandos:
VERSIÓN 1 125
PL/SQL
Al contenido del buffer también se puede acceder desde el editor del Sistema
Operativo. Así, el buffer podrá ser manipulado con las posibilidades del editor con el
que estemos acostumbrados a trabajar. Al salir del editor se devuelve el control al
SQL*Plus. Para conseguir trabajar con el editor del Sistema Operativo basta con
colocar la variable DEFINE_EDITOR y luego llamar al editor.
126 VERSIÓN 1
PL/SQL
SQL> define_editor=vi
SQL> edit
3 UTILIZACIÓN DE FICHEROS
SPOOL fichero
VERSIÓN 1 127
PL/SQL
• START: Ejecuta el fichero del sistema operativo que se indique, admite hasta
nueve parámetros posicionales indicados en la línea de comandos (los parámetros
se definen como un número entero comprendidos entre 1 y 9).
DESCRIBE nombre_tabla
HOST orden
• SPOOL: Envía los resultados de una orden SQL a un fichero para imprimirlas
posteriormente.
SPOOL [fichero|OFF|OUT] ON
&nombre_variable
128 VERSIÓN 1
PL/SQL
vez por su valor en una variable que aparece varias veces se la marcará con
&&.
5 FICHEROS DE COMANDOS
• líneas de comentarios,
• líneas de ejecución,
• líneas de comandos SQL, y
• líneas de comandos SQL*Plus.
LÍNEAS DE COMENTARIOS
LÍNEAS DE EJECUCIÓN
VERSIÓN 1 129
PL/SQL
SQL*Plus aporta una serie de posibilidades al lenguaje SQL que le acerca un poco
mas a lo que entendemos como un lenguaje de programación.
Variables de Usuario
UNDEFINE variable
Variables de Sustitución
Las variables de sustitución son un nombre de variable de usuario con el símbolo &
delante. Cuando SQL*Plus detecta una variable de sustitución en un comando, ejecuta
el comando tomando el valor de la variable.
Esto se puede ver en el ejemplo, donde preguntamos por los empleados que son
analistas:
130 VERSIÓN 1
PL/SQL
NOMBRE OFICIO
---------- -----------
Sastre Analista
Recio Analista
En muchas ocasiones es necesario recoger datos desde un terminal, que luego serán
utilizados en el archivo de comandos. Para realizarlo se pueden utilizar dos medios:
las variables de sustitución o los parámetros en la línea de comandos.
Cuando SQL*Plus reconoce una variable de sustitución sin valor asignado se lo pide al
usuario:
En el archivo de comandos nos referiremos a los parámetros con las variables &1, &2,
... ,&9 que se corresponden posicionalmente con ellos.
VERSIÓN 1 131
PL/SQL
Otros Comandos
6 GENERACIÓN DE INFORMES
Con SQL*Plus podemos dar forma a los resultados de las consultas para producir un
informe. Podremos:
132 VERSIÓN 1
PL/SQL
Básicamente, el formato con el que se van a presentar los resultados de las consultas
dependen de unos parámetros y de unos comandos.
PARÁMETROS
• SET LINESIZE: pone el número máximo de caracteres por línea. Por defecto
vale 80 y el máximo es 999.
• SET NULL texto: Indica la cadena de caracteres que hay que colocar en
sustitución de los valores NULL. Por defecto es "".
VERSIÓN 1 133
PL/SQL
• SET VERIFY [ON | OFF]: Controla la salida de confirmación para los valores de
las variables de sustitución. Por defecto está activado.
COMANDOS
134 VERSIÓN 1
PL/SQL
La sentencia SELECT recupera datos de una base de datos y los devuelve en forma
de resultados de la consulta. Conviene diferenciar de forma clara la cláusula y la
sentencia SELECT. Mientras que la cláusula solamente específica los columnas que
se quieren listar la sentencia engloba a toda la sintaxis que tiene como objetivo
recuperar ciertos datos.
(o/y):
WHERE condiciones
La cláusula SELECT específica los ítems que se desea recuperar, que puede ser.
• Nombre de columna.
VERSIÓN 1 135
PL/SQL
• Una constante.
El especificador * como sustituto de la lista de ítems separados por comas indica todas
las columnas. ORACLE no permite combinaciones con * y expresiones pero en otros
productos esto es posible.
La cláusula FROM indica la tabla o las tablas de las que se toman los datos
solicitados. A dichas tablas se las llama tablas fuentes de las consultas.
La cláusula WHERE dice a SQL que incluya solo ciertas filas de datos en los
resultados de la consulta.
La cláusula HAVING dice a SQL que incluya sólo ciertos grupos producidos por la
cláusula GROUP BY en los resultados de las consultas.
La estructura tabular hace que los datos sean tablas al igual que las consultas.
136 VERSIÓN 1
PL/SQL
<columna> ["<alias_columna>']
<tabla>.<columna>["<alias~columna>"]
<alias_tabla>.<columna>["<alias_columna>"]
<usuario>.<tabla>.<columna>["<alias-columna>"]
donde:
2 FROM dept d;
Además de una lista de campos simple, la lista de campos SELECT se puede "ampliar'
introduciendo funciones u "operadores". Pasamos a exponer la lista de funciones
permitidas así como los operadores. En general, las funciones permitidas son
funciones columna y el operador al que nos referimos es DISTINCT.
FUNCIONES COLUMNA
VERSIÓN 1 137
PL/SQL
Una función columna toma a una columna como argumento y produce un único dato
que sumariza la columna. SQL ofrece seis funciones de columna diferentes:
CLAUSULA FROM
<alias tabla> Alias dado a la tabla; sinónimo o vista por el cual podemos
referirnos a la misma en la sentencia SQL
2 FROM product;
138 VERSIÓN 1
PL/SQL
TEST DE COMPARACIÓN
Compara el valor de una expresión con otra; para lo cual utiliza los siguientes símbolos
de comparación:
Si la comparación es cierta, el test produce como resultado TRUE y por tanto la fila
será incluida. Si por el contrario es falsa producirá un FALSE y será excluida al igual
que si alguno de los términos de la comparación es NULL.
2 FROM product
Si alguna de las columnas ha sido definida a la hora de crear la tabla como clave
primaria esto implica que no puede haber valores duplicados en dicha columna con lo
cual esta servirá para diferenciar unívocamente cada fila.
VERSIÓN 1 139
PL/SQL
2 FROM emp
PERTENENCIA A UN CONJUNTO
SQL> SELECT *
2 FROM emp
140 VERSIÓN 1
PL/SQL
2 FROM emp
2 FROM emp
Dado que los caracteres _ y % tienen significados especiales, para hacer referencia a
ellos literalmente se puede definir para cada LIKE un carácter de escape añadiendo al
final la cláusula ESCAPE 'char'. Cuando en la expresión aparece el carácter char el
carácter que le precede se considera de forma literal.
2 FROM user_tables
VERSIÓN 1 141
PL/SQL
Las condiciones de búsqueda simples se pueden combinar con OR, AND y NOT
originando lo que se llaman condiciones de búsqueda compuestas.
SQL> SELECT *
2 FROM cities
3 WHERE population<200000
SQL> SELECT *
2 FROM cities
4 OR state = ‘TX’;
Por defecto ordena las filas seleccionadas en orden ascendente considerando el orden
léxico - gráfico que genera la lista de ítems. Con DESC este orden se hace
descendente y con ASC ascendente.
142 VERSIÓN 1
PL/SQL
2 FROM cities
Cuando se quiere ordenar utilizando alguna columna no propia de la tabla sino que se
ha generado a través de una expresión en la cláusula SELECT esta se puede indicar a
través de la posición que ocupa en la lista de Items de la cláusula SELECT.
3 FROM price
4 ORDER BY 2 DESC;
2 FROM cities
3 GROUP BY state;
VERSIÓN 1 143
PL/SQL
2 FROM stocks
Hay que destacar que a NULL para los efectos de agrupamiento se le considera otro
valor más que constituiría otro grupo como sucede en el primer ejemplo aunque este
aspecto depende del producto SQL en cuestión.
• Constantes.
• Funciones de columna.
• Cualquier columna que tenga el mismo dato para todas las filas que
integran un grupo.
2 FROM sales_revenue
3 GROUP BY sname
144 VERSIÓN 1
PL/SQL
• Una constante.
• Una función columna, que produzca un único valor que sumarice las filas del
grupo.
• Una columna de agrupación, que por definición tiene el mismo valor para todas
las filas del grupo.
Si en una sentencia SELECT se tiene una cláusula HAVING sin una cláusula GROUP
BY se considera que todas las filas forman un único grupo rechazando o aceptándole
en su totalidad.
Esta es una característica específica del SQL proporcionado por ORACLE. Permite la
recuperación jerárquica de filas siguiendo una estructura tipo árbol. Las cláusulas
asociadas a este tipo de recuperación de datos son CONNECT BY...START WITH... y
van siempre a continuación de la cláusula WHERE.
VERSIÓN 1 145
PL/SQL
FROM [usuario.]tabla,...
WHERE predicado
2 FROM emp
<selección_sin_ORDER_BY>
UNION|INTERSECT|MINUS
146 VERSIÓN 1
PL/SQL
ORDER BY <predicado>.
• No utiliza índices.
UNION
Se pueden reunir varias sentencias select con el fin de seleccionar las filas que cada
una de las sentencias considera. Esto se hace gracias al comando UNION.
sentencia SELECT 1
UNION
sentencia SELECT 2
UNION
...
sentencia SELECT n
VERSIÓN 1 147
PL/SQL
• El ANSI/ISO establece que los ítems solo pueden ser columnas pero los
productos SQL suelen relajar esta restricción.
INTERSECT
sentencia SELECT 1
INTERSECT
sentencia SELECT 2
INTERSECT
...
sentencia SELECT n
2 INTERSECT
148 VERSIÓN 1
PL/SQL
MINUS
sentencia SELECT 1
MINUS
sentencia SELECT 2
MINUS
...
sentencia SELECT n
Este tipo de combinación de sentencias SELECT devuelve aquellas filas que están en
el primer conjunto (datos obtenidos y vía la primera sentencia SELECT) pero no en el
segundo. Las filas duplicadas del primer conjunto se reducirán a una fila única antes
de que empiece la comparación con el otro conjunto.
2 MINUS
WHERE columnal=columna2
VERSIÓN 1 149
PL/SQL
En este ejemplo la conexión se realiza a través de una relación simple pero esta
puede ser múltiple utilizando AND con el WHERE. En este caso la conexión se
establecería si se verificaran todas las relaciones.
Hasta ahora hemos tratado relaciones que se basaban en la igualdad de los datos de
dos columnas de dos tablas pero esto no tiene por que ser necesariamente así. La
relación la puedo establecer con los siguientes símbolos: =, <, >, <>, <=, >=.
Dado que puede haber nombres de columnas iguales aunque en tablas diferentes es
recomendable para evitar ambigüedades el uso de columnas cualificadas.
150 VERSIÓN 1
PL/SQL
SUBCONSULTAS.
VERSIÓN 1 151
PL/SQL
estructurado. Hay consultas en SQL que no se pueden expresar sino es utilizando una
subconsulta.
Una subconsulta es simplemente una consulta que aparece dentro del WHERE o
HAVING de otra sentencia SQL encerrada entre paréntesis.
• Una subconsulta debe producir una única columna de datos como resultado.
Por lo cual la cláusula SELECT de la subconsulta debe de tener un único ítem.
2 FROM emp
4 FROM emp
152 VERSIÓN 1
PL/SQL
Compara un único valor de datos con una columna de valores producida por una
subconsulta y devuelve un resultado TRUE si el valor coincide con uno de los valores
de la columna. Utiliza el operador IN.
2 FROM emp
4 FROM dept
5 WHERE loc=’MADRID’);
TEST DE EXISTENCIA.
2 FROM dept
4 FROM emp);
VERSIÓN 1 153
PL/SQL
TESTS CUALIFICADOS
EL TEST ANY
SQL> SELECT *
2 FROM cities
4 FROM cities
EL TEST ALL
La sintaxis es igual que el test ANY aunque la palabra clave utilizada es ALL. Si todas
las comparaciones individuales dan como resultado TRUE el test da como resultado
TRUE.
SQL> SELECT *
2 FROM cities
154 VERSIÓN 1
PL/SQL
4 FROM cities
ANIDAMIENTO DE SUBCONSULTAS
SQL> SELECT *
2 FROM customer
4 FROM cities
VERSIÓN 1 155
PL/SQL
SUBCONSULTAS CORRELACIONADAS
Conceptualmente, SQL efectúa una subconsulta una y otra vez, una por cada fila de la
consulta principal. Algunos productos detectan esta circunstancia optimizando así el
tiempo de este tipo de consultas.
4. Si hay una cláusula GROUP BY, disponer las filas restantes de la tabla producto
en grupos de filas, de modo que las filas de cada grupo tengan valores idénticos
en todas las columnas de agrupación.
6. Para cada fila (o grupo de filas) restante, calcula el valor de cada elemento en la
lista de selección para producir una única fila de resultados. Para una referencia
de columna simple, utilizar el valor de la columna en la fila (o grupo de filas) actual.
Para una función de columna, utilizar como argumento el grupo de filas actual si se
especifico GROUP BY; en caso contrario, utilizar el conjunto entero de filas.
156 VERSIÓN 1
PL/SQL
7. Si hubiera SELECT DISTINCT, eliminar las filas duplicadas de los resultados que
se hubieran producido.
9. Si hay una cláusula ORDER BY, ordenar los resultados de la consulta según se
haya especificado.
Las filas generadas por este procedimiento forman los resultados de la consulta.
VERSIÓN 1 157
PL/SQL
Las sentencias de SQL que modifican los contenidos de una base de datos son
sencillas, sin embargo presentan algunas complejidades al sistema de gestión de
bases de datos como son:
158 VERSIÓN 1
PL/SQL
Por supuesto los valores de los datos tras la cláusula VALUES deben ser válidos
según el tipo de datos de la columna que les corresponde.
SQL permite omitir la lista de columnas de la sentencia INSERT, entonces SQL genera
automáticamente una lista formada por todas las columnas de la tabla, en secuencia
de izquierda a derecha (es la misma secuencia de columnas que la generada por un
SELECT *).
Nota: SQL requiere que las filas sean tratadas como conjuntos en operaciones de
inserción, supresión y actualización, con lo que no existe la noción de insertar la fila 'al
comienzo', 'al final' o 'entre dos filas' de la tabla, después de ejecutar la sentencia
INSERT la nueva fila simplemente forma parte del conjunto de la tabla.
Ahora INSERT añade múltiples filas de datos a la tabla destino, los valores de datos
para las nuevas filas no son especificados explícitamente dentro del texto de la
sentencia, sino que la fuente de las nuevas filas es una consulta de base de datos
especificada en la sentencia. Así pues los nuevos datos se obtienen de la propia base
de datos.
VERSIÓN 1 159
PL/SQL
FROM libros
Sí se van a realizar varias consultas a distintas tablas grandes, puede también ser útil
el uso de la sentencia INSERT multifila para coger en una tabla distinta las filas de
esas tablas con las que se va a trabajar y sobre ella realizar las consultas.
Notas: El estándar SQL ANSI/ISO especifica varias restricciones sobre la consulta que
aparece dentro de la sentencia INSERT multifila:
Los datos a insertar en una base de datos son frecuentemente extraídos de otro
sistema informático o recolectados de otros lugares y almacenados en archivos
secuenciales. Para cargar los datos en una tabla, se podría escribir un programa que
leyera cada registro del archivo y utilizara la sentencia INSERT de una fila para añadir
la fila a la tabla. Sin embargo, el recargo de hacer que el RDBMS ejecute
repetidamente sentencias INSERT de una fila puede ser bastante alto, por esta razón
160 VERSIÓN 1
PL/SQL
todos los productos RDBMS comerciales incluyen una capacidad de carga masiva que
carga los datos desde un archivo a una tabla a alta velocidad.
Nota: El estándar SQL ANSI/ISO no considera esta función, y suele ser suministrada
como un programa de utilidad autónomo, en lugar de formar parte del lenguaje SQL.
La cláusula FROM especifica la tabla destino que contiene las filas, la cláusula
WHERE especifica que filas de la tabla van a ser suprimidas.
Conceptualmente SQL aplica la cláusula WHERE a cada una de las filas de la tabla
especificada, suprimiendo aquellas para las cuales la condición de búsqueda produce
un resultado TRUE.
Supongamos que queremos suprimir de nuestra tabla de libros el libro "El péndulo de
Foucault", cuya signatura es 10234 para ello hacemos:
VERSIÓN 1 161
PL/SQL
FROM escritores
WHERE edad>80);
Las subconsultas pueden anidarse unas sobre otras y pueden contener referencias
externas a la tabla destino de la sentencia DELETE, con la única limitación (en una
sentencia DELETE) de que la tabla destino no puede aparecer en la cláusula FROM
de una subconsulta ni en ninguna de sus subconsultas anidadas.
UPDATE nombre-de-tabla
...
WHERE condición~de~busqueda
O bien:
UPDATE nombre-tabla
162 VERSIÓN 1
PL/SQL
...
WHERE condición-de-busqueda
Para el segundo formato, en el que aparece una subconsulta en la cláusula SET, esta
debe devolver una única fila por cada fila que se va a actualizar.
La cláusula SET especifica que columnas se van a actualizar y calcula los nuevos
valores, y la cláusula WHERE selecciona las filas de la tabla a modificar.
UPDATE libros
UPDATE oficinas
VERSIÓN 1 163
PL/SQL
Aquí WHERE selecciona sólo aquellas OFICINAS cuya columna CUOTA tenía un
valor menor de 40000 antes de la sentencia UPDATE y la columna VENTAS toma el
valor de la columna CUOTA también antes del UPDATE.
UPDATE clientes
FROM repventas
164 VERSIÓN 1
PL/SQL
SINTAXIS GENERAL.
... )
El nombre de la tabla debe ser único al igual que el nombre de la columna dentro de la
tabla (puede ser igual al nombre de una columna que pertenece a otra tabla).
• NOT NULL: impide que existan valores nulos (NULL) dentro de la columna. Si se
omite, se permiten NULL.
VERSIÓN 1 165
PL/SQL
• tipos de datos.
• manejo de los valores NULL: Según el estándar una columna puede contener
un valor NULL a menos que específicamente se declare NOT NULL. En
algunos productos el defecto es NOT NULL y hay que especificar NULL para
que puedan darse valores nulos.
.....
) [ STORAGE <storage> ]
[AS <consulta>]
PRIMARY KEY: define la clave primaria. Sirve como identificador único para cada fila
de la tabla. Especifica la/s columna/s que forman la clave primaria de la tabla. Se exige
que los valores de la clave primaria para cada fila sean únicos y no nulos (NOT NULL
para la/s columna/s de la clave primaria).
FOREIGN KEY: define la clave foránea de la tabla. Específica la relación que crea
con otra tabla de la base de datos. Especifica:
166 VERSIÓN 1
PL/SQL
...
rep NUMBER(8),
VERSIÓN 1 167
PL/SQL
ON DELETE RESTRIC)
...
168 VERSIÓN 1
PL/SQL
RESTRICCIONES DE UNICIDAD
Si una clave primara, clave foránea o una restricción de unicidad afecta a una sola
columna, el estándar ANSI/ISO permite una forma abreviada de la definición: permite
que estas claves se añadan al final de la definición de la columna.
DROP borra la tabla de la base de datos, su definición y todos sus contenidos. Todo
esto se pierde y no hay forma de recuperarlo.
VERSIÓN 1 169
PL/SQL
La nueva columna se añade al final de la tabla. El RDBMS asume un valor NULL para
la columna recién añadida en todas las filas existentes en la tabla. Puede ponerse
NOT NULL WITH DEFAULT con lo que el RDBMS pone el valor de defecto
especificado. Todos estos cambios se realizan cuando se intenta visualizar, no
inmediatamente.
No se puede suprimir una columna con ALTER. Los pasos que hay que dar son:
170 VERSIÓN 1
PL/SQL
Existen programas para cargar y descargar datos que facilitan esta labor de supresión.
REFERENCES region;
Para ello la relación que se crea entre la tabla padre e hijo debe tener un nombre.
VERSIÓN 1 171
PL/SQL
OTRAS MODIFICACIONES.
172 VERSIÓN 1
PL/SQL
Una vista es una tabla virtual en la base de datos cuyos contenidos están definidos por
una consulta. De cara al usuario aparece igual que una tabla real, con un conjunto de
columnas designadas y filas de datos. A diferencia de una tabla real, una vista no
existe en la base de datos como un conjunto almacenado de valores. La vista esta
formada por un conjunto de tablas fuente de las cuales se selecciona un conjunto de
columnas (o todas).
Una vez definida la vista, se puede utilizar en una sentencia SELECT, lo mismo que en
una tabla real. En algunas vistas también se puede utilizar las sentencias INSERT,
DELETE y UPDATE para modificar datos a través de ella, corno si fuera una tabla real.
Por tanto, a todos los efectos prácticos, se puede utilizar como si fuera una tabla real.
• Seguridad: cada usuario esta autorizado para acceder a una serie de vistas.
VERSIÓN 1 173
PL/SQL
• menor rendimiento.
Para crear una vista se debe tener permiso para acceder a todas las tablas
referenciadas en la consulta.
a) Vistas horizontales
Una vista horizontal divide horizontalmente la tabla fuente para crear la vista. Todas
las columnas de la tabla fuente participan en la vista, pero solo algunas de sus filas
son visibles a través de la vista.
SELECT *
WHERE <condición>
La vista se deriva de una única tabla fuente. WHERE determina qué filas van a formar
parte de la vista.
SELECT *
FROM repventas
174 VERSIÓN 1
PL/SQL
b) Vistas verticales
Una vista vertical divide la tabla fuente verticalmente para crear la vista. Todas las filas
de la tabla fuente participan en la vista, pero solo algunas de sus columnas son
visibles a través de ella.
La vista se deriva de una única tabla fuente. SELECT determina que columnas van a
FROM oficinas;
La vista esta formada por un conjunto de filas y columnas de una única tabla real.
WHERE <condición>
VERSIÓN 1 175
PL/SQL
FROM clientes
WHERE rep_clie=109;
d) Vistas agrupadas
Una vista agrupada es aquella en la que los datos visibles a través de ella son el
resultado de una consulta agrupada. Las vistas agrupadas toman una columna de la
tabla, le aplican una función de grupo, producen una fila resultado y se le asigna a un
nombre de columna.
GROUP BY <coln>
Las vistas agrupadas funcionan como vistas de solo lectura, pueden participar en
consultas, pero no en actualizaciones.
MIN(importe),MAX(importe),AVG(importe)
FROM pedidos
GROUP BY rep;
176 VERSIÓN 1
PL/SQL
e) Vistas compuestas
Una vista compuesta extrae sus datos de dos o tres tablas diferentes y presentan los
resultados de la consulta como única tabla virtual.
WHERE <condicion1>
AND <condicion2>
Donde:
cola, colb ... nombres de las columnas de las tablas especificadas por FROM.
Sobre esta nueva vista puede hacerse todo tipo de consultas y accesos a datos.
En una vista se puede insertar una fila de datos, suprimirla y actualizarla. Cualquier
tipo de modificación realizada en la vista implica una modificación en la/s tabla/s
original/es.
VERSIÓN 1 177
PL/SQL
Bajo el estándar ANSI/ISO una vista puede ser actualizada si la consulta que define
satisface las siguientes restricciones.
• la vista debe tener una única tabla fuente para la cual el usuario tiene los
privilegios requeridos. Si la tabla fuente es una vista debe cumplir estos criterios.
Estas reglas sobre actualizaciones de vistas son muy restrictivas. En realidad las
reglas específicas que determinan si una vista puede ser actualizada o no varían de un
producto RDBMS a otro, y suelen estar bastante detalladas.
En ORACLE una vista puede ser actualizada si la consulta de la que deriva contiene
cumple las siguientes restricciones:
SELECT *
178 VERSIÓN 1
PL/SQL
WHERE <condición>
SELECT *
FROM repventas
VERSIÓN 1 179
PL/SQL
PUBLIC especifica que el sinónimo puede ser empleado por todos los usuarios de la
base de datos. Si se omite PUBLIC, por defecto el sinónimo solo es accesible a su
creador.
FOR ADMIN_PP.OFICINAS
180 VERSIÓN 1
PL/SQL
Existe un comando o sentencia SQL que permite la modificación del nombre de una
tabla, vista o sinónimo. Este comando es específico del SQL de ORACLE. La
sentencia a la que nos referimos es RENAME.
donde:
INDICE: es una estructura que proporciona un acceso rápido a las filas de una tabla
en base a los valores de una o más columnas. Almacena valores y punteros a las filas
en donde se producen los valores. En el índice los valores dados están dispuestos en
orden creciente o decreciente de modo que el RDBMS puede buscar rápidamente el
índice para encontrar un valor particular. A continuación puede seguir el puntero para
localizar la fila que contiene al valor. El índice informa al RDBMS en que lugar del
disco esta localizada la fila. Todo esto acelera enormemente la ejecución de las
sentencias SQL con condiciones de búsqueda.
• debe actualizarse cada vez que se añade una fila a la tabla y cada vez que la
columna indexada se actualiza en una fila existente.
Utilidad:
VERSIÓN 1 181
PL/SQL
El RDBMS siempre establece un índice para la clave primaria, ya que presupone que
el acceso a la tabla se efectuará más frecuentemente a través de la clave primaria.
UNIQUE es opcional. Indica que los valores de las columnas deben ser únicos.
ON pedidos(fab, producto);
ORACLE: Soporta la misma sintaxis para crear y borrar índices. Entre otras cosas se
puede especificar en qué TABLESPACE se quiere almacenar el índice:
[TABLESPACE <tablespace>]
182 VERSIÓN 1
PL/SQL
VERSIÓN 1 183
PL/SQL
• Privilegios de objetos: aquellos que indican si el usuario tiene permiso para realizar
ciertas acciones sobre un objeto concreto (p.e. borrar filas de la tabla EMP).
La cantidad de distintos privilegios que se pueden dar a un usuario es muy grande, por
ello, para evitar tener que dar los privilegios de uno en uno a los usuarios se usan los
roles. Un role es un conjunto de privilegios.
1. CONNECT: permite conectase y acceder a las tablas públicas y a aquellas para las
que se le hayan otorgado permisos. Contiene entre otros los privilegios “alter
session”, “create database link”, “create sequence”, “create session”, “create
synonym”, “create table”, “create view”.
2. RESOURCE: permite al usuario crear sus propios objetos. Los privilegios son
“create procedure”, “create sequence”, “create table”, “create trigger”.
184 VERSIÓN 1
PL/SQL
Los objetos de una base de datos son propiedad del usuario que los creo y sólo son
visibles por su dueño inicialmente. Para que otros usuarios puedan acceder a ellos, el
propietario debe conceder a estos usuarios unos privilegios.
CONCESIÓN DE PRIVILEGIOS.
Donde privilegio es el comando que se autoriza que el usuario ejecute sobre el objeto.
Estos pueden ser: ALTER, DELETE, INDEX, SELECT, UPDATE, DROP,...
La opción ALL otorga todos los privilegios y PUBLIC hace referencia al conjunto de
todos los usuarios. Finalmente, WITH GRANT OPTION permite al usuario que recibe
estos privilegios transmitirlos a otros usuarios.
RETIRADA DE PRIVILEGIOS.
El propietario de los objetos pueda retirar los privilegios concedidos sobre sus objetos
a otros usuarios empleando la sentencia REVOKE:
Quitar el privilegio a un usuario también significa quitárselo a los usuarios a los que
este hubiera transmitido dichos privilegios.
VERSIÓN 1 185
PL/SQL
186 VERSIÓN 1
PL/SQL
Toda la información de las tablas está registrada en el diccionario del sistema (Data
Dictionary), que son tablas especiales que se crean en la instalación de ORACLE (que
son administradas por el sistema).
Conjunto de tablas y vistas que contienen información sobre la base de datos (se
crean automáticamente cuando se crea esa base). Se pueden consultar las tablas y
vistas del diccionario con la sentencia SELECT.
Tablas:
• DICTIONARY
• ALL_CATALOG
• ALL_OBJECTS
Contiene todos los objetos (tablas, vistas, índices, …) propiedad del usuario
o a los que puede acceder.
• USER_CATALOG
VERSIÓN 1 187
PL/SQL
• USER_OBJECTS
• USER_SOURCE
• ALL_TAB_COLUMNS
• USER_TAB_COLUMNS
• USER_INDEXES
• ALL_SYNONYMS
• USER_SYNONYMS
• USER_TAB_GRANTS
• ALL_USERS
• ALL_VIEWS
188 VERSIÓN 1
PL/SQL
• USER_VIEWS
VERSIÓN 1 189
PL/SQL
ANEXO 4: OPERADORES
OPERADORES
Se utilizan para manipular datos de forma individual y devolver un valor. Suelen estar
representados por caracteres especiales o palabras claves.
OPERADOR DESCRIPCIÓN
+, - Sumar y restar.
*, / Multiplicar y dividir.
= Igual.
<>,!=, ¬= Distinto.
[NOT] BETWEEN c1 AND c2 Mayor o igual que c1 y menor igual que c2.
190 VERSIÓN 1
PL/SQL
AND Y lógica.
OR O lógica.
OPERADORES LÓGICOS
VERSIÓN 1 191
PL/SQL
VALOR ÚNICO
!= <> ^=
IS NULL
LIKE
LISTA DE VALORES
IN (valor,...,valor)
Combinaciones lógicas.
AND
OR
192 VERSIÓN 1
PL/SQL
NEGACIÓN
NOT
IS NOT NULL
NOT IN (valor,...,valor)
NOT LIKE
PATRÓN DE CONSULTA
Para la definición del patrón de consulta existen dos tipos de caracteres especiales:
VERSIÓN 1 193
PL/SQL
Listar los clientes que tengan la palabra LIBRO a partir de la 5ª posición en el nombre.
SELECT nombre,direccion,telefono
FROM clientes
194 VERSIÓN 1