Está en la página 1de 43

1

Practicas de BB. DD.


ORACLE
Oracle Es un sistema gestor de Bases de datos relacionales, y
utiliza, para consultar los datos que mantiene, el lenguaje SQL. Este
lenguaje es el que se analiza a continuacin, en sus tres aspectos, consulta,
modificacin, y manipulacin de los datos.
Los ejemplos que se incluyen se realizan sobre unas tablas, que
corresponden a un modelo relacional sencillo, y son las siguientes:
Tabla EMP: (describe a los empleados de una empresa)
Nombre de columna

Permite
valores nulos?
------------------------------- -----------------EMPNO
NOT NULL
ENAME
JOB
MGR
HIREDATE
SAL
COMM
DEPTNO
NOT NULL

Tipo de Dato
---------------NUMBER(4)
VARCHAR2(10)
VARCHAR2(9)
NUMBER(4)
DATE
NUMBER(7,2)
NUMBER(7,2)
NUMBER(2)

Tabla DEPT (describe a los departamentos de la empresa)


Nombre de columna

Permite
valores nulos?
------------------------------- -----------------DEPTNO
NOT NULL
DNAME
LOC

Tipo de Dato
---------------NUMBER(2)
VARCHAR2(14)
VARCHAR2(13)

Tabla SALGRADE (describe un grado de la empresa segn el


intervalo entre el cual se encuentra el salario del empleado)
Nombre de columna

Permite
valores nulos?
------------------------------- -----------------GRADE
LOSAL
HISAL

Tipo de Dato
---------------NUMBER
NUMBER
NUMBER

Toda esta informacin puede ser obtenida desde Oracle SQL


mediante el comando "DESCRIBE nombre_tabla".
Las tablas creadas en el perfil de usuario pueden ser consultadas
mediante la tabla "user_tables" y una orden de consulta sencilla, que es un
Manual de SQL ORACLE

mandato 'SELECT'. Este mandato, es bsico en la realizacin de consultas


al sistema gestor de BBDD de Oracle, y es el que permite mostrar la
informacin de la base de datos.
TEMA 1: Mandato "Select" Bsico.
La sintaxis de este mandato es:
SELECT [DISTINCT] {*, nombre_columna [alias], ....}
FROM nombre_tabla [alias];
Este mandato muestra los valores incluidos en las columnas
seleccionadas de la tabla especificada. Los comandos incluidos entre
corchetes, son opcionales, y los incluidos entre llaves indican que ha de
escogerse entre uno de ellos. Por ejemplo, la siguiente consulta:
SELECT ename, job, sal
FROM emp;

Muestra el siguiente resultado:


ENAME
JOB
SAL
-------------------------KING
PRESIDENT
5000
BLAKE MANAGER
2850
CLARK MANAGER
2450
JONES MANAGER
2975
MARTIN SALESMAN
1250
ALLEN
SALESMAN
1600
TURNER SALESMAN
1500
JAMES
CLERK
950
WARD
SALESMAN
1250
FORD
ANALYST
3000
SMITH
CLERK
800
SCOTT
ANALYST
3000
ADAMS CLERK
1100
MILLER CLERK
1300
DOE
CLERK
15 rows selected.

La opcin "distinct" selecciona nicamente las diferentes ocurrencias


que existen en las tuplas de una columna, o conjunto de ellas.
La opcin "*" selecciona todas las columnas de la tabla especificada.
Si especificamos nicamente una columna de la tabla, deberemos incluir su
nombre.

Manual de SQL ORACLE

Podemos asignarle un alias, es decir, un encabezamiento de la


columna en la salida producida, que describa el contenido de las tuplas de
la columna que se va a mostrar.
Para poder incluir un alias, se escribe dicho alias despus del nombre
de la columna, sin coma. Si el alias posee espacios entre sus caracteres
deberemos usar las comillas dobles para delimitar dicho alias. Tambin se
pede incluir opcionalmente la palabra clave "AS" para indicar que se debe
renombrar la columna con la palabra que se incluye despus.
Existen operadores que permiten realizar cambios sobre los datos de
salida, estos operadores son:
|| : operador de concatenacin, permite concatenar una cadena entre
comillas simples a la cadena de salida del mandato "select".
+: suma, permite sumar una cantidad determinada al dato de salida
del mandato "select".
-: resta, permite restar una cantidad determinada al dato de salida
del mandato "select".
*: multiplicacin, permite multiplicar por una cantidad determinada
el dato de salida del mandato "select".
/: divisin, permite dividir por una cantidad determinada el dato de
salida del mandato "select".
TEMA 2: Restriccin y Ordenacin de los datos recuperados
Vamos a incluir en la sintaxis del mandato "select" bsico, una nueva
sentencia, "WHERE", que nos va ha permitir restringir la salida del
mandato segn las condiciones indicadas en esta sentencia. As, la sintaxis
queda como:
SELECT [DISTINCT] {*, columna [alias],...}
FROM nombre_tabla
[WHERE condition(s)];
Como se puede observar, la inclusin de esta clusula es opcional.
Un mandato "select" con una clusula "where" mostrar nicamente los
datos que cumplan la condicin especificada en ella. La condicin se
expresa mediante una serie de operadores que son:
= (igual), > (mayor que), >= (mayor o igual que), < (menor
que), <= (menor o igual que), <> (distinto de)
"between .... and ...." (entre los valores .... y ....)
"in (..., ..., ......)" (se encuentra en la lista dada entre parntesis
y cuyos valores estn separados por comas)
"like" (igual a, pero para cadenas de caracteres)
"is null" (para cadenas o caracteres nulos)

Manual de SQL ORACLE

Se pueden concatenar condiciones, de manera que la salida ser segn el


operador:
"condicin AND condicin" (mostrar los datos que cumplan
las condiciones que se encuentran antes y despus de este
operador).
"condicin OR condicin" (mostrar los datos que cumpla la
condicin que se encuentran antes despus de este operador).
"NOT condicin" (mostrar los datos que no cumplan la
condicin que se encuentra despus de este operador).
Para ordenar los datos que recuperamos mediante el mandato
"select", se usa la clusula "ORDER BY nombre_columna" as tenemos
ahora:
SELECT [DISTINCT] {*, columna [alias],...}
FROM nombre_tabla
[WHERE condition(s)]
[ORDER BY column_name [{DESC, ASC}];
Se puede observar que esta clusula tambin es opcional. La
ordenacin es por defecto ascendente, es decir , de menor a mayor, excepto
en el caso de que se incluya la palabra reservada "DESC". Esta palabra
reservada, hay que incluirla para cada una de las columnas que se incluyen
dentro de la sentencia 'ORDER BY...'. Por ejemplo, la consulta:
SELECT ename, sal, comm
FROM emp
WHERE comm IS NOT NULL
ORDER BY sal,comm DESC;

Ofrece la salida:
ENAME
---------MARTIN
WARD
TURNER
ALLEN

SAL
COMM
--------- --------1250
1400
1250
500
1500
0
1600
300

Donde se puede observar que se ha ordenado de mayor a menor la columna


de las comisiones ('comm') pero de menor a mayor en el campo del salario,
tomando adems este como el campo de ordenacin principal. As, el
salario ('sal') esta ordenado en orden ascendente por defecto. Para poder
ordenar en orden descendente de salario y comisiones la consulta correcta
es:
Manual de SQL ORACLE

5
SELECT ename,sal,comm
FROM emp
WHERE comm IS NOT NULL
ORDER BY sal DESC,comm DESC;

que ofrece la salida:


ENAME
---------ALLEN
TURNER
MARTIN
WARD

SAL
--------1600
1500
1250
1250

COMM
--------300
0
1400
500

TEMA 3: Funciones sobre cadenas de caracteres y tipos de


datos especiales.
Funciones para cadenas

Para la manipulacin de cadenas de caracteres existen funciones


como:

LOWER({columna,expresion}): Pasa toda la cadena indicada


en el nombre de columna, o en expresin entre comillas
simples a letras minsculas.
UPPER({columna,expresion}): Pasa toda la cadena indicada
en el nombre de columna, o en expresin entre comillas
simples a letras maysculas.
INITCAP({columna,expresion}): Pasa toda la cadena indicada
en el nombre de columna, o en expresin entre comillas
simples a letras donde la primera letra esta en mayscula y el
resto en minsculas.
CONCAT(cadena1,cadena2): Devuelve una cadena
concatenacin de 'cadena1' y 'cadena2'.
SUBSTR(cadena,n,m,.....): Devuelve los caracteres de la
cadena desde el n, hasta el carcter nmero m.
LENGTH(cadena): Devuelve un entero con el nmero de
caracteres de la cadena pasada como parmetro.
LPAD(columna,numero_caracteres,'caracter') ofrece a la
salida un cadena de longitud 'numero_caracteres' que contiene
a caracteres 'caracter' a la izquierda y el contenido de la
columna indicada en 'columna', rellenando dicha cadena, con
los caracteres especificados hasta alcanzar el tamao indicado.
Estas funciones nos permiten consultas como:
SELECT ename, job, hiredate
Manual de SQL ORACLE

6
FROM emp
WHERE LOWER(ename)='blake';

Donde el nombre que encontramos en la tabla, puede estar escrito de


cualquier manera, pero se pasa a letras minsculas para ser comparado con
el nombre 'blake'.
Funciones numricas

Tambin existen funciones numricas tales como:


ROUND({columna,expresin,numero}): que obtiene el
redondeo de la cifra pasada como parmetro a un nmero
entero.
TRUNC({columna,expresion},n): que obtiene el redondeo de
la cifra real pasada como primer parmetro a un nmero con
tantos decimales como se le indique en el segundo parmetro
'n'.
MOD(m,n): Que obtiene el resto de la divisin entera entre 'm'
y 'n'.
Donde la utilidad de estas es similar a la que se muestra en el
conjunto de funciones anterior, pero adems se puede utilizar (como las
anteriores tambin) en consultas como la siguiente:
SELECT empno,ename,sal,round (sal*1.15) "New Salary"
FROM emp;

Que ofrece la salida siguiente:


EMPNO ENAME SAL New Salary
--------- ---------- --------- ---------7839 KING
5000
5750
7698 BLAKE
2850
3278
7782 CLARK 2450
2818
7566 JONES 2975
3421
7654 MARTIN 1250
1438
7499
ALLEN 1600
1840
7844 TURNER 1500
1725
7900 JAMES 950
1093
7521 WARD
1250
1438
7902 FORD
3000
3450
7369 SMITH
800
920
7788 SCOTT 3000
3450
7876 ADAMS 1100
1265
7934 MILLER 1300
1495
8000 DOE
15 rows selected.

Manual de SQL ORACLE

Donde en la columna 'New Salary', se ofrece el redondeo de la cifra


obtenida al multiplicar el salario del trabajador por 1.15.
Funciones para fechas

Tambin existen funciones especficas para el tipo de dato 'fecha', de


Oracle que son:
MONTHS_BETWEEN(date1,date2): Devuelve los meses que
hay entre dos fechas dadas como 'date1' y 'date2'.
ADD_MONTHS(date,n): Devuelve una fecha con 'n' meses
aadidos a la fecha pasada como primer parmetro.
NEXT_DAY(date,'char'): Permite conocer la fecha (valor
devuelto) del da indicado en 'char' siguiente a la fecha pasada
como primer parmetro. Por ejemplo podemos conocer la
fecha del siguiente lunes a partir de una fecha determinada.
LAST_DAY(date): Devuelve el ltimo da del mes.
Para realizar conversiones explicitas entre tipos de datos en relacin
al tipo de dato 'fecha', se usan funciones como:
TO_CHAR(number/date,[fmt]): Devuelve una cadena
obtenida a partir de una fecha o un nmero.
TO_DATE('char',[fmt]): Devuelve una fecha creada a partir de
una cadena pasada como parmetro.
TO_NUMBER(char): pasa a nmero la cadena pasada como
parmetro.
En este ltimo grupo de funciones, encontramos un parmetro, que
es el formato de fecha. Este formato est formado por una serie de
caracteres dados, que permiten al SGBD determinar el formato en el que se
ha pasado la fecha. El formato por defecto es: DD-Month-YY, es decir, una
fecha con este formato podra ser: '12-May-03'. Estos caracteres especiales
son:
YYYY: Nmero del ao completo y en nmero entero.
YY: ao, en dos cifras (2003-->03)
Year: Forma escrita del ao (la primera en mayscula y las
siguientes en minscula).
MM: Mes, en cifras numricas
Month: Mes escrito en letras (la primera en mayscula y las
siguientes en minscula).
DD: Cifra numrica del ao.
Day: Da escrito en letras (la primera en mayscula y las
siguientes en minscula).

Manual de SQL ORACLE

Como ejemplo, podemos ver los empleados dados de alta entre el 20


de febrero del 81, y el 1 de mayo del mismo ao.
SELECT ename,hiredate
FROM emp
WHERE hiredate BETWEEN to_date('20-February-81','DD-Month-YY')
AND to_date('01-May-81','DD-Month-YY');

Funciones especiales

Existen otras funciones especiales, no asociadas a ningn tipo de


dato en especial, entre las que podemos encontrar:
NVL(columna,sustitucin): Permite cambiar cualquier valor
nulo por el dato que interese. Detecta los valores nulos en la
columna pasada como primer parmetro y los sustituye por el
dato pasado en el segundo parmetro. Por ejemplo, en esta
consulta, se muestra con un cero a los empleados que no ganan
comisiones:
SELECT ename, NVL(comm,0) "Commisions"
FROM emp;

Esta funcin es especialmente interesante ya que cualquier


operacin con un dato nulo da como resultado otro dato nulo,
lo cual puede no interesarnos, en casos como el de calcular el
salario total de todos los empleados, ya que aquellos que no
cobran comisin, tienen un valor NULL en este campo
(comm=NULL), y sumado al salario, dara el valor nulo, con
lo que la salida no sera correcta.
DECODE Function: Esta funcin es similar a un "case" de C,
o un "Segn" en pseudocdigo, permite especificar los valores
a mostrar, segn una columna dada, o el valor de una
expresin. Por ejemplo:
SELECT job, sal, DECODE (job, 'ANALYST', sal*1.1,
'CLERK', sal*1.5,
'MANAGER',sal*1.20,
sal) "Revised Salary"
FROM emp;

De esta manera adecuamos la subida de salario en


funcin del trabajo.

Manual de SQL ORACLE

TEMA 4: Productos Cartesianos.


En este tema se aprende a obtener datos de mltiples tablas dentro de
la base de datos que tenemos, as en nuestro caso, tenemos las tablas 'emp'
y 'dept' definidas al comienzo del presente documento. Para ello es
necesario que ambas tablas posean una clave fornea, que es un campo que
permite relacionar los datos que ambas contienen, as, para conocer la
localizacin del departamento donde trabaja un empleado, necesitaremos
ambas tablas.
Este tipo de consultas se realiza teniendo en cuenta los siguientes
puntos:
Incluir las tablas que vamos a necesitar en la clusula 'from'
que en nuestro caso sern, como ya se ha dicho antes, las
tablas 'emp' y 'dept'.
Es necesario, en algunos casos, definir a que tabla pertenece la
columna que deseamos recuperar con nuestra consulta. As,
en caso de que una columna este en ambas tablas, se deber
hacer mencin a esas columnas mediante el nombre de la
tabla, un punto, y el nombre de la columna.
Tambin, debemos evitar que se produzca un producto
cartesiano. Siempre que utilicemos dos o ms tablas en una
consulta, deberemos "emparejar" las tuplas de las tablas, de
manera que el SGBD de Oracle pueda mostrarnos la
informacin correcta. si no se realiza esta accin, emparejar
cada tupla de una tabla con todas las de la otra u otras, es
decir, realiza un producto cartesiano de las tablas que
intervienen en la consulta.
A continuacin veremos un ejemplo de lo que se acaba de explicar.
Supongamos que queremos recuperar los nombres de los trabajadores, y el
departamento donde trabajan, as como la localizacin de este
departamento. Podramos realizar la siguiente consulta, sin tener en cuenta
el producto cartesiano, que provocar que la salida sea incorrecta:
SELECT ename, deptno, loc
FROM emp, dept;

Esta consulta ofrece a la salida lo siguiente:


SELECT ename, deptno, loc
*
ERROR at line 1:
ORA-00918: column ambiguously defined

Manual de SQL ORACLE

10

Debido a que la columna 'deptno', esta definida tanto en la tabla


'emp' como en la tabla 'dept', as es que nos informa de que la columna esta
definida ambiguamente. Si subsanamos ese error, queda la consulta:
SELECT ename, dept.deptno, loc
FROM emp, dept;

Ahora se nos ofrece a la salida la siguiente lista de tuplas:


ENAME
DEPTNO LOC
---------- --------- ------KING
10 NEW YOR
BLAKE
10 NEW YOR
CLARK
10 NEW YOR
JONES
10 NEW YOR
MARTIN
10 NEW YOR
ALLEN
10 NEW YOR
TURNER
10 NEW YOR
JAMES
10 NEW YOR
WARD
10 NEW YOR
FORD
10 NEW YOR
SMITH
10 NEW YOR
SCOTT
10 NEW YOR
ADAMS
10 NEW YOR
MILLER
10 NEW YOR
DOE
10 NEW YOR
KING
20 DALLAS
BLAKE
20 DALLAS
CLARK
20 DALLAS
JONES
20 DALLAS
MARTIN
20 DALLAS
ALLEN
20 DALLAS
.............................................
.............................................
FORD
40 BOSTON
SMITH
40 BOSTON
SCOTT
40 BOSTON
ADAMS
40 BOSTON
MILLER
40 BOSTON
DOE
40 BOSTON
60 rows selected.

Tal y como podemos comprobar, esta no es la salida que deseamos


obtener, ya que tenemos 60 filas, y en realidad en nuestra empresa tan solo
hay 15 trabajadores, luego algo ha pasado. Efectivamente se ha producido
un producto cartesiano entre las tuplas de las tablas 'emp' y 'dept'. Para
evitar esto, debemos emparejar cada empleado con la localizacin del
departamento en que trabaja, ya que antes se han emparejado todos los
Manual de SQL ORACLE

11

empleados con todos los departamentos existentes en nuestra empresa


(producto cartesiano). As, la consulta correcta que nos ofrece los datos
requeridos es:
SELECT ename, dept.deptno , loc
FROM emp, dept
WHERE emp.deptno=dept.deptno;

Consulta que ofrece a la salida los datos correctos sobre la


localizacion del departamento, donde trabajan todos los empleados:
ENAME
DEPTNO LOC
---------- --------- ------------KING
10 NEW YORK
BLAKE
30 CHICAGO
CLARK
10 NEW YORK
JONES
20 DALLAS
MARTIN
30 CHICAGO
ALLEN
30 CHICAGO
TURNER
30 CHICAGO
JAMES
30 CHICAGO
WARD
30 CHICAGO
FORD
20 DALLAS
SMITH
20 DALLAS
SCOTT
20 DALLAS
ADAMS
20 DALLAS
MILLER
10 NEW YORK
DOE
10 NEW YORK
15 rows selected.

Dependiendo del tipo de relacin a que estn sujetas las tablas, se


pueden definir varios tipos de emparejamiento dentro de este tipo de
consultas que veremos mediante ejemplos, as, tenemos:
Equijoins (igualdad): Cuando la relacin es de uno a uno, es el
caso anterior. Un ejemplo es la consulta realizada
anteriormente.
Non-equijoins (no igualdad): son relaciones que no son de
igualdad, como ejemplo utilizaremos la tabla 'salgrade' en la
siguiente consulta:
SELECT ename, sal, grade
FROM emp, salgrade
WHERE sal BETWEEN losal AND hisal;

que ofrece la siguiente salida:


ENAME
SAL GRADE
---------- --------- --------JAMES
950
1

Manual de SQL ORACLE

12
SMITH
ADAMS
MARTIN
WARD
MILLER
ALLEN
TURNER
BLAKE
.........

800
1100
1250
1250
1300
1600
1500
2850

1
2
2
2
3
3
4

14 rows selected.

Outer-joins (filas que no tienen ningn valor): Si existen filas


que no tiene ningn valor asociado, ejemplo:
SELECT e.ename, d.deptno, d.dname
FROM emp e, dept d
WHERE e.deptno(+)=d.deptno
ORDER BY e.deptno;

que ofrece al siguiente salida:


ENAME
DEPTNO DNAME
---------- --------- -------------KING
10 ACCOUNTING
CLARK
10 ACCOUNTING
DOE
10 ACCOUNTING
MILLER
10 ACCOUNTING
JONES
20 RESEARCH
SCOTT
20 RESEARCH
ADAMS
20 RESEARCH
SMITH
20 RESEARCH
FORD
20 RESEARCH
BLAKE
30 SALES
MARTIN
30 SALES
ALLEN
30 SALES
TURNER
30 SALES
JAMES
30 SALES
WARD
30 SALES
40 OPERATIONS
16 rows selected.

Donde se puede observar que se coloca el smbolo (+) para


indicar que la salida puede ser nula en los campos que poseen
ese smbolo, y as, mostramos todos los departamentos
existentes, aunque estos no tengan asignado ningn trabajador.
Manual de SQL ORACLE

13

Self-joins (para datos almacenados en la misma tabla): este


tipo de consultas, se realizan entre datos de la misma tabla.
Como se ha podido observar, se pueden asignar alias a las
tablas, de manera que no haga falta que se escriba el nombre
completo de la tabla cuando queremos distinguir dos campos
de igual nombre, pero que pertenecen a tablas distintas. esto
podemos usarlo para realizar consultas como la siguiente:
SELECT worker.ename||' works for '||manager.ename
FROM emp worker, emp manager
WHERE worker.mgr=manager.empno;

Consulta que ofrece a la salida, el nombre de todos los


empleados, y el jefe del cual depende:
WORKER.ENAME||'WORKSFOR'||MANAG
------------------------------BLAKE works for KING
CLARK works for KING
JONES works for KING
MARTIN works for BLAKE
ALLEN works for BLAKE
TURNER works for BLAKE
JAMES works for BLAKE
WARD works for BLAKE
FORD works for JONES
SMITH works for FORD
SCOTT works for JONES
ADAMS works for SCOTT
MILLER works for CLARK
DOE works for BLAKE
14 rows selected.
TEMA 5: Funciones de grupo. Agrupar datos.
Existen funciones no especificadas en el tema 3 que permiten
calcular valores como medias, valores mximos etc. Estas funciones son
entre otras:
MAX(columna): ofrece a la salida el valor mximo encontrado
en la columna especificada en el parmetro.

Manual de SQL ORACLE

14

MIN(columna): ofrece a la salida el valor mnimo encontrado


en la columna especificada en el parmetro.
AVG(columna): ofrece a la salida el valor de la media
aritmtica en la columna especificada en el parmetro.
SUM(columna): Que ofrece a la salida, la suma de todas las
ocurrencias encontradas en la columna que se pasa como
parmetro a la funcin.
COUNT(columna): Cuenta el n de filas en una columna de la
tabla.
STDDEV(columna): Obtiene la desviacin tpica en los valore
de una columna de la tabla.
As, podemos crear consultas tales como la siguiente:
SELECT max(sal), min(sal), avg(sal), sum(sal)
FROM emp
WHERE job like 'sales%';

Que ofrece a la salida una sola fila que contendr los valores
especificados en las funciones definidas anteriormente.
Dentro de estas funciones, es de especial importancia, la funcin
COUNT, ya que esta puede tener en cuenta valores nulos en el momento de
realizar la cuenta, o no. As, podemos ver que en la siguiente consulta, se
realiza una cuenta de todas las ocurrencias de las columnas, sin importar si
estas contienen valores nulos o no:
SELECT count(*)
FROM emp
WHERE deptno=30;

Esta consulta ofrece a la salida una sola fila (y columna) con el valor
de todas las ocurrencias de la tabla en las que se encuentre un valor en la
columna 'deptno' igual a 30. Sin embargo, en el siguiente caso, en el que se
especifica un nombre de columna, si se tienen en cuenta aquellos valores
que poseen un valor nulo:
SELECT count(comm)
FROM emp
WHERE deptno=30;

As, se ofrece a la salida de nuevo una sola fila con el nmero de


ocurrencias que poseen en la columna de las comisiones un valor distinto
de NULL. Esta funcin, permite adems la inclusin de la palabra
reservada DISTINCT para contar las ocurrencias de valores distintos como

Manual de SQL ORACLE

15

se muestra en la siguiente consulta que muestra el nmero de managers que


existen en la empresa:
SELECT count(distinct mgr)
FROM emp;

El resto de funciones no tienen en cuenta el valor NULL, es decir,


cualquier otra funcin de las especificadas anteriormente (sum, avg, max,
min...) no tienen en cuenta el valor nulo a la hora de realizar los clculos,
debido a que tampoco aceptan el '*' como un nombre de columna vlido.
Si queremos que estas funciones tengan en cuenta los valores nulos,
tendremos que valernos de la funcin NVL, como se muestra en el
siguiente ejemplo:
SELECT avg(nvl(comm,0))
FROM emp;

En este caso, la media tendr en cuenta todos los valores nulos, que
sern sustituidos por un cero.
Estas funciones son llamadas "de grupo" debido a que permiten la
inclusin de una nueva clusula que permite presentar la informacin por
grupos de datos que tengan caractersticas distintivas. As podremos
agrupar la salida de una consulta que calcule la media del salario para los
distintos departamentos que existen en nuestra empresa. Esto es posible
mediante la clusula GROUP BY que se aade a la sintaxis original de la
orden SELECT quedando como se muestra a continuacin en caso de que
utilicemos funciones de grupo:
SELECT {columna [alias],funcion_de_grupo(columna)}
FROM nombre_tabla
[WHERE condition(s)]
[GROUP BY columna];
Como ejemplo, se mostrar la siguiente consulta:
SELECT deptno, avg(sal)
FROM emp
GROUP BY deptno;

Que nos mostrar a la salida, la media del salario de cada uno de los
diferentes departamentos que podemos encontrar en nuestra empresa.
DEPTNO AVG(SAL)
----------------10
2916.6667

Manual de SQL ORACLE

16
20
30

2175
1566.6667

Tambien podemos agrupar por ms de una columna, como se


muestra en la siguiente consulta:
SELECT deptno, avg(sal)
FROM emp
GROUP BY deptno, job;

Que ofrece la siguiente salida:


DEPTNO AVG(SAL)
----------------10
1300
10
2450
10
5000
20
3000
20
950
20
2975
30
950
30
2850
30
1400
9 rows selected.

Consulta que no tiene mucho sentido si no se muestra el trabajo por


el cual se agrupan los datos, pero se ha realizado de esta manera para
mostrar la posibilidad de hacerlo. En cambio hay que destacar que no se
puede realizar esta consulta sin incluir la clusula GROUP BY, ya que
Oracle intentar mostrar la media del salario, para todas las tuplas
(ocurrencias) de la tabla, y calcular la media para una sola ocurrencia, lo
cual carece de sentido. Es decir, si incluimos una funcin de grupo en la
lista de columnas y un(os) nombre(s) de columna simple, debemos agrupar
por ese(os) nombre(s) de columna ya que esta clusula, debe poseer como
campos de agrupamiento todas las columnas que no estn incluidas en
funciones de grupo. As, la siguiente consulta sera incorrecta:
SELECT dept.dname, dept.loc, count(empno), avg(sal)
FROM emp, dept
WHERE emp.deptno=dept.deptno
GROUP BY dept.dname;

Y nos ofrecera un mensaje de error a la salida, a no ser que


agrupsemos por nombre de departamento y por localizacin, en cuyo caso,
ofrecera el nmero de trabajadores que hay en cada departamento as:

Manual de SQL ORACLE

17
SELECT dept.dname, dept.loc, count(empno), avg(sal)
FROM emp, dept
WHERE emp.deptno=dept.deptno
GROUP BY dept.dname;

Consulta que ofrecera a la salida lo siguiente:


DNAME
-------------ACCOUNTING
RESEARCH
SALES

LOC
COUNT(EMPNO) AVG(SAL)
-------------------------------NEW YORK
4
2916.6667
DALLAS
5
2175
CHICAGO
6
1566.6667

Otra de las restricciones a tener en cuenta cuando utilizamos


funciones de grupo, es que no podemos incluir funciones de grupo en la
clusula WHERE, es decir, no estn permitidas consultas como la
siguiente:
SELECT deptno, count(ename)
FROM emp
WHERE avg(sal)>2000
GROUP BY deptno;

Para ello se habilita una nueva clusula, HAVING, que si permite la


inclusin de este tipo de funciones en las agrupaciones de datos. Esta
clusula siempre se aade al final de la consulta excepto en el caso de que
debamos incluir una clusula ORDER BY, y se puede utilizar en consultas
como la siguiente:
SELECT deptno, count(ename),avg(sal)
FROM emp
WHERE deptno in (10,20)
GROUP BY deptno
HAVING avg(sal)>2200;

Esta consulta muestra el numero de empleados en los departamentos


que tienen una media de salario mayor a 2200$ y tan solo para los
departamentos 10 y 20,(la media del salario en el departamento 20 es 2175)
luego la salida ser:
DEPTNO COUNT(ENAME) AVG(SAL)
---------------------------10
4
2916.6667
En el siguiente ejemplo, se muestra el numero de manager, y el
salario del empleado peor pagado (salario mnimo) para aquellos

Manual de SQL ORACLE

18

empleados que tengan manager (su manager no sea un valor NULL) y


excluyendo aquellos grupos cuyo mnimo salario sea menor de 1000$ y en
orden descendente de salario mnimo:
SELECT mgr, min(sal)
FROM emp
WHERE mgr is not null
GROUP BY mgr
HAVING min(sal)>1000
ORDER BY min(sal) desc;

As la salida es:
MGR MIN(SAL)
--------- --------7566 3000
7839 2450
7782 1300
7788 1100
TEMA 6: Subconsultas
Son consultas dentro de la clusula WHERE de una consulta. Este
tipo de consultas debe devolver un solo valor en cada fila, ya que se
utilizan para la comparacin dentro de la clusula antes indicada. Como
ejemplo, podramos buscar el nombre y el nmero del empleado que tenga
el salario mnimo.
As, deberemos incluir en la clusula WHERE una comparacin con
el salario del empleado que posea el salario mnimo, lo cual se hace de la
siguiente manera.
SELECT ename, empno
FROM emp
WHERE sal =(SELECT min(sal)
FROM emp);

Es de destacar que dentro de la subconsulta no podemos incluir


ninguna clusula ORDER BY. Si se puede usar sin embargo la clusula
WHERE para restringir al salida a una sola fila. Por ejemplo podemos
buscar aquellos empleados que posean un salario mayor que el salario que
gana el empleado nmero 7566 y que tengan el mismo trabajo que el
empleado nmero 7369 mediante la siguiente consulta:
SELECT ename, job
FROM emp

Manual de SQL ORACLE

19
WHERE sal>(SELECT sal
FROM emp
WHERE empno=7566)
AND job like (SELECT job
FROM emp
WHERE empno = 7369);

De esta manera mediante dos subconsultas podemos hallar los datos


pedidos.
Tambin se puede incluir la clusula HAVING en una subconsulta,
si utilizamos funciones de grupo de manera que restrinjan la salida a una
sola fila.
Existen casos en los que podemos realizar consultas que devuelvan
ms de una fila. En estos casos el criterio de comparacin debe ser
mediante uno de los siguientes operadores:
IN: Para que los valores devueltos coincida con uno de los
valores de la lista. Es equivalente a '=ANY'.
ANY: Se utiliza siempre detrs de algn operador de
comparacin, tal como <,>,<=,>=,<>,..... e indica que debe ser
comparado con alguno de los valores de la lista.
ALL: Este operador tambin va precedido de un operador de
comparacin (<,>,<=,>=,.....), pero esta vez indica que la
comparacin debe cumplirse para todos los valores que
devuelva la subconsulta.
Como ejemplo de lo expuesto anteriormente, vamos a obtener el
nombre y el numero de los empleados que trabajan en un departamento que
tenga algn empleado cuyo nombre contenga una 'T'.
SELECT ename, empno
FROM emp
WHERE deptno IN (SELECT deptno
FROM emp
WHERE lower(ename) like lower( '%T%'));

Tambin, como ejemplo vamos a hallar el nombre de los empleados


cuyo salario sea menos que alguno de los empleados cuyo trabajo sea
CLERK as:
SELECT ename, empno
FROM emp
WHERE sal <ANY (SELECT sal
FROM emp
WHERE job like 'CLERK');

Manual de SQL ORACLE

20

Por ltimo, hallaremos los empleados cuyo salario sea mayor que el
de todos los empleados (mayor que el mayor de todos los salarios) de lso
empleados cuyo trabajo sea CLERK de la siguiente manera:
SELECT ename, empno
FROM emp
WHERE sal >ALL (SELECT sal
FROM emp
WHERE job like 'CLERK');

TEMA 7:Subconsultas que devuelven mltiples columnas


Este tipo de consultas, son similares a las anteriores, pero en este
caso se devuelven varias columnas, no solo una. La forma de hacerlo,
normalmente es incluyendo entre parntesis los dos campos o columnas
con las que se pretende comparar la salida de la subconsulta, ya que en el
caso de necesitar una consulta de este tipo, podremos encontrarnos con
varias posibilidades. La primera de ellas es el caso mencionado en el que
necesitamos que coincidan ambas columnas (matches both) que se llama
'Pairwise', y el segundo caso es en el que necesitemos que coincida alguno
de los campos o columnas con la restriccin a imponer, llamada 'Nonpairwise'. Vamos a citar dos ejemplos, uno para cada tipo.
En primer lugar, hallaremos el nombre, el numero de departamento y
la comisin de aquellos empleados cuyo salario y comisin coinciden
ambos a la vez con el salario y la comisin de algn empleado del
departamento 30:
SELECT ename, deptno, comm
FROM emp
where (sal, nvl(com,-1)) in (SELECT sal, nvl(comm,-1)
FROM emp
WHERE deptno=30);

Este es un ejemplo de Pairwise, en el que las columnas o campos


deben compararse por pares, es decir debe coincidir la pareja de valores de
salario y comisin de un empleado con la pareja salario y comisin de un
empleado del departamento 30. Es de destacar el uso de la funcin NVL
para evitar los valores nulos, ya que cualquier operacin entre dos valores
nulos da como resultado el valor nulo, luego en la comparacin de igualdad
entre dos valores nulos, nos dara falso (null=null ->null -falso-).
Como ejemplo de Nonpairwise, podemos encontrar una consulta
como:
SELECT ename, job

Manual de SQL ORACLE

21
FROM emp
WHERE sal>(SELECT sal
FROM emp
WHERE empno=7566)
AND job like (SELECT job
FROM emp
WHERE empno = 7369);

Anteriormente descrita, y que pretende buscar aquellos empleados


que posean un salario mayor que el salario que gana el empleado nmero
7566 y que tengan el mismo trabajo que el empleado nmero 7369.
Las subconsultas no solo pueden estar en la clusula WHERE,
tambin podemos tener subconsultas dentro de la clusula FROM, donde se
crea una nueva tabla que contendr las columnas y las filas que devuelva la
consulta realizada. Para ilustrar esto, vamos a realizar una consulta que
muestre el nmero de empleado, el departamento al que pertenece, y la
media del salario de dicho departamento. En un principio, podemos pensar
que la siguiente consulta obtiene dichos valores:
SELECT empno, deptno, avg(sal)
FOM emp
GROUP BY empno, deptno;

Pero esto es incorrecto, ya que intentar calcular la media para un


grupo por cada nmero de empleado (empno), y la salida ser incorrecta.
Sin embargo, podemos calcular la media para cada departamento, incluirla
en una tabla, y asociarla con cada empleado. As, deberemos crear la
siguiente consulta:
SELECT empno, deptno, avg.media
FROM emp, (SELECT deptno, avg(sal) media
FROM emp
GROUP BY deptno) avg
WHERE emp.deptno=avg.deptno;

Donde como se puede comprobar, la subconsulta de la clusula


FROM, crea una tabla llamada 'avg', que contiene la media del salario de
cada departamento.
TEMA 8: Operadores de conjunto
En este tema se analizan los operadores de conjunto 'intersect',
'union', 'union all' y 'minus'. Estos operadores, nos permiten tomar las
consultas por conjuntos de tuplas, que tienen varias columnas. As,
podemos hallar la interseccin, la resta, o la union de los elementos de cada
conjunto. La descripcin de cada operacin, es la siguiente:
Manual de SQL ORACLE

22

Intersect: Devuelve los elementos comunes a dos conjuntos,


es decir las tuplas que coinciden en dos consultas distintas.
Hay que tener en cuenta, que para que pueda haber una
interseccin, ambas consultas deben seleccionar las mismas
columnas.
Union / Union all: Estos operadores actan de forma muy
similar, ambos devuelven la salida de una consulta ms la
salida de otra. La diferencia es que el primero, no incluye
elementos repetidos, sin embargo, 'Union all' si incluye estos
elementos repetidos.
Minus: Este operador, devuelve las tuplas de la primera
consulta menos las tuplas de la segunda consulta.
Como ejemplo de consultas, podemos mostrar todos los empleados
que han trabajado en la empresa, ayudndonos de la tabla 'emp_history' que
contiene el historial de todos los trabajadores que hay y han habido en la
empresa, as, tendremos:
SELECT ename,job, deptno
FROM emp
UNION
SELECT name,title,deptid
FROM emp_history;

Otro ejemplo del uso de este tipo de operadores nos permite mostrar
aquellos empleados que estn en ambas tablas a la vez de la siguiente
manera:
SELECT ename,job, deptno
FROM emp
INTERSECT
SELECT name,title,deptid
FROM emp_history;

Tambin podemos encontrar aquellos que tendramos que introducir


en la tabla de la siguiente manera:
SELECT ename,job, deptno
FROM emp
MINUS
SELECT name,title,deptid
FROM emp_history;

As, para realizar este tipo de consultas, tenemos que tener en cuenta
los siguientes puntos:

Manual de SQL ORACLE

23

Las expresiones de las consultas tienen que coincidir en


cantidad y tipo de los datos que se van a mostrar (ej: ename ->
name).
Automticamente en todos los operadores de conjuntos las
filas repetidas son borradas (en la salida y excepto en el
operador 'union all')
Los encabezamientos de las filas que se ofrecen a la salida son
los de la primera consulta realizada.
TEMA 9: Manipulacin de datos
El lenguaje de manipulacin de datos es el que nos permite tanto la
insercin como el borrado de los datos en las tablas de que dispone nuestra
base de datos. Asi, se definen varias ordenes que permiten realizar este tipo
de acciones.
Aadir una nueva fila en la tabla:

INSERT INTO tabla[(columa[, columna,....])]


VALUES (valor[, valor, ......]);
[consulta]
Si se omiten los campos despus del nombre de la tabla, es que
deseamos introducir una fila con todos los campos que contiene la tabla, y
si lo que aadimos es una consulta, se introducen los datos devueltos por
esa consulta.
As, como ejemplo, podemos incluir una fila en la tabla 'dept' que
contenga el nmero de departamento 50, llamado 'development' y
localizado en 'detroit', as deberemos introducir la siguiente orden de
entrada de datos:
INSERT INTO dept(deptno,dname,loc)
VALUES (50,'DEVELOPMENT','DETROIT');
Se pueden crear macros para la introduccin de los datos, y usar asi
variables para la introduccin de estos datos. Para ello, utilizamos el
comando ACCEPT, que nos permite declarar una variable de entorno con
un nombre cualquiera:
ACCEPT nombre_variable PROMPT 'mensaje_introduccin';

Manual de SQL ORACLE

24

Esta orden, nos permite sacar por pantalla el mensaje


'mensaje_introduccin' y despues quedar a la espera de la introduccin del
valor que se asignar a la variable nombre_variable. Asi, un ejemplo de
macro para realizar la introduccin de la fila que se ha introducido antes es:
ACCEPT num_dept PROMPT 'introduzca el nmero de depto.: ';
ACCEPT nom_dept PROMPT 'introduzca el nombre de depto.: ';
ACCEPT loc_dept PROMPT 'introduzca la localizacin de depto.: ';
INSERT INTO dept(deptno,dname,loc)
VALUES (&num_dept,'nom_dept','loc_dept');

Esto provocar la siguiente salida por pantalla:


SQL> @a:/p2ej.sql
introduzca el nmero de depto.: 50
introduzca el nombre de depto.: DEVELOPMENT
introduzca localizacion de depto.: DETROIT
old 2: VALUES (&num_dept,'nom_dept','locdept')
new 2: VALUES (50,'nom_dept','locdept')
1 row created.
SQL>
Habiendo guardado previamente esta macro en el archivo p2ej.sql en
la ruta especificada. Es de destacar, que las variables, se deben referenciar
mediante el '&' delante del nombre de variable y las cadenas adems entre
comillas simples.
Modificacion de datos en la tabla:

Para la modificacin de datos de la tabla se usa el mandato UPDATE


de la siguiente manera:
UPDATE nombre_tabla
SET columna=valor [, columna2=valor2, .....]
[WHERE condicion]
En este caso, substituimos el valor de la columna especificada por el
valor introducido. La sentencia WHERE, es opcional, y si se omite, se
modificarn todos los valores de la(s) columna(s) especificada(s) pero si se
especifica, la modificacin tendr lugar tan solo en la fila que se seleccione
segn la condicin. Tambin es posible especificar una macro que realice

Manual de SQL ORACLE

25

esta accin, de la misma manera en la que se realiz en la sentencia de


manipulacin anterior.
Eliminacin de datos en la tabla:

Para la eliminacin de datos de una tabla de nuestra base de datos, se


utiliza el comando DELETE. La sintaxis de dicho comando es la siguiente:
DELETE [FROM] nombre_tabla
[WHERE condicin];
Este comando posee la posibilidad de borrar una sola fila de la tabla,
aadiendo las opciones FROM, y WHERE, ya que se eliminaran las filas
de la tabla que cumplan la condicin especificada en la sentencia WHERE,
pero si estas opciones no se incluyen, se vaca la tabla al completo.
Existen una serie de ordenes, que nos permiten una gran seguridad
dentro de las bases de datos creadas con Oracle y que son los comandos
commit, savepoint y rollback:
COMMIT: este comando, verifica que las modificaciones
realizadas se guardan en la base de datos. As tras realizar
cualquier cambio en esta, mediante el DML (Data
Modification Languaje) deberemos ejecutar dicho comando.
SAVEPOINT nombre_savepoint: Permite realizar una copia
de seguridad de los datos guardados en las tablas hasta el
momento para luego poder recuperarlos. Se puede indicar el
nombre (por ejemplo la fecha y hora) del punto de guardado.
Mediante otro comando, podemos volver a los datos que
tenamos antes de guardar mediante SAVEPOINT.
ROLLBACK / ROLLBACK TO nombre_savepoint: Permite
volver atrs en los cambios realizados en una tabla. cuando
ejecutamos este comando, deshacemos los cambios realizados
hasta el ltimo savepoint. Si queremos volver atrs hasta un
determinado savepoint, deberemos especificar el savepoint
hasta el que queremos volver, mediante la segunda opcin de
este comando.
Como ejemplo citamos:
SQL> savepoint update_done;
Savepoint created.
SQL> rollback to update_done;

Manual de SQL ORACLE

26

Rollback complete.
SQL>
TEMA 10: Creacin de tablas.
Create table

Para la creacin de tablas, se utiliza la orden CREATE TABLE, que


tiene varias opciones que iremos viendo poco a poco. La sintaxis bsica de
esta orden es:
CREATE TABLE [esquema.]nombre_tabla
[(columna tipo_de_dato [default_expr])];
De esta manera, creamos una tabla con el nombre indicado, y las
columnas indicadas si se desea. Si no se desea definir las columnas se
puede realizar ms adelante con el comando ALTER TABLE que veremos
ms adelante. Los tipos de datos a los que puede pertenecer una columna
son entre otros:
1. VARCHAR2(tamao): texto de tamao variable.
2. CHAR(tamao): carrcter de tamao variable.
3. NUMBER(p,s): nmero de tamao fijo, donde 'p' es el tamao
mximo, y 's' el nmero de bits despus de la coma.
4. DATE: tipo de dato fecha.
5. LONG: Cadena de caracteres de longitud variable hasta 2GB.
6. CLOB: Cadena de caracteres de longitud variable hasta 4GB.
7. RAW y LONG RAW: Datos binarios de tamao pequeo.
8. BLOB: Datos binarios de hasta 4GB.
9. BFILE: Para ficheros externos.
10.BINARY: Para valores binarios (verdadero,falso).
Por ejemplo, podemos citar la orden de creacin de la tabla 'dept',
que es la siguiente:
CREATE TABLE dept
(deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13));
Tambin podemos crear tablas a partir de subconsultas, mediante
esta misma orden, pero en este caso, la sintaxis es la siguiente:

Manual de SQL ORACLE

27

CREATE TABLE AS subconsulta;


Asi se crea una tabla que contiene todas las columnas que devuelva
la consulta realizada en esta orden, y con todas las tuplas que devuelva esta
orden. Como ejemplo vamos a crear una tabla llamada 'dept30' que
contendr todos los empleados de dicho departamento, y las columnas
empno, ename, y sal:
CREATE TABLE deptno30
AS SELECT empno, ename, sal
FROM emp
WHERE deptno=30;
Alter table

Esta orden, nos permite modificar las columnas de una tabla, para
aadir o para modificar el tipo de dato de la columna en cuestin. La
sintaxis de la sentencia ALTER TABLE es la siguiente:
ALTER TABLE nombre_tabla
([ADD (columna tipo_de_dato)],
[MODIFY (columna nuevo_tipo_de_dato)]);
Drop table

Esta elimina la estructura de la tabla por completo, y por tanto la


borra por completo. La sintaxis de esta sentencia es la siguiente:
DROP TABLE nombre_tabla;
Truncate table

Esta orden vaca el contenido de la tabla, es decir borra todas las filas
que contiene, pero deja la estructura. La sintaxis es la siguiente:
TRUNCATE TABLE nombre_tabla;
Rename table

En este caso la orden cambia el nombre de la tabla por el


especificado mediante la siguiente sintxis:

Manual de SQL ORACLE

28

RENAME nombre_tabla_antiguo TO nombre_tabla_nuevo;


Comment on table

En este caso se le aaden comentarios a las tablas, que permiten


describir el contenido de las mismas. Esto se realiza con la orden
Comment, que tiene la siguiente sintaxis:
COMMENT ON TABLE nombre_tabla IS 'comentario de la
tabla';
Restricciones de las tablas (constraints)

Existen varias restricciones posibles para las columnas de las bases


de datos mantenidas por Oracle, estas son llamadas 'constraints' y
permiten cualidades de las columnas de una tabla tales como hacer cumplir
reglas a nivel de tablas, o prevenir el borrado de una tabla si hay
dependencias con otra tabla. Los tipos de restricciones posibles en
Oracle son:
NOT NULL: Especifica que esa columna no debe contener un
valor nulo.
UNIQUE key: Especifica una columna o combinacin de ellas
cuyos valores no deben estar repetidos.
PRIMARY KEY: Especifica que debe ser llave primaria, por
lo tanto, esta, no debe contener valores duplicados, ni poseer
valores nulos.
FOREIGN KEY: Establece y hace cumplir una relacin
fornea entre la columna, y la otra columna referenciada de la
tabla.
CHECK: Especifica una condicin que debe ser cierta.
La sintaxis de creacin de una constraint en una tabla es la siguiente:
CREATE TABLE [esquema.]nombre_tabla
[(columna tipo_de_dato [default_expr]
[constraint de columna],
...........
[constraint de tabla])];

Manual de SQL ORACLE

29

Donde el constraint de columna, es una constraint formada por la


palabra clave constraint, seguido de un nombre orientativo que entra en la
tabla 'user_constraints' (esto es opcional pero recomendable), y despus el
tipo_constraint, que es uno de los tipos antes definidos (NOT NULL,
PRIMARY KEY,.....) de la siguiente manera:
[CONSTRAINT constraint_name] tipo_constraint,
Las constraints de tabla, no incluyen la constraint NOT NULL, van
siempre al final, y el aadir el nombre de la constraint es tambin opcional.
Se forma mediante la palabra reservada CONSTRAINT y el nombre de
constraint (opcional), despus el tipo de constraint a aplicar (excepto NOT
NULL) y entre parntesis el nombre de la columna a la que se aplica dicha
constraint. Hay que tener en cuenta que estos tipos de constraints se ponen
siempre despus de haber definido todas las columnas de la tabla:
[CONSTRAINT constraint_name] tipo_constraint
(nombre_columna,...),
As como ejemplo, introduciremos la constraint que posee la tabla
dept, que es NOT NULL en la columna 'deptno' de la siguiente manera:
CREATE TABLE dept
(deptno NUMBER(2) CONSTRAINT dept_nn NOT NULL,
dname VARCHAR2(14),
loc VARCHAR2(13));
Por otro lado, podemos definir algunas de las constraints de la tabla
emp de la siguiente manera:
CREATE TABLE emp
(empno NUMBER(4),
ename VARCHAR2(10),
....
deptno NUMBER(7,2) NOT NULL,
CONSTRAINT emp_empno_pk
PRIMARY KEY (empno)
CONSTRAINT emp_deptno_fk
FOREIGN KEY (deptno)
REFERENCES dept (deptno)
CONSTRAINT emp_deptno_ck CHECK

Manual de SQL ORACLE

30

(deptno BETWEEN 10 AND 99));

Se puede observar que todas estas son lneas de la creacin de una


tabla, que por lo tanto pueden aadirse mediante la orden ALTER TABLE,
para aadir dichas constraints posteriormente a las tablas. As podramos
poner tambin, una vez creada la tabla sin constraints:
ALTER TABLE emp
ADD CONSTRAINT emp_empno_pk
PRIMARY KEY (empno);
Para borrar cualquier constraint, se utiliza la orden ALTER TABLE,
que acta de igual manera que anteriormente, pero ahora, deberemos
indicar que queremos borrar y la constraint que queremos borrar, mediante
el nombre que le hemos asociado. As, la orden de borrado de esta ltima
constraint 'emp_empno_pk' es:
ALTER TABLE emp
DROP CONSTRAINT emp_empno_pk;
Tambin podemos deshabilitar dicha constraint, en vez de borrarla,
mediante la siguiente orden:
ALTER TABLE emp
DISABLE CONSTRAINT emp_empno_pk;

TEMA 11: Vistas y secuencias. Objetos de la base de datos.


Dentro de los objetos de una base de datos de Oracle, hemos visto
tan solo las tablas, pero tambin existen objetos tales como vistas,
secuencias, ndices y sinnimos. En este documento nos centraremos tan
solo en las tablas, como ya se ha hecho, en las vistas y secuencias.
Vistas

Una vista crea un subconjunto de datos a partir de una tabla. Sirve


para tener un acceso ms rpido a una determinada tabla, para dar acceso
solo de lectura a un usuario de las tablas etc. Existen dos tipos de vistas ,
simples y compuestas.
Las vistas simples, contienen una sola tabla, y no contiene funciones,
ni grupos de datos, as como DML (data modification languaje) a travs de
Manual de SQL ORACLE

31

la vista. En cambio, las vistas complejas, contienen ms de una tabla, y


contienen el resto de caractersticas antes mencionadas.
La orden de creacin de una vista es mediante la orden CREATE,
vista anteriormente. As la sintaxis es la siguiente:
CREATE [OR REPLACE] [FORCE|NO FORCE] VIEW
nombre_vista AS (subconsulta)
[WITH CHECK OPTION [CONSTRAINT constraint]]
[WITH READ ONLY];
Las opciones dignas de comentario, son:
OR REPLACE: vuelve a crear la vista, incluso si esta existe o
no.
FORCE | NO FORCE: Crea la vista incluso si las tablas base
de la consulta que se realiza existen o no (en el caso de que
incluyamos FORCE) o no crea la vista en caso de que no
existan dichas tablas (si incluimos la opcin NO FORCE).
WITH CHECK OPTION: Especifica que solo las filas
accesibles a la vista, pueden ser insertadas o modificadas.
WITH READ ONLY: Asegura que ningn tipo de DML
puede ser utilizado en esta vista (luego ninguna modificacin
de los datos puede ser realizada).
As como ejemplo vamos a crear una vista llamada EMPVU10 que
contenga el numero de empleado, el nombre y el trabajo, de todos los
empleados que pertenecen al departamento 10.
CREATE OR REPLACE VIEW empvu10 AS
SELECT empno, ename, job
FROM emp
WHERE deptno=10;
De esta manera creamos una vista con las caractersticas antes
mencionadas. Para ver el contenido de dichas vistas, utilizamos una orden
SELECT en la que el nombre de la tabla ser un nombre de vista. Tambin
podemos ver la estructura de una vista mediante la orden DESCRIBE. Para
ver las vistas que tenemos creadas, existe la tabla user_views, en cuya
columna view_name, podemos encontrar todos los nombres de vistas que
tengamos creadas.
Una vista compuesta puede ser una vista tal como la siguiente:
CREATE VIEW dept_sum_vu (name,minsal,avgsal)
Manual de SQL ORACLE

32

AS SELECT d.dname, MIN(e.sal), MAX(e.sal), AVG(e.sal)


FROM emp e, dept d
WHERE e.deptno=d.deptno
GROUP BY d.dname;
Orden que crea una vista que contendr un campo (columna) que
ser el nombre de departamento, otra columna con el salario mnimo del
departamento, otra con el salario mximo del departamento y otra con la
media del salario del departamento.
Se pueden usar operaciones DML en vistas simples. No se pueden
borrar filas si contienen funciones de grupo, una clusula GROUP BY o la
palabra clave DISTINCT.
Para borrar una vista, se utiliza la orden DROP VIEW nombre_vista.
Secuencias

Una secuencia genera automticamente nmeros consecutivos. Es un


objeto ocultable y tpicamente usado para crear valores de llaves primarias.
Se crean mediante la orden CREATE con la siguiente sintaxis.
n]

CREATE SEQUENCE nombre_secuencia [INCREMENT BY


[START WITH n]
[MAXVALUE n | NOMAXVALUE]
[MINVALUE n | NOMINVALUE]
[CYCLE | NOCYCLE];

Por la simple traduccin de las palabras clave que se usan como


opciones de la sentencia de creacin, podemos determinar la funcin de las
mismas. Como ejemplo vamos a crear una secuencia llamada dept_deptno
usada por la primary key de la tabla dept:
CREATE SEQUENCE dept_deptno
INCREMENT BY 1
START WITH 91
MAXVALUE 100
NOCACHE
NOCYCLE;
Para hacer referencia a los valores de una secuencia, deberemos
introducir el nombre de la secuencia, seguido de un punto, y despus una
de las siguientes opciones:
NEXTVAL: Accede al prximo valor disponible.

Manual de SQL ORACLE

33

CURRVAL: El valor actual en el que se encuentra la


secuencia.
Como ejemplo utilizaremos la secuencia para aadir una nueva fila a
la tabla dept utilizando la secuencia antes creada.
INSERT INTO dept(deptno, dname, loc)
VALUES (dept_deptno.NEXTVAL, 'MARKETING','SAN
DIEGO');
Para ver el valor actual de la secuencia que deseemos, tan solo
deberemos realizar una consulta con la tabla 'DUAL', en la que
referenciemos el valor actual de una secuencia, es decir, para consultar el
valor actual de la secuencia que acabamos de crear, deberemos introducir la
siguiente orden:
SELECT dept_deptno.CURRVAL
FROM dual;
Tambien es posible tanto la modificacin de la secuencia, as como
el borrado de la misma, mediante las ordenes ALTER SEQUENCE y
DROP SEQUENCE.
TEMA 12: Bloques PL/SQL bsicos.
Esta leccin presenta la estructura bsica de un bloque de cdigo
PL/SQL. Estos bloques de cdigo son una especie de scripts, que se
transfieren por completo al SGBD y son ejecutados por completo, lo cual
permite una secuenciacin entre las distintas consultas y acciones sobre la
base de datos. La estructura bsica de un bloque de cdigo SQL consta de
las siguientes dos partes principales que comienzan con las siguientes
palabras reservadas:
'DECLARE' (opcional): A Partir de esta se declaran las
variables, los cursores, y las excepciones (errores) declaradas
por el usuario.
'BEGIN': Despus de esta palabra, comienza la segunda parte
y en ella se incluyen los mandatos SQL y PL/SQL.
'EXCEPTION' (opcional): A partir de esta palabra reservada
se incluye la definicin de las excepciones del bloque
PL/SQL.
'END;' : Esta es la palabra final despus de la cual, no hay ms
cdigo.
Manual de SQL ORACLE

34

Se debe colocar un punto y coma (;) despus de cada sentencia SQL


o PL/SQL y una barra invertida (/) para poder ejecutar el bloque.
Existen varios tipos de bloques PL/SQL, annimos, procedimientos
y funciones. Los bloques annimos son bloques sin nombre empotrados
dentro de una aplicacin o emitidos para su ejecucin interactivamente. El
resto, tanto los procedimientos, como las funciones, son bloques de cdigo
PL/SQL que quedan grabados en el servidor de Oracle, pueden ser
invocados repetidamente por su nombre y pueden aceptar parmetros.
Comencemos describiendo las variables. Estas son utilizadas para
guardar datos temporalmente, manipular estos datos etc. Para su
manipulacin, debemos declararlas, le asignamos un valor, pasamos los
valores y vemos los resultados. Tambin se pueden declarar variables
globales, lo cual se realiza antes de la palabra reservada DECLARE. Para
la declaracin de variables se usa la siguiente sintaxis:
nombre_variable tipo_de_dato;
Y para las variables globales (BIND), se realiza mediante la
siguiente sintaxis:
VARIABLE nombre_variable tipo_de_dato
Este tipo de variables, se declaran fuera del bloque de cdigo
PL/SQL, y se pueden referenciar dentro de este poniendo dos puntos antes
del nombre de la variable.
El operador de asignacin de valores a una variable es ':=', poniendo
primero el nombre de la variable a la cual queremos asignar el valor,
despus el smbolo ':=' y despus el valor que queremos asignarle, que
puede ser el valor de otra variable por ejemplo.
Para imprimir por pantalla, siempre hay que declarar variables
globales, y estas se referencian dentro del bloque PL/SQL aadiendo dos
puntos (:) antes del nombre de la variable, ej: ':v_ejemplo'. El resto de las
variables no pueden ser aceptadas como parmetro de la orden 'PRINT' (La
orden PRINT, seguida de un nombre de variable y un punto y coma
muestra el contenido de la variable por pantalla, y el nombre de la variable
que posee dicho valor.).
El uso de las variables esta restringido nicamente por el tipo de
datos al que pertenece una determinada variable. Es decir, es importante
asignar a una variable, datos del tipo al cual pertenecen, por lo que es til la
utilizacin de funciones antes comentadas como 'to_char()', para pasar un
tipo de dato fecha ('date') a cadena por ejemplo si vamos a asignarlo a una

Manual de SQL ORACLE

35

cadena. Por ejemplo, si declaramos la variable 'v_cadena' de tipo varchar2


as:
DECLARE
v_cadena varchar2(30);
.........
Y a continuacin escribimos en la parte de cdigo ejecutable:
BEGIN
v_cadena:='Anderson'||':'||sysdate;
...........
Esto dara un error, ya que sysdate, es de tipo 'date', con lo que el
bloque no se ejecutara correctamente. As, la correcta formulacin que
deberamos realizar para esta accin sera:
BEGIN
v_cadena:='Anderson'||':'||to_char(sysdate);
...........
Ntese que se han utilizado comillas simples para delimitar los
valores de cadenas constantes, el operador '||' para concatenar cadenas, y un
punto y coma al final de la sentencia.
Hasta aqu se ha visto lo mas importante que debemos saber sobre
las variables, a partir de ahora describiremos las acciones bsicas que se
pueden realizar con un bloque de cdigo PL/SQL.
Los bloques de cdigo se pueden anidar. Es decir podemos incluir
un bloque de PL/SQL dentro de otro, pero hay que tener cuidado con el
mbito de las variables que declaramos, es decir, las variables declaradas
en el bloque ms exterior, se 'ven' dentro de los bloques de cdigo
interiores, pero esto no es cierto al contrario, es decir, las variables de los
bloques interiores, no pueden referenciarse por los bloques externos.
La orden para pedir datos por pantalla se ha explicado en temas
anteriores, esta es la orden 'accept' que debe ponerse fuera de los bloques
PL/SQL, con la siguiente sintaxis:
ACCEPT nombre_variable PROMPT 'mensaje_introduccin';
De esta manera se introducen datos en una variable de entorno, que
podemos utilizar luego. Para borrar todas las variables de entorno que
tengamos creadas, deberemos introducir la orden 'set verify off'. Para
referenciarlas, se incluye un '&' antes del nombre de dicha variable.

Manual de SQL ORACLE

36

Para la salida de datos por pantalla, se utiliza la orden


dbms_output.put_line con la siguiente sintaxis:
a});

dbms_output.put_line({'cadena_a_mostrar',variable_de_caden

Dentro de los bloques de PL/SQL, podemos escribir diferentes tipos


de consultas. El mandato select que podemos introducir dentro de un
bloque de cdigo debe incluir despus de la lista de columnas a mostrar
(SELECT *) la palabra reservada INTO nombre_variable, para introducir
los datos dentro de la variable que se especifique. As la sintaxis de un
mandato select bsico queda de la siguiente manera:
SELECT [DISTINCT] {*, columna [alias],...}
INTO {lista_de variables}
FROM nombre_tabla
[WHERE condition(s)];
As, podemos deducir que la lista de variables, debe corresponderse
con el nmero y el tipo de las columnas que estemos seleccionando, para
que sean asignadas a las variables correctamente. Tambin debemos notar
que estos mandatos select, deben devolver tan solo una fila, es decir que
debemos incluir una condicin que haga que la consulta devuelva una sola
fila en el momento de ser ejecutada.
Ahora ya estamos preparados para ver el primer ejemplo de bloque
PL/SQL mediante el cual obtendremos el nmero y la localizacin de el
departamento de ventas (sales) de la tabla dept as:
DECLARE
v_deptno dept.deptno%TYPE;
v_loc dept.loc%TYPE;
BEGIN
select deptno,loc
into v_deptno,v_loc
from dept
where dname='SALES';
dbms_output.put_line(v_deptno);
dbms_output.put_line(v_loc);
END;
/
Que ofrece a la salida el siguiente mensaje:

Manual de SQL ORACLE

37

SQL> @a:/plsql1.sql
30
CHICAGO
PL/SQL procedure successfully completed.
SQL>
Se debe de destacar que el tipo de dato al cual pertenecen las
variables declaradas v_deptno y v_loc, es el tipo de dato de las variables
detpno y loc de la tabla dept.
Vamos a realizar ahora una insercin de datos en una tabla mediante
un bloque PL/SQL para ver ms ejemplos:
DECLARE
v_empno emp.empno%TYPE;
BEGIN
select empno_secuence.NEXTVAL
into v_empno
from dual;
insert into emp(empno, ename, job, deptno)
values (v_empno,'Harding','clerk', 10);
END;
/
Suponiendo que ya tenemos creada la secuencia empno_sequence,
que nos devuelve el valor correcto de nmero de empleado. Es de notar el
uso de la variable declarada como valor a introducir en la orden insert.
Dentro de las ordenes de un bloque PL/SQL tambin existen
sentencias de control del flujo del programa y dentro de ellas vamos a
comenzar con el mandato IF. Este mandato tiene la siguiente sintaxis:
IF condicin THEN
sentencias_1;
[ELSIF condicin THEN
sentencias_2;]
[ELSE
sentencias_3;]
ENDIF;
Siendo el control de flujo el mismo para todos los lenguajes que
poseen una sentencia de bifurcacin condicional, es decir , se ejecutarn
la(s) sentencia(s) 1 en caso de cumplirse las primeras condiciones, o las

Manual de SQL ORACLE

38

sentencias 2 en caso de que se cumplan las segundas condiciones, o si no se


cumplen ningunas de las condiciones, se ejecutaran las sentencias 3.
As, podemos realizar bloques de cdigo que realicen acciones en
funcin de el cumplimiento de ciertas condiciones.
Otro tipo de sentencias de control del flujo de ejecucin son los
bucles, dentro de los cuales podemos encontrar bucles tales como LOOP,
FOR y WHILE. La sintaxis de estos bloques de cdigo es la siguiente:
LOOP
sentencias:
...
EXIT [WHEN condicin];
END LOOP;
Para la orden FOR tenemos la siguiente sintaxis:
FOR contador IN [REVERSE] limite_inferior..limite_superior
LOOP
sentencias;
...
END LOOP;
Y para la orden WHILE tenemos la siguiente sintaxis:
WHILE condicion LOOP
sentencias;
...
LOOP;
TEMA 13: Tipos de datos compuestos
Existen dos tipos de datos compuestos que son:
RECORDS: Son un tipo de datos definido por el usuario, que
contiene varias variables en una sola estrucutura. Es similar a
un 'struct' de C.
TABLES: Son un tipo de dato similar a una tabla, o a un array,
en el que se introducen datos de un solo tipo y luego podemos
acceder a ellos segun un ndice.
As, la sintaxis para definir estos tipos de datos es la siguiente, para
los records:

Manual de SQL ORACLE

39

TYPE type_name IS RECORD


(nombre_variable1 tipo_de_dato,
[nombre_variable2 tipo_de_dato,...]);
Y para declarar un record de ese tipo se pone:
nombre_record type_name;
En ese momento ya podemos utilizar el record mediante la inclusin
de un punto, seguido del nombre de la variable que deseamos acceder.
Para las TABLES, que son parecidas a los arrays, tenemos la
siguiente sintaxis:
TYPE type_name IS TABLE OF
{(tipo_columna),variable%TYPE}
[INDEX BY BINARY INTEGER];
As, tenemos un array al cual podemos acceder mediante un ndice
que se pone entre parntesis. Tambin tenemos una serie de mtodos
asociados a las TABLES, que nos permiten realizar acciones como:
EXISTS(n): devuelve verdadero si el valor del ndice que
contenga no el nulo, es decir tiene asignado algn valor.
COUNT: devuelve el nmero de elementos que posee la Table
FIRST and LAST: Devuelve el valor final o el inicial,
dependiendo del mtodo utilizado.
PRIOR(n): Devuelve el elemento anterior al indicado en el
ndice.
NEXT(n): Devuelve el siguiente elemento del indicado por el
ndice.
EXTEND(n,i): agrega valores 'i', a partir de 'n'.
TRIM(n): Elimina los 'n' ltimos valores.
DELETE[(n,m)]: Si no lleva ndices, vaca la TABLE entera,
si lleva un solo ndice borra el elemento indicado, y si lleva los
dos ndices, borra desde el indice 'n' hasta el ndice 'm'.
Vamos a ver dos ejemplos de utilizacin de estos tipos de datos.
Para los tipos de datos RECORD, declararemos uno que almacenar el
nombre, el trabajo, u el salario, de un nuevo empleado:
TYPE emp_record_type IS RECORD
(ename VARCHAR2(10),
Manual de SQL ORACLE

40

job VARCHAR2(9),
sal NUMBER(7,2));
En este momento tendramos definido el tipo de dato
emp_record_type, y ahora crearamos una instancia de ese tipo de dato
llamado emp_record:
emp_record emp_record_type;
Para el uso de los distintos campos que contiene la variable que
acabamos de declarar, podemos acceder por ejemplo al nombre de la
siguiente manera: 'emp_record.ename'.
Existe un atributo especial, llamado %ROWTYPE que recoge un
dato que puede poseer ms de un atributo y asignarlo a un tipo record, as,
para crear un record con todas las variables necesarias para guardar una fila
completa de la tabla dept, deberamos poner:
dept_record dept%ROWTYPE;
Para declarar una table, seguiremos la sintaxis antes definida, y
crearemos una table para almacenar nombres de empleados contenidos en
la tabla emp as:
TYPE ename_table_type IS TABLE OF emp.ename%TYPE
INDEX BY BINARY_INTEGER;
Ya tendramos creado el tipo de TABLE ename_table_type, que
ahora es un tipo de dato ms, y ahora necesitamos una instancia, o variable
de ese tipo, as:
ename_table ename_table_type;
Ahora nos referiremos a los distintos elementos de dicha variable as
ename_table(1):='Cameron';
O tambin podremos acceder a alguno de los mtodos antes
especificados para realizar acciones como la siguiente:
IF ename_table.EXISTS(1) THEN
INSERT INTO...........

Manual de SQL ORACLE

41

TEMA 14: Cursores


Un Cursor es un rea de trabajo de SQL. Cuando emitimos una
sentencia SQL, el servidor de Oracle abre un rea de memoria, en la que el
comando es analizado y ejecutado, este rea es llamada cursor. Cuando la
parte ejecutable de un bloque emite una sentencia SQL, PL/SQL crea un
cursor implcito, que tiene el identificador 'SQL'. Oracle cuenta con dos
tipos de cursores, los explcitos y los implcitos, los implcitos estn
definidos por el identificador 'SQL', y posee atributos que entre otros son:
SQL%ROWCOUNT: cuenta el nmero de filas que fueron
accedidas en la ltima operacin.
SQL%FOUND: Posee el valor TRUE si el cursor anterior es
igual o mayor que uno, es decir, que se pone a valor TRUE si
se a accedido a alguna fila.
SQL%NOTFOUND: Poseer el valor TRUE en el caso de que
el cursor anterior tenga el valor FALSE, es decir este cursor
toma el valor TRUE si en la ltima operacin no se accedi a
ninguna fila.
SQL%ISOPEN: Posee siempre el valor FALSO, porque
PL/SQL cierra los cursores explcitos inmediatamente despus
de ser ejecutados.
Como ejemplo de uso de un cursor explcito, expongo el siguiente
boque PL/SQL que imprime el nmero de columnas que han sido borradas:
VARIABLE rows_deleted NUMBER
DECLARE
v_ordid NUMBER:=605;
BEGIN
DELETE FROM item
WHERE ordid=v_ordid;
:rows_deleted:=SQL%ROWCOUNT;
END;
/
PRINT rows_deleted
Los cursores explcitos sin embargo, son definidos por el usuario, y a
la zona de memoria, le asignamos una sentencia SELECT. Para controlar
un cursor explcito, debemos seguir los siguientes pasos:
1. Declaramos el cursor en DECLARE.
2. Se abre el cursor con OPEN, y estamos en la primera posicin.
Manual de SQL ORACLE

42

3. Leemos la primera fila con FETCH.


4. Comprobamos si ha ledo algo, y cerramos el cursor con
CLOSE.
La sintaxis de declaracin de un cursor, es la siguiente:
CURSOR nombre_cursor IS
SELECT [lista_de variables]
FROM nombre_tabla;
Donde la sentencia SELECT, es una sentencia cualquiera, que puede
incluir cualquier tipo de restriccin. La sintaxis de las ordenes open y close
es:
OPEN nombre_cursor;
CLOSE nombre_cursor;
Cuando queramos recuperar informacin del cursor, deberemos
utilizar la orden FETCH, con la siguiente sintaxis:
FETCH nombre_cursor INTO variable1, variable2,.....;
Orden que devolver una fila cada vez que sea ejecutada, y avanzar
a la siguiente posicin dentro de las filas que devuelve la consulta
especificada en la declaracin del cursor. El funcionamiento de los
atributos de los cursores vistos anteriormente (%ROWCOUNT, %FOUND,
%NOTFOUND, %ISOPEN) es similar, solo que el valor de %ISOPEN,
puede ser TRUE en este caso si el cursor esta abierto.
Existe un tipo de bucle para los cursores, que ejecuta
automticamente las ordenes OPEN, CLOSE y FETCH, y es el bucle FOR,
cuya sintaxis es la siguiente:
FOR record_name IN cursor_name LOOP
statements;
.......
END LOOP;
En caso de no usar este bucle, se debera especificar la condicin de
salida que puede ser cuando el cursor haya recorrido todas las filas, en ese
caso, la condicion sera:
EXIT WHEN nombre_cursor%NOTFOUND;

Manual de SQL ORACLE

43

Por ejemplo, voy a escribir dos formas de realizar la misma accin,


una mediante el bucle FOR antes mencionado, y otra mediante la forma
clsica, as, mediante la forma clsica, podramos hacer:
DECLARE
CURSOR c1 IS
SELECT empno, ename
FROM emp;
emp_record c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO emp_record;
dbms_output.put_line(to_char(emp_record.empno));
dbms_output.put_line(emp_record.ename);
EXIT WHEN c1%NOTFOUND;
END LOOP;
CLOSE c1;
END;
/
Sin embargo, esto puede realizarse de forma mucho ms sencilla,
utilizando el bucle LOOP de la siguiente manera:
DECLARE
CURSOR c1 IS
SELECT empno, ename
FROM emp;
emp_record c1%ROWTYPE;
BEGIN
FOR emp_record IN c1 LOOP
dbms_output.put_line(to_char(emp_record.empno));
dbms_output.put_line(emp_record.ename);
END LOOP;
END;
/

Manual de SQL ORACLE

También podría gustarte