Está en la página 1de 84

http://desarrolloweb.com/manuales/tutorial-oracle.

html Página 1 de 84
Introducción: Tutorial de Oracle

Oracle es uno de los sistemas gestores de bases de datos más potentes del mercado. Es un
sistema comercial con cualidades empresariales, muy usado en todo el mundo.

En este tutorial aprenderas a gestionar bases de datos con Oracle y administrar el sistema
gestor de base de datos, para realizar configuraciones y usos de todo tipo.

No busca ser un manual exahustivo, pues Oracle es uno de los sistemas de bases de datos más
complejos y sería complicado abarcarlo todo, pero al menos sí ofrece una introducción a los
asuntos más importantes, que se abordan en las formaciones de Oracle.

Encuentras este manual online en:


http://desarrolloweb.com/manuales/tutorial-oracle.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 2 de 84
Autores del manual

Las siguientes personas han participado como autores escribiendo artículos de este manual.

Sara Alvarez

Equipo DesarrolloWeb.com

Agustin Jareño

Russvell Oblitas Valenzuela

Bch. Sistemas e Informática

Claudio

David Masip

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 3 de 84
Qué es Oracle

Oracle es una potente herramienta cliente/servidor para la gestión de Bases de Datos.


Explicamos la herramienta y las ayudas que ofrece al desarrollador.

Para ver este vídeo es necesario visitar el artículo original en:


https://desarrolloweb.com/articulos/840.php

Oracle es básicamente una herramienta cliente/servidor para la gestión de Bases de Datos. Es


un producto vendido a nivel mundial, aunque la gran potencia que tiene y su elevado precio
hace que sólo se vea en empresas muy grandes y multinacionales, por norma general. En el
desarrollo de páginas web pasa lo mismo: como es un sistema muy caro no está tan extendido
como otras bases de datos, por ejemplo, Access, MySQL, SQL Server, etc.

Vamos ahora en centrarnos en que es Oracle exactamente y como funciona la programación


sobre éste. Oracle como antes he mencionado se basa en la tecnología cliente/servidor, pues
bien, para su utilización primero sería necesario la instalación de la herramienta servidor
(Oracle 8i) y posteriormente podríamos atacar a la base de datos desde otros equipos con
herramientas de desarrollo como Oracle Designer y Oracle Developer, que son las
herramientas básicas de programación sobre Oracle.

Para desarrollar en Oracle utilizamos PL/SQL un lenguaje de 5ª generación, bastante potente


para tratar y gestionar la base de datos, también por norma general se suele utilizar SQL al
crear un formulario.

Nota: Podemos aprender qué es el lenguaje SQL en un artículo de DesarrolloWeb.com.


Además, existe un manual de SQL para el que desee profundizar.

Es posible lógicamente atacar a la base de datos a través del SQL plus incorporado en el
paquete de programas Oracle para poder realizar consultas, utilizando el lenguaje SQL.

El Developer es una herramienta que nos permite crear formularios en local, es decir,
mediante esta herramienta nosotros podemos crear formularios, compilarlos y ejecutarlos,

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 4 de 84
pero si queremos que los otros trabajen sobre este formulario deberemos copiarlo
regularmente en una carpeta compartida para todos, de modo que, cuando quieran realizar un
cambio, deberán copiarlo de dicha carpeta y luego volverlo a subir a la carpeta. Este sistema
como podemos observar es bastante engorroso y poco fiable pues es bastante normal que las
versiones se pierdan y se machaquen con frecuencia. La principal ventaja de esta herramienta
es que es bastante intuitiva y dispone de un modo que nos permite componer el formulario, tal
y como lo haríamos en Visual Basic o en Visual C, esto es muy de agradecer.

Los problemas anteriores quedan totalmente resueltos con Designer que es una herramienta
que se conecta a la base de datos y por tanto creamos los formularios en ella, de esta manera
todo el mundo se conecta mediante Designer a la aplicación que contiene todos los formularios
y no hay problemas de diferentes versiones, esto es muy útil y perfecto para evitar machacar el
trabajo de otros. Pero el principal y más notable problema es la falta de un entorno visual para
diseñar el formulario, es decir, nos aparece una estructura como de árbol en la cual insertamos
un formulario, a la vez dentro de éste insertamos bloques o módulos que son las estructuras
que contendrán los elementos del formularios, que pueden estar basados en tablas o no.

Por lo tanto si queremos hacer formularios para practicar o para probar qué es esto de Oracle,
os recomiendo que uséis Developer pues es mucho más fácil e intuitivo al principio.

Este artículo es obra de David Masip


Fue publicado / actualizado en 19/07/2002
Disponible online en https://desarrolloweb.com/articulos/840.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 5 de 84
SQL con Oracle

Empezamos un nuevo curso sobre SQL con Oracle que puede resultar muy interesante para
ampliar los conocimientos de SQL que habíamos adquirido anteriormente.

Introducción:
Antes de empezar me gustaría decir que este curso esta basado en Oracle, es decir los ejemplos
expuestos y material se han utilizado sobre Oracle. Por otro lado decir que pienso que es
interesante saber algo de SQL antes de comenzar con MYSQL, ya que, aunque existen algunos
cambios insignificantes, sabiendo manejar SQL sabes manejar MYSQL.

Algunas caracteristicas:
SQL: Structured query language.

Permite la comunicación con el sistema gestor de base de datos.

En su uso se puede especificar que quiere el usuario.

Permite hacer consulta de datos.

Tipos de datos:

CHAR:

Tienen una longitud fija.

Almacena de 1 a 255.

Si se introduce una cadena de menos longitud que la definida se rellenara con blancos a
la derecha hasta quedar completada.

Si se introduce una cadena de mayor longitud que la fijada nos dará un error.

VARCHAR:

Almacena cadenas de longitud variable.

La longitud máxima es de 2000 caracteres.

Si se introduce una cadena de menor longitud que la que esta definida, se almacena con
esa longitud y no se rellenara con blancos ni con ningún otro carácter a la derecha hasta
completar la longitud definida.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 6 de 84
Si se introduce una cadena de mayor longitud que la fijada, nos dará un error

NUMBER:

Se almacenan tanto enteros como decimales.

Number (precisión, escala)

Ejemplo:

X=number (7,2)

X=155'862 à Error ya que solo puede tomar 2 decimales

X= 155'86 à Bien

| Nota: El rango máximo va de 1 a 38. |

LONG:

No almacena números de gran tamaño, sino cadenas de caracteres de hasta 2 GB

DATE:

Almacena la fecha. Se almacena de la siguiente forma:

Siglo/Año/Mes/Día/Hora/Minutos/Segundos

RAW:

Almacena cadenas de Bytes (gráficos, sonidos…)

LONGRAW:

Como el anterior pero con mayor capacidad.

ROWID:

Posición interna de cada una de las columnas de las tablas.


Sentencias de consultas de datos

Select:

Select [ALL | Distinct] [expresión_columna1, expresión_columna2, …., | *]

From [nombre1, nombre_tabla1, …, nombre_tablan]

{[Where condición]

[Order By expresión_columna [Desc | Asc]…]};

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 7 de 84
Vamos a explicar como leer la consulta anterior y así seguir la pauta para todas las demás.
Cuando ponemos [] significa que debemos la que va dentro debe existir, y si además ponemos |
significa que deberemos elegir un valor de los que ponemos y no mas de uno. En cambio si
ponemos {} significa que lo que va dentro de las llaves puede ir o no, es decir es opcional y se
pondrá según la consulta.

Nota: En el select el valor por defecto entre ALL y DISTINCT es ALL.

Alias = El nuevo nombre que se le da a una tabla. Se pondrá entre comillas

Order By = Ordena ascendentemente (Asc) (valor por defecto) o descendentemente


(Desc).

All = Recupera todas las filas de la tabla aunque estén repetidas.

Distinct = Solo recupera las filas que son distintas.

Desc Emple; = Nos da un resumen de la tabla y sus columnas. En este caso de la tabla
Emple.

Not Null= Si aparece en una lista de una columna significa que la columna no puede
tener valores nulos.

Null= Si está nulo.

Nota: Nótese que cada consulta de SQL que hagamos hemos de terminarla con un punto y
coma ";".

Varios ejemplos para verlo mas claro:

SELECT JUGADOR_NO, APELLIDO, POSICION, EQUIPO

FROM JUGADORES

WHERE EQUIPO_NO = 'VALENCIA'

ORDER BY APELLIDO;

Este ejemplo mostrar el número de jugador (jugador_no) el apellido (Apellido), la posición en


la que juega (Posición), y el equipo (Equipo) al que pertenece. Seleccionara todos los datos de
la tabla jugadores donde (Where) el nombre de equipo (Equipo_No) sea igual que la palabra

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 8 de 84
'Valencia' y se ordenara (order by) apellido. Notemos también que no pone ni 'Distinct' ni 'All'.
Por defecto generara la sentencia con ALL.

SELECT *

FROM JUGADORES

WHERE POSICION = 'DELANTERO'

ORDER BY JUGADOR_NO;

Este ejemplo muestra todos los campos de la tabla jugadores donde (Where) la posición sea
igual que 'Delantero' y lo ordena por número de jugador. Al no poner nada se presupone que es
ascendentemente (Asc).

SELECT *

FROM JUGADORES

WHERE EQUIPO_NO = 'VALENCIA' AND POSICION = 'DELANTERO'

ORDER BY APELLIDO DESC, JUGADOR_NO ASC;

En este ejemplo selecciona todos los campos de la tabla jugadores donde (Where) el nombre
del equipo sea igual a 'Valencia' y la posición de los jugadores sea igual a 'Delantero'. Por
ultimo los ordena por 'Apellido' descendentemente y por numero de jugador ascendentemente.

Si quieres profundizar más en el sistema gestor de base de datos Oracle te recomendamos


nuestro Tutorial de Oracle.

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 11/03/2005
Disponible online en https://desarrolloweb.com/articulos/1869.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 9 de 84
Instalar Oracle Database 10g Express

Pasamos a describir los pasos necesarios para instalar el sistema gestor de base de datos Oracle
Database 10g Express.

Vamos a guiar a los lectores de DesarrolloWeb.com a través de la instalación de Oracle


Database 10g Express, para que podáis tener el sistema gestor de base de datos y realizar
pruebas desde un navegador antes de instalarlo en un servidor en producción.

Lo primero que tenemos que hacer es descargar los archivos de instalación del sistema gestor
de bases de datos. Para ello accedemos a la página oficial de Oracle y nos descargamos el
archivo Oracle Database 10g Express Edition (Universal) de esta URL. La página de Oracle
solicitará nuestro registro para realizar la descarga, pues tenemos que ser usuarios registrados
para poder bajarlo. En realidad se tarda dos minutos en registrarse.

Una vez descargado, iniciamos la instalación y lo primero que nos pedirá sera introducir una
contraseña para el usuario sys y el system (implementa la misma a los dos usuarios por
defecto). Podemos elegir cualquier clave, además siendo una instalación en local tiene menos
importancia que sea segura. De cualquier modo, lo que sí es importante es que la recodemos,
así que no estará de más el apuntar dicha contraseña en algún lugar, ya que más adelante la
necesitaremos.

Una vez instalado el sistema gestor, podemos acceder a nuestra base de datos online a través
de tu menú inicio / programas / base de datos Oracle. En este menú podemos iniciar los
servicios de Oracle, iniciar el sql *plus, así como dirigirnos a la página de inicio de nuestra base
de datos.

Es importante tener arrancados los servicios relacionados con la base de datos Oracle, ya que
si no lo están, la base de datos no funcionará. Pero cabe comentar por otro lado, que tener los
servicios funcionando come muchos recursos, por lo que os recomiendo que, cuando no estáis
utilizando la base de datos Oracle, paréis los servicios.

La puesta en marcha o parado de los servicios relacionados con la base de datos Oracle se
puede hacer desde el panel de control / herramientas administrativas / servicios. Entonces
tenéis que buscar los servicios que se llaman Oracleservicesxe y OracleXETNSListener y
cambiarlos a manual, para así poderlos arrancar y parar cuando vosotros queráis.

Ahora podemos irnos a la pagina de inicio de nuestra base de datos, la cual accedemos
mediante el menu inico->programas->Base de datos Oracle 10g Express Edition->pagina de
inicio de la base de datos, para ver la forma visual de hacer todas estas cosas.

Cuando abramos la página de incio de nuestra base de datos nos pedirá un usuario y una
contraseña, tendréis que poner como usuario system y la contraseña que le hayáis dado al

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 10 de 84
instalar el sistema. Una vez dentro, tenemos las opciones de administración (todo lo referente
a la seguridad de sistema), explorador de objetos (todo lo referente a las tablas), sql ( para
hacer las cosas por linea de comando) y utilidades diversas para tu base de datos.

Este interfaz visual que nos ofrece la pagina de inicio de nuestra base de datos te facilitará
mucho el trabajo pero no nos valdrá para hacer nada con SQL *Plus ya que solo nos deja
realizar operaciones sql básicas.

Por lo tanto, quizás nos interesará utilizar la opción que tenemos en nuestro escritorio, que se
llama "ejecutar linea de comandos SQL". Con ello nos abre una pantalla de DOS con el editor
de SQL *Plus.

Nota:Quiero recordar que esto es una versión online de tu base de datos, para instalar una
versión completa tendríamos que bajarnos el Oracle Database 10g ( que incluye sistema
cliente, ejemplos, sistema gateway y sistema clusterware para desarrolladores) y
tendríamos muchas más opciones que ya comentaremos más adelante. La diferencia
fundamental es que la version express puede manejar solamente hasta 4 GB de datos y 1 GB
de memoria. Esta versión puede embeberse con otras aplicaciones de terceros y se puede
distribuir gratuitamente.

Con esto instalado ya podemos comenzar a explicar el SQL *Plus y sus múltiples opciones.

Antes de comenzar os comento que necesitaremos una serie de tablas para ir haciendo
ejercicios y os aconsejaría que os creéis algunos usuarios más con distintos privilegios para ir
repasando lo que hemos comentado de la seguridad en Oracle . Esto lo podéis hacer de forma
visual o por linea de comando desde la pagina inicial de tu base de datos.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 21/01/2009
Disponible online en https://desarrolloweb.com/articulos/instalar-oracle-database-10g-
express.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 11 de 84
Gestión de seguridad en Oracle I

Conceptos básicos para la gestión de seguridad de una base de datos en Oracle.

Un administrador de Oracle puede controlar dos tipos de seguridad;

La seguridad del sistema: Se refiere a mecanismos que controlan el acceso y el uso de la


base de datos. Lo que llamamos permisos del sistema.
Seguridad de los datos: Son los mecanismos que controlan el acceso y uso de la base de
datos a nivel del objectos (tablas, vistas, usuario, etc). Son lo que llamamos los permisos
a nivel de objetos.

Seguridad del sistema


En lo referente a la seguridad del sistema es bastante importante saber que el administrador
puede crear perfiles para limitar los recursos de la base de datos.

Los factores más importantes que puede limitar son:

| Recurso | Descripción | | SESSION_PER_USER | El número de sesiones concurrentes que


un usuario puede tener en una instancia. | | CPU_PER_SESSION | El tiempo de CPU, en
centenas de segundos, que una sesión puede utilizar. | | CONNECT_TIME | El número de
minutos que una sesión puede permanecer activa. | | IDLE_TIME | El número de minutos que
una sesión puede permanecer sin que sea utilizada de manera activa. | |
LOGICAL_READS_PER_SESSION | El número de bloques de datos que se pueden leer en
una sesión. | | LOGICAL_READS_PER_CALL | El número de bloques de datos que se pueden
leer en una operación. | | PRIVATE_SGA | La cantidad de espacio privado que una sesión
puede reservar en la zona de SQL compartido de la SGA. | | COMPOSITE_LIMIT | El número
de total de recursos por sesión, en unidades de servicio. Esto resulta de un calculo ponderado
de CPU_PER_SESSION, CONNECT_TIME, LOGICAL_READS_PER_SESSION y
PRIVATE_SGA, cuyos pesos se pueden variar con el comando ALTER RESOURCE COST. |

La sintaxis para la creación de un perfil con varias limitaciones seria:

create profile nombre_perfil limit {Entero [K|M] | unlimited | default};

Donde unlimited significa que no hay limite sobre un recurso particular y default significa que
coge el limite del perfil DEFAULT

Para activar los perfiles el administrador debe ejecutar la siguiente orden:

alter system set resource_limit=true;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 12 de 84
Para borrar un perfil tenemos que ejecutar la siguiente orden:

drop profile nombre_perfil [cascade];

Es importante saber si este perfil esta asignado a algún usuario ya que, si es así, tendremos que
poner "cascade", para que lo elimine de esos usuarios también.

Otro factor importante en la seguridad a nivel de sistema es la gestión de tablespaces. Un


tablespace es un espacio de la base de datos que contiene tablas o como su definición oficial
nos dice, es una unidad lógica de almacenamiento de datos compuesta por uno o más archivos.
En Oracle antes de introducir los datos en la base de datos tenemos que crear un tablespace
para que nos deje trabajar. Es importante tener un tablespace para cada tipo de datos es decir,
un tablespace para cada aplicación.

La sintaxis de la creación de un tablespace es la siguiente:

create tablespace nombre_tablespace datafile 'nombre_Archivo' [size entero [K|M]] [reuse]


[autoextend {off|on clausulas}] [,'nombre_archivo' [size entero [K|M]] [reuse] [autoextend
{off|on clausulas}] ] ... [ default storage { initial tamaño next tamaño minextents tamaño
maxextents tamaño pctincrease valor }] [online|offline];

Donde:

datafile: especifica el archivo/s de datos que constara el tablespace


size: especifica el tamaño del tablesapce
reuse: si el archivo ya existe lo reutiliza y sino lo crea.
Dafault storage: define el almacenamiento por defecto para todos los objectos que se
creen en ese tablespace
initial: indica la extensión inicial del tablespace
next: indica la extensión siguiente
minextents: reserva extensiones adicionales a la extensión inicial y nos permite asignar
gran cantidad de espacio cuando se crea un objeto. El valor por defecto es 1
maxextents: es el número máximo de extensiones que se le asigna a un objecto
pctincrease: factor de crecimiento para la extensión. Valor por defecto 50
offline|online: nos indica si el tablespace esta operativo o no, después de su creación

Por defecto Oracle crea los siguientes tablespace:

system: donde Oracle almacena toda la información para su propia gestión


users: espacio de tablas donde se almacena la información personal de los usuarios
temporary o temp: donde Oracle almacena las tablas temporales
tools: espacio para hacer pruebas sobre la base de datos
RBS: donde Oracle guarda la información al deshacer algún cambio.

Para modificar un tablespace cambiamos el create por el alter mientras que para borrarlo basta
con hacer drop tablespace nombre_tablespace;

Este artículo es obra de Sara Alvarez

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 13 de 84
Fue publicado / actualizado en 08/01/2009
Disponible online en https://desarrolloweb.com/articulos/gestion-seguridad-oracle-
I.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 14 de 84
Gestión de seguridad en Oracle II

Continuamos con los conceptos básicos en la gestión de seguridad de una base de datos.
Seguridad de los datos en Oracle.

En el articulo anterior hablábamos de que existían dos tipos de seguridad en un sistema gestor
de base de datos. El primero era el encaminado a la seguridad del sistema (enlace al articulo
anterior) y el segundo el encaminado a la seguridad de los datos, tema que vamos a abarcar en
este segundo articulo.

Lo que hace tener una cierta seguridad en nuestros datos es la utilización de usuarios. Estos
usuarios son nombres que definimos y a los cuales damos una contraseña para acceder a la
base de datos.

En Oracle cada usuario esta asignado a un esquema. Siendo un esquema una colección lógica
de objetos. Por defecto un usuario tiene acceso a todos los objectos de su esquema y podría
acceder a los objetos de otros esquemas como los permisos necesarios.

Cuando instanciamos Oracle se crean por defecto dos usuarios importantes:

sys change_on_install: propietario del diccionario de datos de la base de datos


system manager: usuario para realizar las tareas de administración de la base de datos

La sintaxis para la creación de un usuario es la siguiente:

create user nombre_usuario identified by contraseñas [default tablespace nombre_tablespace]


[temporary tablespace nombre_tablespace] [quota {entero {K|M} | unlimited} on
nombre_tablespace] [profile nombre_perfil];

Para modificar el usuario cambiaremos el create por el alter y para borrarlo tan solo tendremos
que poner drop user nombre_usuario cascade;Cada usuario tiene ciertos privilegios, y dentro
de esos privilegios podemos hablar de:

privilegios de sistema: son los que nos dan derecho a realizar ciertas operaciones sobre
objetos de un tipo especificado.

Cuando creamos un usuario es necesario darle privilegios, de lo contrario no podría realizar


ninguna acción.

Roles de usuario
Un rol es un conjunto de permisos que recibe un nombre común y facilita la tarea de dar
permisos a los usuarios. Para crear un rol tan solo tenemos que escribir lo siguiente: create role

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 15 de 84
nombre_role;

Oracle ofrece varios roles o funciones ya creadas que ofrecen ciertos privilegios. Esos roles son
los siguientes:

connect: Todos los permisos necesarios para iniciar una sesión en Oracle
resource: Todos los permisos necesarios para tener recursos para la creación de objetos
dba: posee todos los privilegios del sistema

La sentencia para privilegios sobre los objetos es la siguiente:

grant {privilegio_objeto[,privilegio_objeto]...| all [privileges]} [(columna [,columna]...)] on


[usuario.]objeto} to {usuario|rol| public [,{usuario|rol|public} ...] [with grant option];

Mientras que la sentencia para crear privilegios de sistema es la siguiente:

grant {privilegio|rol} [,privilegio|rol}, ....] to {usuario|rol| public [,{usuario|rol|public} ...]


[with admin option];

En ambos caso se utiliza la sentencia revoke para suprimir privilegios, cambiando la sintaxis.
Para los privilegios de sistema:

revoke {privilegio|rol} [,privilegio|rol}] ... from {usuario|rol|public} [,usuario|rol|public}] ...;

para los privilegios de objetos:

revoke {privilegio[,privilegio] ... | all [privileges]} on [usuario.]objeto from


{usuario|rol|public}[ ,{usuario|rol|public}]...;

Con esto podríamos empezar a gestionar una base de datos, siempre y cuando tengamos
algunos conocimientos de pl/sql. Esto lo veremos en sucesivos artículos que iremos
publicando.

Este artículo es obra de Russvell Oblitas Valenzuela


Fue publicado / actualizado en 08/01/2009
Disponible online en https://desarrolloweb.com/articulos/gestion-seguridad-oracle-
II.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 16 de 84
Usuarios en Oracle

Todo lo relacionado con la gestión de usuarios en Oracle.

Es un nombre definido en la base de datos que se puede conectar a ella y acceder a


determinados objetos según ciertas condiciones que establece el administrador. Los objetos del
diccionario de datos a los que un usuario puede acceder se encuentran en la vista
DICTIONARY, que es propiedad del usuario SYS.

DESC DICTIONARY;

Con la orden:

SELECT TABLENAME FROM DICTIONARY;

Se visualizan los objetos del diccionario de datos a los que se puede acceder.

Creación deusuarios:

CREATE USER NOMBRE_USUARIO

IDENTIFIED BY CLAVE_ACCESO

[DEFAULT TABLESPACE ESPACIO_TABLA]

[TEMPORARY TABLESPACE ESPACIO_TABLA]

[QUOTA {ENTERO {K | M} | UNLIMITED } ON ESPACIO_TABLA]

[PROFILE PERFIL];

DEFAULT TABLESPACE= Asigna a un usuario el tablespace por defecto para almacenar los
objetos que cree. Si no se asigna ninguno, el tablespace por defecto es SYSTEM. TEMPORARY
TABLESPACE= Especifica el nombre del tablespace para trabajar temporales. Si no se
especifica ninguno, el tablespace por defecto es SYSTEM. QUOTA= Asigna un espacio en
megabites o kilobites en el tablespace asignado. Si no se especifica esta cláusula, el usuario no
tiene cuota asignada y no podrá crear objetos en el tablespace. Para tener espacio y acceso
ilimitad a un tablespace es:

GRANT UNLIMITED TABLESPACE NOMBRE_TABLESPACE;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 17 de 84
PROFILE= Asigna un perfil a un usuario.

Modificación de usuarios:

ALTER USER NOMBRE_USUARIO

IDENTIFIED BY CLAVE _ACCESO

[DEFAULT TABLESPACE ESPACIO_TABLA]

[TEMPORARY TABLESPACE ESPACIO_TABLA]

[QUOTA {ENTERO {K | M } | UNLIMITED } ON ESPACIO_TABLA

[PROFILE PERFIL];

Borrado de usuarios:

DROP USER USUARIO [CASCADE];

CASCADE= Suprime todos los objetos del usuario antes de borrarlo.

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 29/06/2005
Disponible online en https://desarrolloweb.com/articulos/2043.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 18 de 84
Claves primarias con SQL con Oracle

Aprendemos a crear y definir claves primarias y sus restricciones.

Rollback:

Permite ir hasta el último COMMIT hecho o en su defecto hasta el comienzo de las órdenes con
lo que estas no se ejecutan.

Commit:

Cuando ejecutamos ordenes estas no son creadas en la tabla hasta que ponemos este orden,
por tanto los cambios realizados se perderán si al salir del programa no realizamos esta acción.
Puede programarse para que lo haga automáticamente.

Algunas ordenes que lleven COMMIT implícito:

QUIT

EXIT

CONNECT

DISCONNECT

CREATE TABLE

CREATE VIEW

GRANT

REVOQUE

DROP TABLE

DROP VIEW

ALTER

AUDIT

NO AUDIT

Creacion de una tabla:

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 19 de 84
Su primer carácter debe ser alfabético y el resto pueden ser letras, números y el carácter
subrayado.

CREATE TABBLE NOMBRETABLA

(COLUMNA1 TIPO_DATO {NOT NULL},

COLUMNA2 TIPO_DATO {NOT NULL},

) TABLESPACE ESPACIO_DE_TABLA;

Características:

Las definiciones individuales de columnas se separan mediante comas.

No se pone coma después de la última definición de columna.

Las mayúsculas y minúsculas son indiferentes.

Los usuarios pueden consultar las tablas creadas por medio de la vista USER_TABLES.

Integridad de datos:

La integridad hace referencia al hecho de que los datos de la base de datos han de ajustarse a
restricciones antes de almacenarse en ella. Una restricción de integridad será: Una regla que
restringe el rango de valores para una o más columnas en la tabla.

Restricciones en create table:

Usamos la cláusula CONSTRAINT, que puede restringir una sola columna o un grupo de
columnas de una misma tabla. Hay dos modos de especificar restricciones:

Como parte de la definición de columnas.

Al final, una vez especificados todas las columnas.

Formato:

CREATE TABLE NOMBRE_TABLA

(COLUMNA1 TIPO_DE_DATO

{CONSTRAINT NOMBRE_RESTRICCION}

{NOT NULL}

{UNIQUE}

{PRIMARY KEY}

{DEFAULT VALOR}

{REFERENCES NOMBRETABLA [(COLUMNA, [,COLUMNA])

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 20 de 84
{ON DELETE CASCADE}}

{CHECK CONDICION},

COLUMNA2...

{TABLESPACE ESPACIO_DE_TABLA} ;

CREATE TABLE NOMBRE_TABLA

(COLUMNA1 TIPO_DATO ,

COLUMNA2 TIPO_DATO,

COLUMNA3 TIPO_DATO,

...

{CONSTRAINT NOMBRERESTRICCION}

[{UNIQUE} | {PRIMARY KEY} (COLUMNA [, COLUMNA])],

{CONSTRAINT NOMBRERESTRICCION}

{FOREIGN KEY (COLUMNA [, COLUMNA])

REFERENCES NOMBRETABLA {(COLUMNA [,

COLUMNA])

{ON DELETE CASCADE}},

{CONSTRINT NOMBRERESTRICCIONI}

{CHECK (CONDICION)}

)[TABLESPACE ESPACIO_DE_TABLA];

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 06/04/2005
Disponible online en https://desarrolloweb.com/articulos/1926.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 21 de 84
Definición de claves para tablas y
restricciones

Vemos claves primarias y claves externas (foreing keys) y aprendemos a aplicar restricciones a
los distintos campos de las tablas.

Clave primaria: Primary key

Es una columna o un conjunto de columnas que identifican unívocamente a cada fila. Debe ser
única, no nula y obligatoria. Como máximo, podemos definir una clave primaria por tabla. Esta
clave se puede referenciar por una columna o columnas. Cuando se crea una clave primaria,
automáticamente se crea un índice que facilita el acceso a la tabla.

Formato de restricción de columna:

CREATE TABLE NOMBRE_TABLA

(COL1 TIPO_DATO [CONSTRAINT NOMBRE_RESTRICCION] PRIMARY KEY

COL2 TIPO_DATO

)[TABLESPACE ESPACIO_DE_TABLA];

Formato de restricción de tabla:

CREATE TABLE NOMBER_TABLA

(COL1 TIPO_DATO,

COL2 TIPO_DATO,

[CONSTRAINT NOMBRERESTRICCION] PRIMARY KEY (COLUMNA [,COLUMNA]),

)[TABLESPACE ESPACIO_DE_TABLA];

Claves ajenas: Foreign Key:

Esta formada por una o varias columnas que están asociadas a una clave primaria de otra o de
la misma tabla. Se pueden definir tantas claves ajenas como se precise, y pueden estar o no en

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 22 de 84
la misma tabla que la clave primaria. El valor de la columna o columnas que son claves ajenas
debe ser: NULL o igual a un valor de la clave referenciada (regla de integridad referencial).

Formato de restricción de columna:

CREATE TABLE NOMBRE_TABLA

(COLUMNA1 TIPO_DATO

[CONSTRAINT NOMBRERESTRICCION]

REFERENCES NOMBRETABLA [(COLUMNA)] [ON DELETE CASCADE]

)[TABLESPACE ESPECIO_DE_TABLA];

Formato de restricción de tabla:

CREATE TABLE NOMBRE_TABLA

(COLUMNA1 TIPO_DATO,

COLUMNA2 TIPO_DATO,

[CONTRAINT NOMBRERESTRICCION]

FOREIGN KEY (COLUMNA [,COLUMNA])

REFERENCES NOMBRETABLA [(COLUMNA [,

COLUMNA])]

[ON DELETE CASCADE],

)[TABLESPACE ESPACIO_DE_TABLA];

Notas:

En la cláusula REFERENCES indicamos la tabla a la cual remite la clave ajena.

Hay que crear primero una tabla y después aquella que le hace referencia.

Hay que borrar primero la tabla que hace referencia a otra tabla y después la tabla que
no hace referencia.

Borrado en cascada (ON DELETE CASCADE): Si borramos una fila de una tabla
maestra, todas las filas de la tabla detalle cuya clave ajena sea referenciada se borraran
automáticamente. La restricción se declara en la tabla detalle. El mensaje "n filas
borradas" solo indica las filas borradas de la tabla maestra.

NOT NULL: Significa que la columna no puede tener valores nulos. DEFAULT: Le
proporcionamos a una columna un valor por defecto cuando el valor de la columna no se

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 23 de 84
especifica en la cláusula INSERT. En la especificación DEFAULT es posible incluir varias
expresiones: constantes, funciones SQL y variables UID y SYSDATE. Verificación de
restricciones: CHECK: Actúa como una cláusula where. Puede hacer referencia a una o más
columnas, pero no a valores de otras filas. En una cláusula CHECK no se pueden incluir
subconsultas ni las pseudoconsultas SYSDATE, UID y USER.

| Nota: La restricción NOT NULL es similar a CHECK (NOMBRE_COLUMNA IS NOT NULL)


|

UNIQUE: Evita valores repetidos en la misma columna. Puede contener una o varias
columnas. Es similar a la restricción PRIMARY KEY, salvo que son posibles varias columnas
UNIQUE definidas en una tabla. Admite valores NULL. Al igual que en PRIMARY KEY,
cuando se define una restricción UNIQUE se crea un índice automáticamente.

Vistas del diccionario de datos para las restricciones:

Contienen información general las siguientes:

USER_CONSTRAINTS: Definiciones de restricciones de tablas propiedad del usuario.


ALL_CONSTRAINTS: Definiciones de restricciones sobre tablas a las que puede acceder el
usuario. DBA_CONSTRAINTS: Todas las definiciones de restricciones sobre todas las tablas.

Creación de una tabla con datos recuperados en una consulta:

CREATE TABLE: permite crear una tabla a partir de la consulta de otra tabla ya existente. La
nueva tabla contendrá los datos obtenidos en la consulta. Se lleva a cabo esta acción con la
cláusula AS colocada al final de la orden CREATE TABLE.

CREATE TABLE NOMBRETABLA

(COLUMNA [,COLUMNA]

)[TABLESPACE ESPACIO_DE_TABLA]

AS CONSULTA;

No es necesario especificar tipos ni tamaño de las consultas, ya que vienen determinadas por
los tipos y los tamaños de las recuperadas en la consulta. La consulta puede tener una
subconsulta, una combinación de tablas o cualquier sentencia select valida. Las restricciones
CON NOMBRE no se crean en una tabla desde la otra, solo se crean aquellas restricciones que
carecen de nombre.

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 06/04/2005
Disponible online en https://desarrolloweb.com/articulos/1925.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 24 de 84
Supresión y modificación de tablas con SQL

Vemos sentencias en SQL para la supresion y modificación tanto de tablas como de


restricciones.

Supresión de tablas:

DROP TABLE: suprime una tabla de la base de datos. Cada usuario puede borrar sus propias
tablas, pero solo el administrador o algún usuario con el privilegio "DROP ANY TABLE" puede
borrar las tablas de otro usuario. Al suprimir una tabla también se suprimen los índices y los
privilegios asociados a ella. Las vistas y los sinónimos creados a partir de esta tabla dejan de
funcionar pero siguen existiendo en la base de datos por tanto deberíamos eliminarlos.
Ejemplo:

DROP TABLE [USUARIO].NOMBRETABLA [CASCADE CONSTRAINTS];

TRUNCATE: permite suprimir todas las filas de una tabla y liberar el espacio ocupado para
otros usos sin que reaparezca la definición de la tabla de la base de datos. Una orden
TRUNCATE no se puede anular, como tampoco activa disparadores DELETE.

TRUNCATE TABLE [USUARIO.]NOMBRETABLA [{DROP | REUSE} STORAGE];

Modificación de tablas:

Se modifican las tablas de dos formas: Cambiando la definición de una columna (MODIFY) ó
añadiendo una columna a una tabla existente (ADD): Formato:

ALTER TABLE NOMBRETABLA

{[ADD (COLUMNA [,COLUMNA]…)]

[MODIFY (COLUMNA [,COLUMNA]…)]

[ADD CONSTRAINT RESTRICCION]

[DROP CONSTRAINT RESTRICCION]};

ADD= Añade una columna o mas al final de una tabla. MODIFY= Modifica una o mas
columnas existentes en la tabla. ADD CONSTRAINT= Añade una restricción a la definición de
la tabla. DROP CONSTRAINT= Elimina una restricción de la tabla.

A la hora de añadir una columna a una tabla hay que tener en cuenta:

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 25 de 84
Si la columna no esta definida como NOT NULL se le puede añadir en cualquier
momento.

Si la columna esta definida como NOT NULL se pueden seguir estos pasos:

1. Se añade una columna sin especificar NOT NULL.


2. Se da valor a la columna para cada una de las filas.
3. Se modifica la columna NOT NULL.

Al modificar una columna de duna tabla se han de tener en cuenta:

Se puede aumentar la longitud de una columna en cualquier momento.

Es posible aumentar o disminuir el numero de posiciones decimales en una columna de


tipo NUMBER.

Si la columna es NULL en todas las filas de la tabla, se puede disminuir la longitud y


modificar el tipo de dato

La opción MODIFY… NOT NULL solo será posible cuando la tabla no contenga ninguna
fila con valor nulo en la columna que se modifica.

Adición de restricciones:

Con la orden ALTER TABLE se añaden restricciones a una tabla. Formato:

ALTER TABLE NOMBRETABLA

ADD CONSTRAINT NOMBRECONSTRAINT…

Borrado de restricciones:

La orden ALTER TABLE con la cláusula DROP CONSTRAINT; con la que se borran las
restricciones con nombre y las asignadas por el sistema. Formato:

ALTER TABLE NOMBRETABLA

DROP CONSTRAINT NOMBRE_CONSTRAINT,

NOMBRE_RESTRICCION:

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 27/04/2005
Disponible online en https://desarrolloweb.com/articulos/1965.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 26 de 84
Manipulación de datos con SQL

Utilizando SQL con Oracle aprendemos como hacer Inserciones, actualizaciones y a eliminar
datos.

Insert, Update y Delete:

Insert:

Se añaden filas de datos en una tabla:

INSERT INTO NOMBRETABLA [(COL [,COL]…)]

VALUES (VALOR [,VALOR]…);

Nombretabla= Es la tabla en la que se van a insertar las filas.

Propiedades:

Si las columnas no se especifican en la cláusula Insert se consideran, por defecto, todas


las columnas de la tabla.

Las columnas a las que damos valores se identifican por su nombre.

La asociación columna valor es posicional.

Los valores que se dan a las columnas deben coincidir con el tipo de dato definido en la
columna.

Los valores constantes de tipo carácter han de ir encerrados entre comillas simples (' ')
(los de tipo fecha también).

Con Select:

Se añaden tantas filas como devuelva la consulta:

INSERT INTO NOMBRETABLA [(COL [,COL]…)]

SELECT {COLUMNA [, COLUMNA]… | *}

FROM NOMBRETABLA2 [CLAUSULAS DE SELECT];

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 27 de 84
Update:

Actualiza los valores de las columnas para una o varias filas de una tabla:

UPDATE NOMBRETABLA

SET COLUMNA1= VALOR1, …, COLUMNAN= VALORN

WHERE CONDICION;

Set= Indica las columnas que se van a actualizar y sus valores.

Con Select:

Cuando la subconsulta (orden select) forma parte de SET, debe seleccionar el mismo numero
de columnas, (con tipos de datos adecuados) que los que hay entre paréntesis al lado de SET.

UPDATE NOMBRETABLA

SET COLUMNA= VALOR1, COLUMNA2= VALOR2, …

WHERE COLUMNA3= (SELECT…)

UPDATE NOMBRETABLA

SET (COLUMNA1, COLUMNA2, …)= (SELECT …)

WHERE CONDICION;

Delete:

Elimina una o varias filas de una tabla:

DELETE [FROM] NOMBRETABLA

WHERE CONDICION;

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 06/04/2005
Disponible online en https://desarrolloweb.com/articulos/1924.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 28 de 84
SQL con Oracle. Operadores

Empezamos a ver los tipos de operadores y trabajamos con algunos ejemplos.

Operadores aritméticos:

= Suma
= Resta
= Multiplicación / = división

Operadores de comparación y lógicos:

!> = Distinto

= = Mayor o igual que <= = Menor o igual que = = Igual que Like = Se utiliza para unir
cadenas de caracteres. Propiedades: % = representa cualquier cadena de caracteres de 0 o
mas caracteres. _= representa un único carácter cualquiera. Not = Negación And = y a and
b Cierto si son ciertas a y b. Or = o a or b Cierto si a o b son ciertas

Veamos un par de ejemplos:

Obtenemos los datos de los jugadores cuyos apellidos empiecen con una "S":

SELECT APELLIDO

FROM JUGADORES

WHERE APELLIDO LIKE 'S%';

Obtenemos aquellos apellidos que tengan una "R" en la segunda posición:

SELECT APELLIDO

FROM JUGADORES

WHERE APELLIDO LIKE '_R*';

Obtenemos aquellos apellidos que empiezan por "A" y tiene una "o" en su interior:

SELECT APELLIDO

FROM JUGADORES

WHERE APELLDIOS LIKE 'A%O%';

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 29 de 84
Comprobación con conjuntos de valores:

In= permite saber si una expresión pertenece o no a un conjunto de valores.

Between= permite saber si una expresión esta o no entre esos valores:

Ejemplo:

SELECT APELLIDOS

FROM JUGADORES

WHERE JUGADOR_NUM IN (10, 20);

Selecciona los apellidos de los jugadores donde el número de jugador (Jugador_num) sea (In)
o 10 o 20

SELECT APELLIDOS

FROM JUGADORES

WHERE SALARIO NOT BETWEEN 15000000 AND 20000000;

Selecciona los apellidos de los jugadores donde el salario de estos no este entre (Not Between)
15000000 y 20000000.

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 11/03/2005
Disponible online en https://desarrolloweb.com/articulos/1870.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 30 de 84
Funciones SQL

Vemos los distintos tipos de funciones y algunos ejemplos de las mismas con SQL para Oracle.

Funciones de valores simples:

ABS(n)=

Devuelve el valor absoluto de (n).

CEIL(n)=

Obtiene el valor entero inmediatamente superior o igual a "n".

FLOOT(n) =

Devuelve el valor entero inmediatamente inferior o igual a "n".

MOD (m, n)=

Devuelve el resto resultante de dividir "m" entre "n".

NVL (valor, expresión)=

Sustituye un valor nulo por otro valor.

POWER (m, exponente)=

Calcula la potencia de un numero.

ROUND (numero [, m])=

Redondea números con el numero de dígitos de precisión indicados.

SIGN (valor)=

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 31 de 84
Indica el signo del "valor".

SQRT(n)=

Devuelve la raíz cuadrada de "n".

TRUNC (numero, [m])=

Trunca números para que tengan una cierta cantidad de dígitos de precisión.

VAIRANCE (valor)=

Devuelve la varianza de un conjunto de valores.

Funciones de grupos de valores:

AVG(n)=

Calcula el valor medio de "n" ignorando los valores nulos.

COUNT (* | Expresión)=

Cuenta el numero de veces que la expresión evalúa algún dato con valor no nulo. La opción "*"
cuenta todas las filas seleccionadas.

MAX (expresión)=

Calcula el máximo.

MIN (expresión)=

Calcula el mínimo.

SUM (expresión)=

Obtiene la suma de los valores de la expresión.

GREATEST (valor1, valor2…)=

Obtiene el mayor valor de la lista.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 32 de 84
LEAST (valor1, valor2…)=

Obtiene el menor valor de la lista.

Funciones que devuelven valores de caracteres:

CHR(n) =

Devuelve el carácter cuyo valor en binario es equivalente a "n".

CONCAT (cad1, cad2)=

Devuelve "cad1" concatenada con "cad2".

LOWER (cad)=

Devuelve la cadena "cad" en minúsculas.

UPPER (cad)=

Devuelve la cadena "cad" en mayúsculas.

INITCAP (cad)=

Convierte la cadena "cad" a tipo titulo.

LPAD (cad1, n[,cad2])=

Añade caracteres a la izquierda de la cadena hasta que tiene una cierta longitud.

RPAD (cad1, n[,cad2])=

Añade caracteres a la derecha de la cadena hasta que tiene una cierta longitud.

LTRIM (cad [,set])=

Suprime un conjunto de caracteres a la izquierda de la cadena.

RTRIM (cad [,set])=

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 33 de 84
Suprime un conjunto de caracteres a la derecha de la cadena.

REPLACE (cad, cadena_busqueda [, cadena_sustitucion])=

Sustituye un carácter o caracteres de una cadena con 0 o mas caracteres.

SUBSTR (cad, m [,n])=

Obtiene parte de una cadena.

TRANSLATE (cad1, cad2, cad3)=

Convierte caracteres de una cadena en caracteres diferentes, según un plan de sustitución


marcado por el usuario.

Funciones que devuelven valores numéricos:

ASCII(cad)=

Devuelve el valor ASCII de la primera letra de la cadena "cad".

INSTR (cad1, cad2 [, comienzo [,m]])=

Permite una búsqueda de un conjunto de caracteres en una cadena pero no suprime ningún
carácter después.

LENGTH (cad)=

Devuelve el numero de caracteres de cad.

Funciones para el manejo de fechas:

SYSDATE=

Devuelve la fecha del sistema.

ADD_MONTHS (fecha, n)=

Devuelve la fecha "fecha" incrementada en "n" meses.

LASTDAY (fecha)=

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 34 de 84
Devuelve la fecha del último día del mes que contiene "fecha".

MONTHS_BETWEEN (fecha1, fecha2)=

Devuelve la diferencia en meses entre las fechas "fecha1" y "fecha2".

NEXT_DAY (fecha, cad)=

Devuelve la fecha del primer día de la semana indicado por "cad" después de la fecha indicada
por "fecha".

Funciones de conversión:

TO_CHAR=

Transforma un tipo DATE ó NUMBER en una cadena de caracteres.

TO_DATE=

Transforma un tipo NUMBER ó CHAR en DATE.

TO_NUMBER=

Transforma una cadena de caracteres en NUMBER.

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 30/03/2005
Disponible online en https://desarrolloweb.com/articulos/1899.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 35 de 84
Subconsultas SQL

Explicación y ejemplos de las subconsultas en SQL para Oracle.

Subconsultas:

Consulta que se hace sobre los datos que nos da otra consulta. Su formato es:

SELECT______

FROM________

WHERE CONDICION OPERADOR (SELECT ______

FROM ___________

WHERE CONDICION OPERADOR);

Ejemplo:

Obtenemos los jugadores con la misma posición que "Sánchez":

SELECT APELLIDO

FORM EMPLE

WHERE POSICION = (SELECT OFICIO

FROM EMPLE

WHERE APELLIDO LIKE 'GIL');

Seleccionamos en todos los campos de la tabla Jugadores cuya sede está en Madrid o
Barcelona:

SELECT *

FROM JUGADORES

WHERE EQUIPO_NOM IN (SELECT EQUIPO_NOM

FROM SEDE

WHERE LOC IN ('MADRID', 'BARCELONA');

FROM SEDE

WHERE LOC IN ('MADRID', 'BARCELONA');

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 36 de 84
Este artículo es obra de Agustin Jareño
Fue publicado / actualizado en 29/03/2005
Disponible online en https://desarrolloweb.com/articulos/1897.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 37 de 84
Agrupación y combinación de elementos
con SQL

Aprendemos a agrupar elementos y a combinar filas seleccionadas con SQL para Oracle

Agrupación de elementos. Group by y Having:

Para saber cual es el salario medio de cada departamento de la tabla Jugadores sería:

SELECT EQUIPO_NO, AVG (SALARIO) "SALARIO MEDIO"

FROM JUGADORES

GROUP BY DEPT_NO;

La sentencia "Select" posibilita agrupar uno o más conjuntos de filas. El agrupamiento se lleva
a cabo mediante la cláusula "GROUP BY" por las columnas especificadas y en el orden
especificado. Formato:

SELECT…

FROM…

GROUP BY COLUMNA1, COLUMNA2, COLUMNAN…

HAVING CONDICION

GROUP BY …

Los datos seleccionados en la sentencia "Select" que lleva el "Group By" deben ser:

Una constante.

Una función de grupo (SUM, COUNT, AVG…)

Una columna expresada en el Group By.

La cláusula Group By sirve para calcular propiedades de uno o más conjuntos de filas. Si se
selecciona más de un conjunto de filas, Group By controla que las filas de la tabla original sean
agrupadas en un temporal.

La cláusula Having se emplea para controlar cual de los conjuntos de filas se visualiza. Se
evalúa sobre la tabla que devuelve el Group By. No puede existir sin Group By.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 38 de 84
Having es similar al Where, pero trabajo con grupos de filas; pregunta por una característica
de grupo, es decir, pregunta por los resultados de las funciones de grupo, lo cual Where no
pude hacer.

Combinación externa (outer joins):

Nos permite seleccionar algunas filas de una tabla aunque estas no tengan correspondencia
con las filas de la otra tabla con la que se combina. Formato:

SELECT TABLA1.COLUMNA1, TABLA1.COLUMNA2, TABLA2.COLUMNA1, TABLA2.COLUMNA2

FROM TABLA1, TABLA2

WHERE TABLA1.COLUMNA1 = TABLA2.COLUMNA1 (+);

Esto selecciona todas las filas de la tabla "tabla1" aunque no tengan correspondencia con las
filas de la tabla "tabla2", se utiliza el símbolo +. El resto de columnas de la tabla "tabla2" se
rellena con NULL.

Union, intersec y minus:

Permite combinar los resultados de varios "Select" para obtener un único resultado. Formato:

SELECT… FROM… WHERE…

OPERADOR_DE_CONJUNTO

SELECT…FROM…WHERE…

UNION=

Combina los resultados de dos consultas. Las filas duplicadas que aparecen se reducen a una
fila única.

UNION ALL=

Como la anterior pero aparecerán nombres duplicados.

INTERSEC=

Devuelve las filas que son iguales en ambas consultas. Todas las filas duplicadas serán
eliminadas.

MINUS=

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 39 de 84
Devuelve aquellas filas que están en la primera "Select" y no están en la segunda "Select". Las
filas duplicadas del primer conjunto se reducirán a una fila única antes de que empiece la
comparación con el otro conjunto.

Reglas para la utilización de operadores de conjunto:

Las columnas de las dos consultas se relacionan en orden, de izquierda a derecha.

Los nombres de columna de la primera sentencia "Select" no tiene porque ser los
mismos que los nombres de la segunda.

Los "Select" necesitan tener el mismo numero de columnas.

Los tipos de datos deben coincidir, aunque la longitud no tiene que ser la misma.

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 30/03/2005
Disponible online en https://desarrolloweb.com/articulos/1900.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 40 de 84
Optimizar consultas SQL

Distintas formas de optimizar las consultas realizadas en SQL.

El lenguaje SQL es no procedimental, es decir, en las sentencias se indica que queremos


conseguir y no como lo tiene que hacer el interprete para conseguirlo. Esto es pura teoría, pues
en la práctica a todos los gestores de SQL hay que especificar sus propios truquitos para
optimizar el rendimiento.

Por tanto, muchas veces no basta con especificar una sentencia SQL correcta, sino que además,
hay que indicarle como tiene que hacerlo si queremos que el tiempo de respuesta sea el
mínimo. En este apartado veremos como mejorar el tiempo de respuesta de nuestro interprete
ante unas determinadas situaciones:

Diseño de las tablas

Normaliza las tablas, al menos hasta la tercera forma normal, para asegurar que no hay
duplicidad de datos y se aprovecha al máximo el almacenamiento en las tablas. Si hay
que desnormalizar alguna tabla piensa en la ocupación y en el rendimiento antes de
proceder.
Los primeros campos de cada tabla deben ser aquellos campos requeridos y dentro de
los requeridos primero se definen los de longitud fija y después los de longitud variable.
Ajusta al máximo el tamaño de los campos para no desperdiciar espacio.
Es muy habitual dejar un campo de texto para observaciones en las tablas. Si este
campo se va a utilizar con poca frecuencia o si se ha definido con gran tamaño, por si
acaso, es mejor crear una nueva tabla que contenga la clave primaria de la primera y el
campo para observaciones.

Gestión y elección de los índices

Los índices son campos elegidos arbitrariamente por el constructor de la base de datos que
permiten la búsqueda a partir de dicho campo a una velocidad notablemente superior. Sin
embargo, esta ventaja se ve contrarrestada por el hecho de ocupar mucha más memoria (el
doble más o menos) y de requerir para su inserción y actualización un tiempo de proceso
superior.

Evidentemente, no podemos indexar todos los campos de una tabla extensa ya que doblamos
el tamaño de la base de datos. Igualmente, tampoco sirve de mucho el indexar todos los
campos en una tabla pequeña ya que las selecciones pueden efectuarse rápidamente de todos
modos.

Un caso en el que los índices pueden resultar muy útiles es cuando realizamos peticiones
simultáneas sobre varias tablas. En este caso, el proceso de selección puede acelerarse

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 41 de 84
sensiblemente si indexamos los campos que sirven de nexo entre las dos tablas.

Los índices pueden resultar contraproducentes si los introducimos sobre campos triviales a
partir de los cuales no se realiza ningún tipo de petición ya que, además del problema de
memoria ya mencionado, estamos ralentizando otras tareas de la base de datos como son la
edición, inserción y borrado. Es por ello que vale la pena pensárselo dos veces antes de indexar
un campo que no sirve de criterio para búsquedas o que es usado con muy poca frecuencia por
razones de mantenimiento.

Campos a Seleccionar

En la medida de lo posible hay que evitar que las sentencias SQL estén embebidas
dentro del código de la aplicación. Es mucho más eficaz usar vistas o procedimientos
almacenados por que el gestor los guarda compilados. Si se trata de una sentencia
embebida el gestor debe compilarla antes de ejecutarla.
Seleccionar exclusivamente aquellos que se necesiten
No utilizar nunca SELECT * por que el gestor debe leer primero la estructura de la tabla
antes de ejecutar la sentencia
Si utilizas varias tablas en la consulta especifica siempre a que tabla pertenece cada
campo, le ahorras al gestor el tiempo de localizar a que tabla pertenece el campo. En
lugar de SELECT Nombre, Factura FROM Clientes, Facturacion WHERE IdCliente =
IdClienteFacturado, usa: SELECT Clientes.Nombre, Facturacion.Factura WHERE
Clientes.IdCliente = Facturacion.IdClienteFacturado.

Campos de Filtro

Se procurará elegir en la cláusula WHERE aquellos campos que formen parte de la


clave del fichero por el cual interrogamos. Además se especificarán en el mismo orden
en el que estén definidos en la clave.
Interrogar siempre por campos que sean clave.
Si deseamos interrogar por campos pertenecientes a índices compuestos es mejor
utilizar todos los campos de todos los índices. Supongamos que tenemos un índice
formado por el campo NOMBRE y el campo APELLIDO y otro índice formado por el
campo EDAD. La sentencia WHERE NOMBRE='Juan' AND APELLIDO Like '%' AND
EDAD = 20 sería más optima que WHERE NOMBRE = 'Juan' AND EDAD = 20 por que
el gestor, en este segundo caso, no puede usar el primer índice y ambas sentencias son
equivalentes por que la condición APELLIDO Like '%' devolvería todos los registros.

Orden de las Tablas

Cuando se utilizan varias tablas dentro de la consulta hay que tener cuidado con el orden
empleado en la cláusula FROM. Si deseamos saber cuantos alumnos se matricularon en el año
1996 y escribimos: FROM Alumnos, Matriculas WHERE Alumno.IdAlumno =
Matriculas.IdAlumno AND Matriculas.Año = 1996 el gestor recorrerá todos los alumnos para
buscar sus matriculas y devolver las correspondientes. Si escribimos FROM Matriculas,
Alumnos WHERE Matriculas.Año = 1996 AND Matriculas.IdAlumno = Alumnos.IdAlumnos,
el gestor filtra las matrículas y después selecciona los alumnos, de esta forma tiene que
recorrer menos registros.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 42 de 84
Este artículo es obra de Claudio
Fue publicado / actualizado en 28/10/2005
Disponible online en https://desarrolloweb.com/articulos/2230.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 43 de 84
Gestión de vistas en SQL

Creación, modificación y supresión de vistas con SQL.

Creación y uso de vistas

No contienen información por si mismas, sino que están basadas en las que contienen otras
tablas y refleja los datos de estas. Si se suprime una tabla la vista asociada se invalida.
Formato:

CREATE [OR REPLACE] VIEW NOMBREVISTA

[(COLUMNA [,COLUMNA])]

AS CONSULTA;

AS CONSULTA= Determina las columnas y las tablas que aparecerán en la vista. [OR
REPLACE]= Crea de nuevo la vista si ya existía.

Para consultar la vista creada, USER_VIEWS:

SELECT VIEW_NAME FROM…

| Nota: al borrar las tablas, las vistas de esas tablas no se borran y quedan inutilizadas. |

Borrado de vistas

Se hace con DROP VIEW. Formato:

DROP VIEW NOMBREVISTA;

Operaciones sobre vistas

Se pueden realizar las mismas operaciones que se hacen sobre las tablas. Restricciones:

Actualización Si una vista esta basada en una sola tabla, se pueden modificar las filas de
la vista.
La modificación de la vista cambia la tabla sobre la que esta definida.
Borrado de filas a través de una vista= Para borrar filas de una tabla a través de una
vista, esta se debe crear:
http://desarrolloweb.com/manuales/tutorial-oracle.html Página 44 de 84
Con filas de una sola tabla.
Sin utilizar la cláusula GROUP BY ni DISTINCT.
Sin usar funciones de grupo o referencias a pseudocolumnas.
Actualización de filas a través de una vista: Para actualizar filas en una tabla a través de
una vista, esta ha de estar definida según las restricciones anteriores y , además,
ninguna de las columnas que se va a actualizar se habrá definido como una expresión.
Inserción de filas a través de una vista: Para insertar filas en una tabla a través de una
vista se han de tener en cuenta todas las restricciones anteriores y, además, todas las
columnas obligatorias de la tabla asociada deben estar presentes en la vista.
Manejo de expresiones y de funciones en vistas: Se pueden crear vistas usando
funciones, expresiones en columnas y consultas avanzadas pero únicamente se parean
consultar estas vistas. También podemos modificar filas siempre y cuando la columna
que se va a modificar no sea la columna expresad en forma de cálculo o con funciones.

| Nota: No es posible insertar filas si las columnas de la vista contiene cálculos o funciones. |

Cambios de nombre

RENAME cambia el nombre de una tabla, vista o sinónimo. El nuevo nombre no puede ser una
palabra reservada ni el nombre de un objeto que tenga creado el usuario. Las restricciones de
integridad, los índices y los permisos dados al objeto se transfieren automáticamente al nuevo
objeto.

REANME NOMBRE_ANTERIOR TO NOMBRE_NUEVO;

Con esta orden no podemos renombrar columnas de una tabla, estas se renombran mediante
CREATE TABLE AS…

Este artículo es obra de Agustin Jareño


Fue publicado / actualizado en 13/06/2005
Disponible online en https://desarrolloweb.com/articulos/2023.php

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 45 de 84
Introducción al lenguaje PL/SQL

**Qué es el lenguaje PL/SQL y primeras explicaciones para saber cómo funciona este gestor
PL/SQL.

**

Nos encontramos ante un gestor que va incorporado en Oracle para solventar las grandes
limitaciones que teníamos con los editores SQL, en cuanto al control de las secuencias de
ejecución de instrucciones, el uso de variables, la gestión de posibles errores, etc.

Este lenguaje esta basado en ADA, por lo que incluye todas las características de los lenguajes
de tercera generación. Esto nos permite manejar las variables, tener una estructura modular
(procedimientos y funciones) y controlar las excepciones. Además incorpora un completo
soporte para la programación orientada a objetos (POO).

Los programas creados con PL/SQL los podemos almacenar en nuestra base de datos como
cualquier otro objeto quedando disponibles para los usuarios. El uso del lenguaje PL/SQL es
imprescindible para construir disparadores de bases de datos (triggers).

PL/SQL esta incluido en el servidor y en algunas herramientas de cliente. Soporta todos los
comandos de consulta y manipulación de datos, aportando al lenguaje SQL las estructuras de
control y otros elementos propios de los lenguajes de programación de 3º generación.

La unidad de trabajo en PL/SQL es el bloque, constituido por un conjunto de declaraciones,


instrucciones y mecanismos de gestión de errores y excepciones.

Bloques
Con PL/SQL se pueden construir distintos tipos de programas: procedimientos, funciones y
bloques anónimos, paquetes, etc. Todos ellos tienen en común una estructura básica
denominada bloque.

Un bloque tiene 3 zonas:

Zona de declaraciones: donde se declaran objectos locales. Suele ir precedida por la cláusula
declare (o is o as en los procedimientos y funciones). Un conjunto de instrucciones precedido
por la cláusula BEGIN Zona de excepciones: es una zona opcional precedida por la cláusula
EXCEPTION, donde se gestionan las excepciones. El formato genérico de un bloque es el
siguiente:

[ DECLARE
<declaraciones>]

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 46 de 84
BEGIN
<instrucciones>
[EXCEPTION
<gestión de excepciones>]
END;

Las únicas cláusulas obligatorias son BEGIN y END

Antes de hacer ningún bloque tenemos que ejecutar el siguiente comando en nuestra ventana
de Sql *PLUS

set serveroutput on;

Aunque ahora no entendáis mucho os dejo un ejemplo de un bloque para que os vayáis
familiarizando con la sintaxis.

DECLARE
v_num_empleados number(2);
BEGIN
insert into depart values(99,'provisional',null);
update emple set dept_no=99 where dept_no=20;
v_num_empleados:=SQL%ROWCOUNT;
delete from depart where dept_no=20
DBMS_OUTPUT.PUT_LINE (v_num_empleados || 'Empleados cambiados a provisional');

Ya en próximos artículos nos meteremos de lleno en la construcción de bloque y en entender


las lineas arriba escritas.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 10/02/2009
Disponible online en https://desarrolloweb.com/articulos/introduccion-al-lenguaje-
plsql.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 47 de 84
Características de PL/SQL primera parte

Para poder trabajar con PL/SQL tenemos que tener claros una serie de conceptos y
definiciones sobre todo en lo referente a compatibilidad de datos y estructuras de control.

Definición de datos compatibles con SQL


Este lenguaje suele tener unos tipos de datos compatibles con SQL para las columnas de las
tablas, pero además puede tener otros tipos de datos propios.

Para declarar los datos en un bloque tenemos que utilizar una sintaxis como esta:

DECLARE
nombre_variable Tipo dato;
BEGIN
...

Un ejemplo seria este:

DECLARE
precio NUMBER(8,2);
suma NUMBER(2) DEFAULT 0;
prenda CHAR(20) NOT NULL :='Camiseta';
descripción VARCHAR2(15);
BEGIN
....

Una de las ventajas de PL/SQL es que nos permite declarar una variable del mismo tipo que
otra variable o que una columna de una tabla. Esto lo hacemos con el atributo %TYPE.

DECLARE
nombre emple.nombre%TYPE;

Otra ventaja es que nos permite guardar el contenido de una fila entera de una tabla en una
variable. Esto lo hacemos con el atributo %ROWTYPE

DECLARE
mifila emple%ROWTYPE;

Con esto ya podemos trabajar con variables dentro de nuestro bloque. Ahora tenemos que ver

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 48 de 84
las estructuras de control que podemos manejar dentro de nuestros bloques.

Estructuras de control
Las estructuras de control son básicamente las mismas que podemos utilizar en cualquier
lenguaje de programación.

La vamos a dividir en estructuras de control alternativas (IF) y estructuras de control


repetitivas (WHILE, FOR, LOOP)

La estructura del IF seria la siguiente:

IF <condición> THEN
instrucciones
ELSEIF <condición> THEN
instrucciones
....
ELSE
instrucciones
END IF;

La estructura del WHILE seria la siguiente:

WHILE <condición> LOOP


instrucciones
END LOOP;

La estructura del FOR se escribiría así:

FOR <variable> IN <mínimo> <máximo> LOOP


instrucciones
END LOOP

Si queremos que nos vaya contando al revés, es decir de 5 hasta 0 por ejemplo, la sintaxis seria
la siguiente:

FOR <variable> IN REVERSE


<final>.......<inicio> LOOP
instrucciones
.....
END LOOP;

Y la estructura del LOOP seria de esta forma:

LOOP
instrucciones
....
EXIT WHEN <condición>

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 49 de 84
instrucciones
...
END LOOP;

Cursores implicitos
Es importante saber que en nuestros bloques PL/SQL es bastante práctico el uso de cursores.
En este lenguaje el resultado de una consulta no va directamente al terminal del usuario, sino
que se guarda en un área de memoria a la que se accede mediante los nombrados cursores.
Para realizar una consulta en PL/SQL tenemos que guardar el resultado en cursores. Esto es
muy sencillo y basta con meter un INTO en las consultas. Un ejemplo seria este:

select <columna/s> INTO <variable/s> from <tabla> [where]

select count(*) INTO vnum from ventas;

La variable que sigue al INTO recibe el valor de la columna. Por este motivo es importante que
el tipo de dato de la variable coincida con el tipo de dato de la columna.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 26/02/2009
Disponible online en https://desarrolloweb.com/articulos/caracteristicas-plsql-I.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 50 de 84
Características de PL/SQL segunda parte

Es importante controlar los posibles errores y además distinguir los distintos tipos de
programas que podemos crear con PL/SQL.

Gestión de excepciones
Las excepciones sirven para tratar los errores y mensajes. Oracle tiene una serie de
excepciones que son las más frecuentes y con las que la mayoría de la gente trabaja.

Unas de las más usadas son: NO_DATA_FOUND (cuando una orden tipo select no ha
devuelto ningún valor) TOO_MANY_ROWS (cuando una orden tipo select ha devuelto mas de
una fila) OTHERS THEN RAISE_APPLICATION_ERROR (para cualquier otro tipo de error
desconocido)

Un ejemplo seria el siguiente:

DECLARE
vapellido varchar(10);
voficio varchar(20);
BEGIN
select apellido,oficio INTO vape,voficio from emple where emp=15;
DBMS_OUTPUT.PUT_LINE (vape||: - || voficio);
EXCEPTION
WHEN NO_DATA_FOUND THEN insert into temp values('No hay datos');
WHEN TOO_MANY_ROWS THEN insert into temp values ('Demasiados datos');
WHEN OTHER THEN RAISE_APPLICATION_ERROR(-2000,'Error en aplicación');
END;

Estructura modular
En PL/SQL podemos distinguir 3 tipos de programas o bloques.Bloques anónimos: Son los que
no tienen nombre y comienzan con el DECLARE, es decir los que hemos ido viendo hasta
ahora.Procedimientos: Se trata del programa más utilizado en PL/SQL y su formato es el
siguiente:

PROCEDURE <nombre_procedimiento>
[(<lista de parámetros>)]
IS
[<declaraciones>]
BEGIN
<instrucciones>;
[EXCEPTIONS
<excepciones>;]
END;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 51 de 84
En el formato distinguimos dos partes claramente, la cabecera donde esta el nombre del
procedimiento y los parámetros y el cuerpo donde se situá un bloque anónimo.

Funciones: similares a los procedimientos pero con la función añadida de que pueden devolver
valores.

Si subís varias lineas y veis el ejemplo de control de excepciones, podéis ver que hemos
utilizado un atributo como DBMS_OUTPUT. Bien pues esto lo que nos permite es visualizar en
pantalla los resultados, tanto excepciones como mensajes. Lo utilizamos porque PL/SQL no
dispone de ordenes o sentencias que capturen datos introducidos por teclado, ni tampoco para
visualizar datos en pantalla.

DBMS_OUTPUT.PUT_LINE nos permite visualizar en pantalla, pero para que funcione


correctamente tenemos que poner el SET SERVEROUTPUT a ON

Si queremos que un bloque nos pida algún dato tenemos que anteponer el símbolo & delante
de la variable, de esta forma cuando el bloque llegue a ese punto nos pedirá por pantalla el
valor.

Otra sentencia importante es la que nos permite visualizar los errores que hemos podido tener
al crear el bloque o procedimiento. Esta sentencia es: show errors

Podemos agregar comentarios a nuestros bloques anteponiendo al comentario /* <comentario> */

Si queremos que el bloque anónimo se ejecute directamente cuando terminamos de crearlo


debemos poner el símbolo / que, ademas de guardar el bloque en el buffer, lo ejecuta.

También podemos guardar los bloques anónimos en ficheros para poderlos ejecutar
posteriormente. Para ello ejecutamos la siguiente sentencia:

save nombrefichero

Y para ejecutarlo primero tenemos que cargar el fichero en el buffer y para ello tenemos que
ejecutar la siguiente sentencia:

get nombrefichero

Una vez cargado el fichero ejecutamos el bloque con la sentencia run nombrefichero. O
podemos hacer los dos pasos con una sola sentencia: start nombrefichero

Sin embargo para los procedimientos es totalmente distinto ya que al tener nombre se
almacena automáticamente en la base de datos y para ejecutarlo tan solo tenemos que realizar
la siguiente operación:

execute nombre_procedimiento(parámetros);

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 52 de 84
En el siguiente capitulo revisaremos todo lo que hemos visto en la introducción del PL/SQL,
pero de una forma mas exhaustiva.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 12/03/2009
Disponible online en https://desarrolloweb.com/articulos/caracteristicas-plsql-II.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 53 de 84
Bloques anónimos y procedimientos
PL/SQL

En este artículo vamos a ver el uso y ejemplos de los bloques anónimos en PL/SQL y los
procedimientos.

Para continuar las explicaciones sobre PL/SQL que estamos publicando en el Tutorial de
Oraclede Desarrolloweb.com, veamos a continuación dos importantes elementos de esta
plataforma.

Bloques anónimos PL/SQL


Empezaremos con los bloques anónimos, caracterizados porque no tienen nombre y se suelen
crear y ejecutar desde PL/SQL.

Todo bloque debe acabar en . para que sea almacenado en el buffer SQL. Una vez guardado lo
podemos ejecutar con la orden “run”. También podemos guardarlo en un fichero con la
siguiente orden:

save nombrefichero [replace]

El replace sólo lo pondremos si el fichero ya esta creado.

Para cargar y ejecutar este bloque anónimo guardado en fichero ejecutaremos la siguiente
orden:

start nombrefichero

El start lo podemos cambiar por la @ y nos funcionará igualmente.

Pero también podemos cargarlo sin ejecutarlo con la orden “get” y luego ejecutarlo
posteriormente con la orden “run”

Un ejemplo muy sencillo de bloque seria el que nos muestra en pantalla un nombre.

BEGIN
DBMS_OUTPUT.PUT_LINE('nombre');
END;
.

Además en los bloques PL/SQL se pueden utilizar lo que llamamos variables de sustitución,
que nos pedirán datos por pantalla antes de ejecutar el bloque. Estas variables tienen que ir

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 54 de 84
antepuestas del & para que funcionen.

Un ejemplo seria un bloque que nos pide el DNI de un usuario y nos muestra su nombre.

DECLARE
Vnom clientes.nombre%TYPE;
BEGIN
select nombre into Vnom from clientes where NIF= '&V_nif';
DBMS_OUTPUT.PUT_LINE (Vnom);
END;
.

Como veis es bastante sencillo, pero no tienen tanta funcionalidad como los procedimientos o
funciones.

Procedimientos y funciones PL/SQL


Los procedimientos y funciones quedan almacenados en la base de datos a diferencia de los
bloques anónimos que se almacenaban en el buffer.

Nota: Al quedar los bloques anónimos almacenados en el buffer, a no ser que se guardasen
en ficheros, se perderían al limpiar el buffer, cosa que no ocurre con los procedimientos y
funciones, que se almacenan en la propia base de datos.

Otra cosa que nos diferencia los bloques anónimos de los procedimientos o funciones es que en
los procedimientos o funciones no se pueden utilizar variables de sustitución.

En cuanto a su construcción es la dada en el articulo Características de PL/SQL segunda parte


añadiendo al principio la siguiente secuencia “CREATE OR REPLACE” para crearlo, o
modificarlo si ya existe.

Pasamos a escribir un procedimiento que nos muestre los datos de un usuario:

CREATE OR REPLACE PROCEDURE ver_usuario(nomusu VARCHAR2)


IS
NIFusu VARCHAR2(10);
Domusu VARCHAR2(10);
BEGIN
select nif, domicilio into NIFusu,Domusu from usuario where nombre=nomusu;
DBMS_OUTPUT.PUT_LINE('Nombre:'||nomusu|| 'NIF:' ||NIFusu|| 'Domicilio' ||Domusu);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No hemos encontrado al usuario || nomusu);
END;
/

Si el compilador detecta errores nos saldrá un mensaje como este: “Procedimiento creado con
errores de compilación”. Para ver estos errores tenemos la orden SHOW ERRORS.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 55 de 84
Al tener almacenado el procedimiento en la base de datos, este puede ser llamado por
cualquier usuario que tenga los permisos oportunos. Para invocar un procedimiento utilizamos
la orden EXECUTE

Para invocar al procedimiento que hemos creado antes tendríamos que ejecutar la siguiente
orden:

EXECUTE ver_usuario('Luis');

Pero también podemos invocarlo desde un bloque PL/SQL de ls siguiente forma:

BEGIN
ver_usuario('Luis');
END;
.

Como en cualquier lenguaje, podemos agregar comentarios a nuestros procedimientos de la


siguiente forma:

para comentar en una sola linea /* <comentario>*/ para varias lineas.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 01/04/2009
Disponible online en https://desarrolloweb.com/articulos/bloque-anonimo-
procedimiento-plsql.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 56 de 84
Fundamentos del lenguaje PL/SQL

En este artículo estudiaremos los fundamentos de PL/SQL y algunos de los elementos que
constituyen este lenguaje.

Para continuar con el manual de Oracle publicado en DesarrolloWeb.com, es hora de


adentrarnos en las explicaciones de los elementos que forman parte del lenguaje PL/SQL.

Tipos de datos
Este lenguaje dispone de los mismo tipos de datos que podemos encontrar en SQL, pero
además se han incorporado algunos nuevos:

char(n): almacena una cantidad fija de caracteres


varchar2(n): almacena cadenas de caracteres de longitudes variables
long(n): almacena cadenas de longitud variable
number(p,e): almacena numero de precisión p y escala e
boolean: almacena valores lógicos, true, false o NULL
date: almacena fechas completas, incluida la hora
raw(n): almacena datos binarios de longitud fija
long raw : almacena datos binarios de longitud variable
rowid: almacena identificadores de direcciones de fila
etc.

Además es importante señalar que el programador puede definir sus propios tipos de datos a
partir de los ya definidos.

Identificadores
Se utilizan para nombrar los objetos que intervienen en los programas PL/SQL como son las
variables, constantes, cursores, excepciones, procedimientos, etc.

Pueden tener como máximo 30 caracteres empezando siempre por una letra, que puede ir
seguida por otras letras, numeros, $, # ó _. Es importante destacar que PL/SQL no diferencia
entre mayúsculas y minúsculas. También debemos señalar que no pueden contener espacios ni
signos de puntuación.

Variables
Como doy por sentado que todos sabemos lo que son las variables, pasaremos directamente a
comentar como se declara una variable en PL/SQL.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 57 de 84
<nombreVariable> <tipo> [NOT NULL] [{:= | DEFAULT } <valor>]

No podemos indicar una lista de variables del mismo tipo y luego declarar el tipo, tenemos que
hacerlo una a una.

Uno ejemplo de declaración de variables seria el siguiente:

DECLARE
importe NUMBER (8,2);
contador NUMBER(2'0);
nombre char(5) NOT NULL :="Sara";
...

Uso de los atributos %TYPE y %ROWTYPE

%TYPE: declara una variable del mismo tipo que otra, o que una columna de una tabla
%ROWTYPE : crea una variable registro cuyos campos se corresponden con las columnas de
una tabla o vista.

Por ejemplo si tenemos una variable definida previamente llamada cantidad podemos definir
otra de la siguiente forma:

total cantidad%TYPE;

De esta forma la variable total tendrá las mismas características que la variable cantidad. Otro
ejemplo seria declarar una variable que fuera del mismo tipo que la columna nombre de la
tabla profesor.

nombre_alta nombre%ROWTYPE;

Ámbito y visibilidad de variables

La variable será local para el bloque en el que ha sido declarada y global para los bloque hijos
de éste, mientras que las variables declaradas en los bloque hijos no son globales a los bloques
padre.

Constantes
Cómo en la mayoría de los lenguajes, en este también podemos declaras constantes, de la
siguiente forma:

<nombreVariable> CONSTANT <tipo> := <valor>;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 58 de 84
Operadores
| Asignación | := | | Lógicos | AND OR NOT | | Concatenación | || | | Comparación | Is null =
!= <> <

<=

= between...and like in y sus correspondientes negaciones | | Aritméticos | + - * / ** |

Funciones predefinidas
En PL/SQL tenemos las mismas funciones predefinidas que en SQL (AVG, MIN, MAX,
COUNT, SUM, etc), pero tenemos que tener dos cosas muy claras a la hora de utilizarlas y son:

1. La función no modifica el valor de las variables o expresiones que se pasan como


argumentos, sino que devuelve un valor a partir de dicho argumento.
2. Si a una función se le pasa un valor nulo en la llamada, posiblemente devolverá un valor
nulo.

Etiquetas
Podemos utilizar etiquetas para poder irnos a cualquier parte del programa utilizando la
sentencia GOTO siempre y cuando se cumplan las siguientes reglas: No pueden haber
etiquetas con los mismos nombres en un mismo programa. La etiqueta debe preceder a un
bloque o a un conjunto de ordenes ejecutables la etiqueta no puede estar dentro de estructuras
de control (IF, LOOP)

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 21/04/2009
Disponible online en https://desarrolloweb.com/articulos/fundamentos-lenguaje-
plsql.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 59 de 84
Subprogramas PL/SQL

Los subprogramas son los bloques PL/SQL con nombre que pueden recibir y devolver valores.

En cualquier subprograma podemos distinguir:

La cabecera, compuesta por el nombre del subprograma, los parámetros y el tipo de


valor de retorno.
El cuerpo, compuesto por las declaraciones, las instrucciones y el manejo de
excepciones.

Podemos distinguir entre dos tipos de subprogramas, como ya hemos comentado en artículos
anteriores:

Procedimientos
Los procedimientos ya los hemos visto en el articulo “Bloques anónimos y procedimientos
PL/SQL ” por lo que pasamos directamente a las funciones.

Funciones
Las funciones son muy similares a los procedimiento con la diferencia que éstas siempre
devolverán un valor. Su estructura es la siguiente:

CREATE [OR REPLACE] FUNCTION NombreFuncion [(parámetros)] RETURN tipo


IS [parte declarativa]
BEGIN
instrucciones
RETURN <valor o expresión>;
[EXCEPTION excepciones]
END;

La cláusula RETURN de la cabecera nos especifica el tipo de valor que nos va a devolver la
función.

Parámetros
Todos los subprogramas utilizan parámetros para pasar y recibir información. Dentro de los
parámetros podemos distinguir dos tipos:

Parámetros actuales: son variables indicadas en la llamada a un subprograma.


Parámetros formales: son variables declaradas en la especificación del subprograma.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 60 de 84
Además podemos hacer el paso de parámetros de un tipo a otro. Generalmente si los tipos son
compatibles PL/SQL lo hace automáticamente. En cualquier caso, podemos hacerlo de forma
manual utilizando las siguientes notaciones:

Posicional: el compilador asocia los parámetros actuales a los formales, basándose en


suposición.
Nominal: el símbolo => después del parámetro actual y antes del nombre del formal,
indica al compilador correspondencia.
Mixta: nos permite usar las dos notaciones anteriores.

Para que esto quede más claro pasamos a escribir un ejemplo de paso de parámetros y
conversión de tipos.

Tenemos la especificación de un procedimiento como esta:

PROCEDURE departamento(
n_departamento INTEGER,
localidad VARCHAR2
IS...

Desde el siguiente bloque se podrán realizar las llamadas indicadas:

DECLARE
num_departamento INTEGER;
aula VARCHAR(30)
BEGIN
...
- - posicional departamento(num_departamento, aula);
- - nominal departamento(num_departamento => n_departamento, aula =>localidad);
...
END;

Esto nos pasaría los parámetros num_departamento al mismo tipo que n_departamento y
localidad al mismo tipo que aula.

Los parámetros que soporta PL/SQL pueden ser de entrada, salida o entrada/salida

| IN | Nos permite pasar valores a un subprograma. Dentro del subprograma, el parámetro


actuá como una constante. Puede ser una variable, constante, literal o expresión. | | OUT |
Permite devolver valores al bloque que llamó al subprograma. Dentro del subprograma, el
parámetro actúa como una variable no inicializada. Solo puede ser una variable. | | IN OUT |
Permite pasar un valor inicial y devolver un valor actualizado. Dentro del subprograma, el
parámetro actuá como variable inicializada. Puede intervenir otras expresiones. El valor actual
debe ser una variable. |

El formato genérico es el siguiente:

<nombrevariable> [IN | OUT | IN OUT] <tipodato>


[ { := | DEFAULT} <valor>]

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 61 de 84
Además es importante recordar que al especificar parámetros debemos indicar el tipo, pero no
el tamaño.

Creación, modificación y borrado de subprogramas


Cuando creamos subprogramas con SQL * PLUS utilizando los comandos CREATE, Oracle
automáticamente compila el código fuente, genera el código objeto y los guarda en el
diccionario de datos, quedando disponibles para su utilización.

Para volver a compilar un subprograma almacenado utilizaremos la orden ALTER en vez del
CREATE y su formato es el siguiente:

ALTER {PROCEDURE | FUNCITON} nombresubprograma COMPILE;

Para ver el código de un subprograma almacenado podemos ejecutar una sentencia como esta;

select LINE, SUBSTR(TEXT,1,60) from USER_SOURCE where name = 'nombresubprograma';

Para borrar un subprograma almacenado utilizaremos la orden DROP de la siguiente forma:

DROP {PROCEDURE | FUNCTION} nombresubprograma;

Nota: PL/SQL implementa la recursividad en los subprogramas, esto quiere decir, que un
programa puede llamarse a si mismo.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 19/05/2009
Disponible online en https://desarrolloweb.com/articulos/subprogramas-plsql.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 62 de 84
Cursores en PL/SQL primera parte

Comenzamos a explicar los cursores de PL/SQL. Veremos los cursores explícitos, sus atributos
y las variables de acoplamiento .

En los anteriores capítulos hemos visto los fundamentos del lenguaje PL/SQL, bien pues, a
partir de ahora pasaremos a estudiar el manejo de este lenguaje para trabar con el gestor de
Oracle. Empezaremos con la utilización de cursores.

Hasta ahora hemos utilizado cursores implícitos, cuando devolvíamos el resultado de una
select mediante la clausula into a una variable. Pero esto es un problema cuando el resultado
de una subconsulta nos devolvía varias filas, porque esto nos daria un error al ejecutar la
consulta

Para que no nos salte un error en estos casos debemos utilizar los cursores explícitos.

Cursores explícitos
Los cursores explícitos los utilizamos cuando tenemos consultas que nos devuelven más de una
fila. Tenemos 4 operaciones básicas para trabajar con un cursor explícito.

1. Declaración del cursor: lo tenemos que declarar en la zona de declaraciones, con el


siguiente formato:

CURSOR <nombrecursor> IS <sentencia SELECT>;

2. Apertura del cursor: Deberá colocarse en la zona de instrucciones, con el siguiente


formato:

OPEN <nombrecursor>;

Al hacerlo se ejecuta automáticamente la sentencia select y sus resultados se almacenan


en las estructuras internas de memoria manejadas por el cursor.

3. Recogida de información: Para recuperar la información anteriormente guardada en las


estructuras de memoria interna tenemos que usar el siguiente formato:

FETCH <nombrecursor> INTO {<variable> | <listavariables>};

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 63 de 84
Si tenemos una única variable que recoge los datos de todas las columnas, el formato de
la variable seria el siguiente:

<variable> <nombrecursor>%ROWTYPE;

Si tenemos una lista de variables, cada una recogerá la columna correspondiente de la


cláusula select, por lo que serán del mismo tipo que las columnas.

4. Cierre del cursor:

CLOSE <nombrecursor>;

Ahora, veamos un ejemplo de utilización de cursores explícitos:

DECLARE
CURSOR C1 IS SELECT nombre, apellido FROM arbitro;
Vnom VARCHAR2(12);
Vape VARCHAR2(20);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO Vnom, Vape;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(Vnom || '' || Vapen);
END LOOP;
CLOSE C1;
END;

Si nos fijamos, en la declaración de los cursores explícitos no utilizamos la cláusula INTO, que
sí se utilizaba en los cursores implícitos.

Ademas podéis ver que después del FETCH hemos comprobado si nos devuelve valores con la
linea del EXIT. Es algo importante ya que si no nos devuelve nada el LOOP se interrumpirá.

Atributos del cursor


Para conocer detalles de la situación del cursor tenemos 4 atributos:

%FOUND: devuelve verdadero di el ultimo FETCH ha recuperado algún valor; en caso


contrario devuelve falso; si el cursor no esta abierto nos devuelve error.
%NOTFOUND: hace justamente lo contrario al anterior.
%ROWCOUNT: nos devuelve el número de filas recuperadas hasta el momento.
%ISOPEN: devuelve verdadero si el cursor esta abierto.

Veamos ahora un ejemplo de utilización de %ROWCOUNT:

DECLARE
CURSOR C1 IS SELECT nombre from futbolista WHERE Cod='e1';

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 64 de 84
Vnom VARCHAR2(15);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO Vnom;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (C1%ROWCOUNT || Vnom);

END LOOP;
CLOSE C1;
END;

Variables de acoplamientos en el manejo de cursores


En el ejemplo siguiente podemos observar que en la cláusula WHERE se incluye una variable
que se debería haber declarado previamente. Este tipo de variables reciben el nombre de
variables de acoplamiento. El programa la sustituirá por su valor en el momento en que se abre
el cursor, y se seleccionarán las filas según dicho valor. Aunque ese valor cambie durante la
recuperación de los datos con FETCH, el conjunto de filas que contiene el cursor no variará.

El ejemplo nos muestra los futbolistas de un equipo cualquiera.

CREATE OR REPLACE PROCEDURE ver_futbolistas_por_equipos(codeq VARCHAR2)


IS
Vequi VARCHAR2(3);
CURSOR C1 IS SELECT nombre from futbolista where codeq=Vequi;
Vnom VARCHAR(15);
BEGIN
vequi:=codeq;
OPEN C1;
FETCH C1 INTO vnom;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(Vnom);
FETCH C1 INTO Vnom;
END LOOP;
CLOSE C1;
END;

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 03/06/2009
Disponible online en https://desarrolloweb.com/articulos/cursores-pl-sql-I.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 65 de 84
Cursores PL/SQL segunda parte

Continuamos con los cursores de PL/SQL, esta vez vamos a ver variables de acoplamiento y
cursores con parámetros.

Dando continuidad al Manual de Oracle que estamos publicando en DesarrolloWeb.com, y en


el apartado del lenguaje PL/SQL, continuamos nuestras explicaciones sobre los cursores, que
habíamos comenzado a explicar en el artículo anterior.

Variables de acoplamiento
Si os fijáis en el siguiente ejemplo veréis que en la cláusula where se incluye una variable que
se deberá declarar previamente. Este tipo de variables recibe el nombre de variables de
acoplamiento. El programa la sustituirá por su valor en el momento en que se abre el cursor, y
se seleccionarán las filas según dicho valor.

Create or replace procedure ver_jugador(codeq varchar2)


IS
vequi varchar2(3);
cursor c1 is select nombre from jugador where cod=vequi;
vnom varchar2(15);
BEGIN
vequi:=codeq;
OPEN c1;
FETCH c1 INTO vnom;
WHILE c1%found LOOP
DBMS_OUTPUT.PUT_LINE(vnom);
FETCH c1 INTO vnom;
END LOOP;
CLOSE c1;
END;

Cursor FOR …. LOOP


El trabajo normal de un cursor consiste en declarar un cursor, declarar una variable que
recogerá los datos del cursor, abrir el cursor, recuperar con fetch, una a una, las filas extraídas
introduciendo los datos en las variables, procesándolos y comprobando si se han recuperado
datos o no.

Para resumir todas esas tareas, tenemos una estructura cursor FOR...LOOP que hace todas
estas cosas de forma implícita, todas menos la declaración del cursor.

El formato y el uso de esta estructura es:

1. se declara la información cursor en la sección correspondiente

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 66 de 84
2. Se presenta el cursor utilizando el siguiente formato: FOR nombreVarReg IN
nombreCursor LOOP …. END LOOP; Al entrar en el bucle se abre el cursor de manera
automática, se declara implícitamente la variable nombreVarReg de tipo
nombrecursor%ROWTYPE y se ejecuta el primer fetch cuyo resultado quedarán en
nombreVarReg. A continuación se realizaran las acciones que correspondas hasta llegar
al END LOOP.

Este es un ejemplo del LOOP …. END LOOP:

DECLARE
cursor c2 is select nombre, peso, estatura from jugador where salario>1200;
BEGIN
FOR vreg IN c2 LOOP
DBMS_OUTPUT.PUT_LINE (vreg.nombre || '-' ||vreg.peso || '-' || vreg.estatura);
END LOOP;
END;

Cursores con parámetros


Un cursor puede tener parámetros; en este caso se aplicara el siguiente formato genérico:

CURSOR nombrecursor [(parámetros)] IS SELECT <sentencia select en la que intervendrán los parámetros>;

Los parámetros formales indicados después del nombre del cursor tienen la siguiente sintaxis:

nombreCursor [IN] tipodato [{:=|DEFAULT} valor]

Todos los parámetros formales de un cursor son parámetros de entrada y su ámbito es local al
cursor por eso sólo pueden ser referenciados dentro de la consulta.

Un ejemplo seria el siguiente:

DECLARE
...
CURSOR C1 (vpeso number, vestatura number DEFAULT 170) is select nficha, nombre FROM emple WHERE estatura=vestatura AND peso=vpeso;

Para abrir un cursor con parámetros lo haremos de la siguiente forma:

OPEN nombrecursor [(parámetros)];

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 09/07/2009
Disponible online en https://desarrolloweb.com/articulos/cursores-pl-sql-II-parte.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 67 de 84
Cursores PL/SQL tercera parte

Continuamos con los cursores, esta vez vamos a ver atributos con cursores explícitos y uso de
cursores para actualizar filas.

Atributos con Cursores implícitos


Los atributos de los cursores implícitos que se crean son los siguientes:

SQL%NOTFOUND: nos dice si el último insert, update,delete o select into no han


afectado a ninguna fila.
SQL%FOUND: nos dice si el último insert, update,delete o select into ha afectado a una
o mas filas
SQL%ROWCOUNT: devuelve el número de filas afectadas por el último insert, update,
delete o select into
SQL%ISOPEN: Nos dice si el cursor esta cerrado, por lo que en teoría siempre nos dará
falso ya que Oracle cierra automáticamente el cursor después de cada orden SQL.

Es importante tener en cuenta una serie de cosas:

Si se trata de un select into tenemos que tener en cuenta que solo puede devolver una única fila
de lo contrario nos levantará automáticamente una de estas dos excepciones:

NO_DATA_FOUND: si la consulta no devuelve ninguna fila* TOO_MANY_ROWS: si


la consulta devuelve más de una fila Cuando un select into hace referencia a una
función de grupo nuca se levantará la excepción NO_DATA_FOUND y SQL%FOUND
siempre será verdadero. Esto se explica porque las funciones de grupo siempre
devuelven algún valor (NULL se considera un valor).

Uso de cursores para actualizar filas


Para realizar una actualización con un cursor tenemos que añadir la siguiente FOR
UPDATE al final de la declaración del cursor:

CURSOR nombre_cursor <declaraciones> FOR UPDATE

Esto indica que las filas seleccionadas por el cursor van a ser actualizadas o borradas.
Una vez declarado un cursor FOR UPDATE, se incluirá el especificador CURRENT OF
nombre_cursor en la cláusula WHERE para actualizar o borrar la última fila
recuperada mediante la orden FETCH.

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 68 de 84
{UPDATE|DELETE}... WHERE CURRENT OF nombre_cursor.

Os pongo un ejemplo para que quede claro:

Subir el salario a todos los empleados del departamento indicado en la llamada. El


porcentaje se indicará también en la llamada.

CREATE OR REPLACE PROCEDURE subir_salario (num_dept NUMBER, incre NUMBER)


IS
CURSOR c IS SELECT oficio, salario FROM empleados WHERE cod_dept=num_dept
FOR UPDATE;
reg c%ROWTYPE;
inc NUMBER (8);
BEGIN
OPEN c;
FETCH c INTO reg;
WHILE c%FOUND LOOP
inc :=(reg.salario/100 )* inc;
UPDATE empleados SET salario=salario+inc WHERE CURRENT OF c
FETCH c INTO reg;
END LOOP;
END;

También podemos usar ROWID en lugar de FOR UPDATE. ROWID nos indicará la fila
que se va a actualizar. Para ello, al declarar el cursor en la cláusula SELECT
indicaremos que seleccione también el identificador de fila:

CURSOR nombre_cursor IS SELECT columna1,columna2,...ROWID FROM tabla;

Al ejecutarse el FETCH se guardará el número de fila en una variable y después ese


número se podrá usar en la cláusula WHERE de la actualización:

{UPDATE |DELETE } ... WHERE ROWID = variable_rowid

El ejemplo anterior utilizando ROWID quedaría de la siguiente manera:

CREATE OR REPLACE PROCEDURE subir_salario (num_dept NUMBER, incre NUMBER)


IS
CURSOR c IS SELECT oficio, salario,ROWID FROM empleados WHERE cod_dept=num_dept
FOR UPDATE;
reg c%ROWTYPE;
inc NUMBER (8);
BEGIN
OPEN c;
FETCH c INTO reg;
WHILE c%FOUND LOOP
inc :=(reg.salario/100 )* inc;
UPDATE empleados SET salario=salario+inc WHERE ROWID = reg.ROWID;
FETCH c INTO reg;
END LOOP;
END;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 69 de 84
Con este artículo damos por terminado todo lo referente a cursores y empezamos a
tratar las excepciones en el siguiente artículo.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 07/09/2009
Disponible online en https://desarrolloweb.com/articulos/cursores-pl-sql-III-parte.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 70 de 84
Excepciones en Oracle y PL/SQL

Las excepciones en el sistema gestor Oracle y el lenguaje PL/SQL, nos ayudan a detectar y
tratar errores en tiempo de ejecución.

En este artículo del Manual de PL/SQL de Oracle vamos a ver lo que son las excepciones, para
qué sirven y cómo utilizarlas. Daremos un repaso también a los tipos de excepciones, las
excepciones definidas por el usuario y la sintaxis con la que tenemos que especificarlas.

Por último, de paso que vemos cosas acerca del tratamiento de errores en PL/SQL,
explicaremos el RAISE_APPLICATION_ERROR, un componente del sistema gestor de base
de datos Oracle que ayuda a gestionar errores y sus mensajes de error.

Qué son las excepciones en Oracle


Las excepciones, presentes en la mayoría de los lenguajes de programación, sirven para tratar
errores en tiempo de ejecución. En el sistema que nos ocupa, Oracle, sirven también para
definir qué se debe hacer frente a errores en sentencias definidas por el usuario. Cuando se
produce un error PL/SQL levanta una excepción y pasa el control a la sección excepción
correspondiente al bloque PL/SQL.

El formato sería el siguiente:

BEGIN
.........
......
......
EXCEPTION
WHEN <nombre_excepción> THEN
<instrucciones>;
......
[WHEN OTHERS THEN <instrucciones>;]
END;

Excepciones predefinidas
Son aquellas que se disparan automáticamente al producirse determinados errores. Estas son
las más comunes:

too_many_rows: Se produce cuando select … into devuelve más de una fila. no_data_found:
se produce cuando un select …. into no devuelve ninguna fila. login_denied: error cuando
intentamos conectarnos a Oracle con un login y clave no validos. not_logged_on: se produce
cuando intentamos acceder a la base de datos sin estar conectados. program_error: se produce
cuando hay un problema interno en la ejecución del programa. value_error: se produce cuando

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 71 de 84
hay un error aritmético o de conversión. zero_divide: se puede cuando hay una división entre
0. dupval_on_index: se crea cuando se intenta almacenar un valor que crearía duplicados en la
clave primaria o en una columna con restricción UNIQUE. invalid_number: se produce
cuando se intenta convertir una cadena a un valor numérico.

Hay alguna más pero estas son las más utilizadas y tenemos que tener en cuenta que no es
necesario declararlas en la sección DECLARE.

Excepciones definidas por el usuario


Son aquellas que crea el usuario. Para ello se requieren tres pasos:

1. Definición: se realiza en la zona de DECLARE con el siguiente formato:


nombre_excepción EXCEPTION
2. Disparar o levantar la excepción mediante la orden raise: RAISE <nombre_excepción>;
</nombre_excepción>
3. Tratar la excepción en el apartado EXCEPTION: WHEN <nombre_excepción>THEN ;
</nombre_excepción>

Para que esto quede más claro ponemos un ejemplo a continuación.

DECLARE
...
Importe_mal EXCEPTION;
...
BEGIN
...
IF precio NOT BETWEEN mínimo and máximo THEN
RAISE importe_mal;
END IF;
...
EXCEPTION
WHEN importe_mal THEN DBMS_OUTPUT.PUT_LINE("Importe incorrecto");
...
END;

Otras excepciones
Existen otros errores internos de Oracle que no tienen asignada una excepción, sino un código
de error y un mensaje, a los que se accede mediante funciones SQLCODE y SQLERRM.
Cuando se produce un error de estos se trasfiere directamente el control a la sección
EXCEPTION donde se tratara el error en la clausula WHEN OTHERS de la siguiente forma:

WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error'||SQLCODE||SQLERRM.)

Utilización de RAISE_APPLICATION_ERROR
En el paquete DBMS_STANDARD se incluye un procedimiento llamado
RAISE_APPLICATION_ERROR que nos sirve para levantar errores y definir mensajes de

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 72 de 84
error. Su formato es el siguiente:

RAISE_APPLICATION_ERROR(numero_error,mensaje_error);

Es importante saber que el numero de error esta comprendido entre -20000 y -20999 y el
mensaje es una cadena de caracteres de hasta 512 bytes. Este procedimiento crea una
excepción que solo puede ser tratada en WHEN OTHERS.

Ponemos un ejemplo para que nos quede más claro.

CREATE or REPLACE PROCEDURE subir_horas (emple NUMBER, horas_subir NUMBER)


IS
horas_actuales NUMBER;
BEGIN
Select horas into horas_actuales from empleados where id_empleado=emple;
if horas_actuales is NULL then
RAISE_APPLICATION_ERROR(-20010,'No tiene horas');
else
update empleados set horas=horas_actuales + horas_subir where id_empleado=emple;
end if;
End subir_horas;

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 13/10/2009
Disponible online en https://desarrolloweb.com/articulos/excepciones-oracle.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 73 de 84
Control de transacciones

Control de transacciones en Oracle. Una transacción se define como un conjunto de


operaciones sobre la base de datos.

En Oracle si se ejecuta un conjunto de operaciones y una de ellas falla se aborta la transacción


entera. En este artículo veremos todo lo que debemos saber sobre transacciones y algunos
ejemplos interesantes. Está englogado dentro del Manual de Oracle que venimos publicando
en DesarrolloWeb.com.

La transacción finaliza cuando se ejecuta un comando de control de transacciones como


rollback o commit work (se puede abreviar poniendo simplemente commit).

Un ejemplo:

BEGIN
....

update alumnos set edad=20 where n_alumno=109;


update nuevos set apellido='perez' where n_alumno=200;
commit work;

...

EXCEPTION
WHEN OTHERS THEN
rollback work;
END;

Comandos utilizados para el control de transacciones


Commit Este comando da por concluida la transacción actual y hace definitivos los cambios
realizados liberando las filas bloqueadas. Sólo después de que se ejecute commit tendremos
acceso a los datos modificados.

Rollback Este comando da por concluida la transacción actual y deshace los cambios que se
pudiesen haber producido en la misma, liberando las filas bloqueadas. Se utiliza especialmente
cuando no se puede concluir una transacción porque se han levantado excepciones.

Savepoint Se utiliza para poner marcas o puntos de salvaguarda al procesar transacciones. Se


utiliza junto con rollback permitiendo deshacer cambios hasta los savepoint. El número de
savepoint esta limitado a 5 por sesión pero lo podemos modificar con la siguiente sentencia:

savepoint numero;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 74 de 84
Rollback implicito Este comando se ejecuta cuando un programa almacenado (procedimiento
o función) falla y no se controla la excepción que produjo el fallo. Pero si en el programa
tenemos un commit estos cambios no serán deshechos.

Rollback to Deshace el trabajo realizado después del punto indicado. Pero no se confirma el
trabajo hecho hasta el savepoint. La transacción no finaliza hasta que se ejecuta un comando
de control de transacciones o hasta que finaliza la sesión.

Os dejo a continuación un ejemplo bastante completo de lo que seria el control de


transacciones:

create or replace procedure prueba (nfilas number)


as
begin
savepoint ninguna;
insert into tmp values ('primera fila');
savepoint una;
insert into tmp values ('segunda fila');
savepoint dos;
if nfilas=1 then
rollback to una;
else if nfilas=2 then
rollback to dos;
else
rollback to ninguna;
end if;
commit;
exception
when other then
rollback
end prueba;

Con este artículo terminamos la parte básica sobre oracle, PL/SQL y pasamos a lo que
podemos denominar programación avanzada de sql. Empezaremos con triggers en el siguiente
artículo.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 06/11/2009
Disponible online en https://desarrolloweb.com/articulos/control-transacciones-
oracle.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 75 de 84
Triggers a tablas en PL/SQL

Explicamos que son los triggers o disparadores de base de datos en PL/SQL de Oracle.

Como ya comentábamos en el articulo anterior, publicado en el Manual de Oracle de


DesarrolloWeb.com, comenzamos lo que podríamos denominar programación avanzada
dentro de PL/SQL.

En el presente artículo vamos a estudiar acerca de los triggers, donde veremos qué son y como
se construyen, comenzando con los trigger de tablas y más tarde veremos los trigger de
sustitución y los de sistema. Para ello lo primero que tenemos que ver es su definición.

Trigger a tablas
Un trigger es un bloque de código PL/SQL que se almacenan en la base de datos. Los bloques
de código de los triggers están asociados a una tabla y se ejecutan automáticamente cuando se
producen ciertos eventos asociados a la tabla.

Se suelen utilizar para prevenir transacciones erróneas y nos sirven también para implementar
restricciones de integridad o seguridad.

Su formato básico es el siguiente:

create or replace trigger nombre_trigger


{before | after} {delete | insert | update[of lista_columnas]}
[or {before | after} {delete|insert|update [of lista_columnas]}]
on nombre_tabla
[for each {row | statement | when (condición)}]
/* comienza el trigger */
[declare]
<declaraciones>
begin
<instrucciones>
[exception]
<excepciones>
end;

Elementos de un trigger
before / after: elemento que dispara el trigger nombre: nombre del trigger que tiene que ser
único. for each: nivel del disparo del trigger que por defecto es statement que significa que se
dispara una sola vez por cada operación independientemente del número de filas afectadas. for
each row: salta por cada fila afectada.

Variables posibles para update: la primera es :old que hace referencia a los valores anteriores y

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 76 de 84
:new que hace referencia a los nuevos valores de actualización de la fila. Tenemos que tener en
cuanta unos cuantos aspectos:

Cuando el evento que dispara el trigger es un delete haremos referencia al valor :old
porque el valor :new es nulo
Cuando el evento que dispara el trigger es un insert haremos referencia al valor :new
porque el :old es nulo.
Cuando el evento es un update tiene sentido hacer referencia a los dos valores.
Sólo se pueden utilizar cuando el trigger es a nivel de fila (for each row).

Vamos a a crear un trigger que se disparé automáticamente después de la modificación del


salario de la tabla empleado y pase un comentario a la tabla auditar.

Create or replace trigger auditar_salario


after update of salario
on empleado
for each row
begin
insert into auditar values
('se ha modificado el salario' || :old.num_empleado);
end;

Orden de ejecución de los trigger


Una misma tabla puede tener varios triggers y el orden de disparo seria el siguiente:

1. Antes de comenzar a ejecutar la orden que provoca el disparo se ejecutaran los triggers
del tipo before.... for each statement
2. Para cada fila afectada por la orden: a) se ejecutan los triggers del tipo before … for each
row b) se ejecuta la actualización de la fila c) se ejecutan los triggers after... for each row
3. Una vez realizada la operación se ejecuta el after … for each statement

Cuanndo se dispara un trigger este forma parte de la operación que lo disparó de manera que
si el trigger falla, Oracle dará por fallida la operación completa. Aunque el fallo sea a nivel de
fila se hará rollback a toda la operación.

Ejemplo:

create or replace trigger nombre_trigger


before insert or delete
begin
if insert then
.....
elseif deleting then
....
elseif updating then
...
end if
....
end;

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 77 de 84
En el siguiente articulo veremos los triggers de sustitución y los del sistema.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 09/12/2009
Disponible online en https://desarrolloweb.com/articulos/triggers-tablas.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 78 de 84
Triggers de sustitución y de sistema

Vemos lo que es un disparador de sustitución y el de sistema, así como su creación en Oracle.

Disparadores de sustitución
Podemos crear triggers que no se ejecutan antes ni después de una instrucción sino en lugar de
(instead of). Solo podemos utilizar estos triggers si están asociados a vistas, además actúan
siempre a nivel de fila.

La sintaxis de este tipo de trigger es la siguiente:

create [or replace] trigger nombre_trigger


instead of { insert | delete | update [of columnas]}
[ or { insert | delete | update}]
on nombre vista
[ for each row]
[declare]
declaraciones
begin
instrucciones
[execption]
excepciones
end;

Sobre una vista podemos hacer un select pero si hacemos un insert, delete o update puede
darnos problemas y no dejar ejecutarse la orden correctamente. Los trigger sobre vistas vas a
sustituir a estas operaciones por las correspondientes en las tablas que forman la vista.

Un ejemplo de trigger de sustitución seria el siguiente:

create or replace trigger t_borrado_emp


instead of delete on empleado
for each row
begin
delete from emple where emp_num=:old.cod
end;

Disparadores de sistema
Estos trigger se disparan cuando se arranca o para la base de datos, entra o sale un usuario,
cuando se crea, modifica o elimina un objeto, etc.

En Oracle para crear este tipo de trigger tenemos que tener privilegios de Administer database

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 79 de 84
trigger.

La sintaxis de este trigger seria la siguiente:

create [or replace] trigger nombre_trigger


{ before | after } { <lista eventos de definición> | <lista eventos del sistema>}
on { database | schema} [when (condición)]
<cuerpo del trigger (bloque PL/SQL)>

Donde la lista de eventos de definición puede tener uno o más eventos DDL separados por or y
la lista de eventos del sistema igualmente separados por or.

Al asociar un disparador a un evento debemos indicar el momento en que se dispare. A


continuación os dejo una tabla de evento, momento y cuando se dispararía para dejarlo todo
mas o menos claro.

| Evento | Momento | Se disparan: | | STARTUP | AFTER | Después de arrancar la instancia | |


SHUTDOWN | BEFORE | Antes de apagar la istancia | | LOGON | AFTER | Después de que el
usuario se conecte a la base de datos. | | LOGOFF | BEFORE | Antes de la desconexión de un
usuario | | SERVERERROR | AFTER | Cuando ocurre un error en el servidor | | CREATE |
BEFORE | AFTER | Antes o después de crear un objeto en el esquema | | DROP | BEFORE |
AFTER | Antes o después de borrar un objeto en el esquema | | ALTER | BEFORE | AFTER |
Antes o después de cambiar un objeto en el esquema | | TRUNCATE | BEFORE | AFTER |
Antes o después de ejecutar un comando truncate | | GRANT | BEFORE | AFTER | Antes o
después de ejecutar un comando grant | | REVOKE | BEFORE | AFTER | Antes o después de
ejecutar un comando revoke | | DLL | BEFORE | AFTER | Antes o después de ejecutar
cualquier comando de definición de datos |

Oracle tiene algunas funciones que permiten acceder a los atributos del evento del disparo
ORA_YSEVENT, ORA_LOGIN, etc. Estas funciones pueden usarse en la clausula WHEN o en
el cuerpo del disparador. En el manual de Oracle podéis encontrar el listado de todas estas
funciones.

Un ejemplo seria un trigger que nos guarda los datos de un usuario al hacer login en la base de
datos:

create or replace trigger control


after logon
on database
begin
insert into control_conexion (usuario, momento, evento)
values {ORA_LOGIN_USER, SYSTIMESTAMP, ORA_SYSEVENT);
end;

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 28/01/2010
Disponible online en https://desarrolloweb.com/articulos/triggers-sustitucion-
sistema.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 80 de 84
http://desarrolloweb.com/manuales/tutorial-oracle.html Página 81 de 84
Paquetes en Oracle

Vamos a ver que son los paquetes en el sistema gestor de base de datos Oracle, explicando
estructura y funcionamiento.

En este artículo que pertenece al tutorial de Oracle trateremos el tema de los paquetes de
forma detenida.

Los paquetes en Oracle se utilizan para guardar subprogramas y otros objetos de la base de
datos.

Un paquete consta de los siguientes elementos:

Especificación o cabecera: contiene las declaraciones públicas (es decir, accesibles


desde cualquier parte de la aplicación) de sus programas, tipos, constantes, variables,
cursores, excepciones, etc.
Cuerpo: contiene los detalles de implementación y declaraciones privadas, es decir,
accesibles solamente desde los objetos del paquete.

La sintaxis de la cabecera es la siguiente:

create [or replace] package nombre_paquete as


<declaraciones públicas>
<especificaciones de subprogramas>
end nombre_paquete;

La sintaxis del cuerpo sería la siguiente:

create [or replace] package body nombre_paquete as


<declaraciones privadas>
<código de subprogramas>
[begin
<instrucciones iniciales>]
end nombre_paquete;

Como podéis observar la cabecera se compila independientemente del cuerpo. Os dejo un


ejemplo de paquete para que lo veáis más claro.

/* Cabecera */
create or replace package busar_emple as
TYPE t_reg_emple is RECORD
(num_empleado emple.emp_no%TYPE,
apellido emple.apellido%TYPE,

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 82 de 84
salario emple.salario%TYPE,
departamento emple.dept_no%TYPE);
procedure ver_por_numero(v_cod emple.emp_no%TYPE);
procedure ver_por_apellido(v_ape emple.apellido%TYPE);
function datos (v_cod emple.emp_no%TYPE)
return t_reg_emple;
end buscar_emple;

/* Cuerpo */

create or replace package body buscar_emple as


vg_emple t_reg_emple;
procedure ver_emple; /* procedimiento privado*/
procedure ver_por_numero (v_cod emple.emp_no%TYPE)
is
begin
select emp_no, apellido, salario, dept_no into vg_emple from emple where emp_no=v_cod;
ver_emple;
end ver_por_numero;
procedure ver_por_apellido (v_ape emple.apellido%TYPE)
is
begin
select emp_no,apellido,salario,dept_no into vg_emple from emple where apellido=v_apellido;
ver_emple;
end ver_por_apellido;
function datos (v_cod emple.emp_no%TYPE)
return t_reg_emple
is
begin
select emp_no,apellido,salario,dept_no into vg_emple from emple where emp_no=v_cod;
procedure ver_emple
is
begin
DBMS_OUTPUT.PUT_LINE(vg_emple.num_empleado || '*' || vg_emple.apellido || '*' || vg_emple.salario || '*'|| vg_emple.departamento);
end ver_emple;
end buscar_emple;

Como podéis ver este paquete nos permite buscar un empleado de tres formas distintas y
visualizar sus datos.

Utilización de los objetos definidos en los paquetes


Podemos utilizar los objetos definidos en los paquetes básicamente de dos maneras distintas:

Desde el mismo paquete: esto quiere decir que cualquier objeto puede ser utilizado
dentro del paquete por otro objeto declarado en el mismo. Para utilizar un objeto dentro
del paquete tan sólo tendríamos que llamarlo. La llamada sería algo así: v_emple
:=buscar_emple.datos(v_n_ape); (como veis no utilizamos el execute ya que nos
encontramos dentro del paquete).
Desde fuera del paquete: Podemos utilizar los objetos de un paquete siempre y cuando
haya sido declarado en la especificación del mismo. Para llamar a un objeto o
procedimiento desde fuera del paquete utilizaríamos la siguiente notación: execute
nombre_paquete.nombre_procedimiento(lista de parametros);

Declaración de cursores en paquetes


En los paquetes también podemos introducir cursores, para ello debemos declararlo en la
cabecera del paquete indicando su nombre, los parámetros y tipo devuelto. Para que lo veáis
más claro os dejo un ejemplo a continuación:

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 83 de 84
CREATE or REPLACE PACKAGE empleados AS
.....
CURSOR a RETURN empleado%ROWTYPE;
...
END empleados;

CREATE or REPLACE PACKAGE BODY empleados AS


....
CURSOR a RETURN empleado%ROWTYPE
SELECT * FROM empleado WHERE salario < 10000;
....
END empleados;

Los paquetes suministrados por Oracle son:

Standard : tiene la función to_char y abs


dbms_standard: tiene la función raise_aplication_error
dbms_output: con la función put_line
dbms_sql: que utiliza sql de forma dinámica.

NOTA: sql dinámico significa que el programa es capaz de ejecutar órdenes de definición y
manipulación sobre objetos que sólo se conocen al ejecutar el paquete. Un ejemplo de la
utilización de dbms_sql es el siguiente:

BEGIN
......
id_cursor := DBMS_SQL.OPEN_CURSOR;
DMBS_SQL.PARSE(id_cursor, instrucción,DMBS_SQL.V3);
v_dum :=DMBS_SQL.EXECUTE(id_cursor);
DMBS_SQL.CLOSE_CURSOR(id_cursor);
......

Lo que hacemos es abrir el cursor y nos devuelve el id del mismo para poder trabajar con él.
Después tenemos el DMBS_SQL.PARSE que analiza la instrucción que se va a ejecutar. Ya
en la siguiente linea ejecutamos la sentencia y por último cerramos el cursor.

No os preocupéis si no habéis terminado de entenderlo ya que dedicaremos un articulo


completo a la utilización de DBSM_SQL.

Este artículo es obra de Sara Alvarez


Fue publicado / actualizado en 29/03/2010
Disponible online en https://desarrolloweb.com/articulos/paquetes-oracle.html

http://desarrolloweb.com/manuales/tutorial-oracle.html Página 84 de 84

También podría gustarte