Sunteți pe pagina 1din 72

Tutorial de Oracle

En este tutorial aprenderás a gestionar una base de datos con el sistema


gestor Oracle.
Contenido
Tutorial de Oracle ......................................................................................................................................................... 1
Qué es Oracle ................................................................................................................................................................ 5
SQL con Oracle ............................................................................................................................................................. 6
Introducción: ............................................................................................................................................................... 6
Algunas caracteristicas:............................................................................................................................................... 6
Instalar Oracle Database 10g Express ....................................................................................................................... 9
Gestión de seguridad en Oracle I ............................................................................................................................. 11
Seguridad del sistema................................................................................................................................................ 11
Gestión de seguridad en Oracle II ............................................................................................................................ 14
Roles de usuario ........................................................................................................................................................ 15
Usuarios en Oracle ..................................................................................................................................................... 16
Claves primarias con SQL con Oracle...................................................................................................................... 17
Definición de claves para tablas y restricciones ..................................................................................................... 19
Supresión y modificación de tablas con SQL.......................................................................................................... 22
Manipulación de datos con SQL............................................................................................................................... 24
SQL con Oracle. Operadores..................................................................................................................................... 25
Funciones SQL ............................................................................................................................................................ 26
Subconsultas SQL....................................................................................................................................................... 28
Agrupación y combinación de elementos con SQL................................................................................................ 29
Optimizar consultas SQL........................................................................................................................................... 30
Gestión de vistas en SQL ........................................................................................................................................... 33
Introducción al lenguaje PL/SQL ............................................................................................................................ 34
Bloques ..................................................................................................................................................................... 35
Características de PL/SQL primera parte ............................................................................................................... 36
Definición de datos compatibles con SQL ................................................................................................................ 36
Estructuras de control................................................................................................................................................ 37
Cursores implicitos ................................................................................................................................................... 38
Características de PL/SQL segunda parte .............................................................................................................. 39
Gestión de excepciones ............................................................................................................................................. 39
Estructura modular .................................................................................................................................................... 39
Bloques anónimos y procedimientos PL/SQL ....................................................................................................... 41
Bloques anónimos PL/SQL ....................................................................................................................................... 41
Procedimientos y funciones PL/SQL ........................................................................................................................ 43
Fundamentos del lenguaje PL/SQL ......................................................................................................................... 44
Tipos de datos ........................................................................................................................................................... 44
Identificadores........................................................................................................................................................... 45
Variables ................................................................................................................................................................... 45
Constantes ................................................................................................................................................................. 46
Operadores ................................................................................................................................................................ 46
Funciones predefinidas ............................................................................................................................................. 47
Etiquetas .................................................................................................................................................................... 47
Subprogramas PL/SQL.............................................................................................................................................. 47
Procedimientos .......................................................................................................................................................... 47
Funciones .................................................................................................................................................................. 48
Parámetros................................................................................................................................................................. 48
Creación, modificación y borrado de subprogramas ................................................................................................. 50
Cursores en PL/SQL primera parte ......................................................................................................................... 50
Cursores explícitos .................................................................................................................................................... 50
Atributos del cursor ................................................................................................................................................... 52
Variables de acoplamientos en el manejo de cursores .............................................................................................. 52
Cursores PL/SQL segunda parte .............................................................................................................................. 53
Variables de acoplamiento ........................................................................................................................................ 53
Cursor FOR …. LOOP .............................................................................................................................................. 54
Cursores con parámetros ........................................................................................................................................... 54
Cursores PL/SQL tercera parte ................................................................................................................................ 55
Atributos con Cursores implícitos............................................................................................................................. 55
Uso de cursores para actualizar filas ......................................................................................................................... 56
Excepciones en Oracle y PL/SQL ............................................................................................................................. 58
Qué son las excepciones en Oracle ........................................................................................................................... 58
Excepciones predefinidas .......................................................................................................................................... 58
Excepciones definidas por el usuario ........................................................................................................................ 59
Otras excepciones ..................................................................................................................................................... 60
Utilización de RAISE_APPLICATION_ERROR .................................................................................................... 60
Control de transacciones ........................................................................................................................................... 60
Comandos utilizados para el control de transacciones .............................................................................................. 61
Triggers a tablas en PL/SQL ..................................................................................................................................... 63
Trigger a tablas.......................................................................................................................................................... 63
Elementos de un trigger ............................................................................................................................................ 64
Orden de ejecución de los trigger.............................................................................................................................. 64
Triggers de sustitución y de sistema ........................................................................................................................ 65
Disparadores de sustitución ...................................................................................................................................... 65
Disparadores de sistema ............................................................................................................................................ 66
Paquetes en Oracle ..................................................................................................................................................... 68
Utilización de los objetos definidos en los paquetes ................................................................................................. 70
Declaración de cursores en paquetes......................................................................................................................... 71
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.
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.

Referencia: 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, 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.

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.
 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]…]};

Vamos a explicar cómo 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 más 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 '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.

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á será 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 página de inicio de nuestra base de datos, la cual accedemos
mediante el menu inico->programas->Base de datos Oracle 10g Express Edition->página de
inicio de la base de datos, para ver la forma visual de hacer todas estas cosas.

Cuando abramos la página de inicio 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
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 página inicial de tu base de datos.

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.

El número de minutos que una sesión puede permanecer sin que sea utilizada de
IDLE_TIME 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.


La cantidad de espacio privado que una sesión puede reservar en la zona de SQL
PRIVATE_SGA compartido de la SGA.

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

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;

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.
privilegios sobre objetos: estos privilegios nos permiten realizar cambios en los datos de los objetos de
otros usuarios

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

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;

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.

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:

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])
{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];

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

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:

 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:
Manipulación de datos con SQL
tilizando 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];

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;

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

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.

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

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

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.

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

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
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.
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:
o Con filas de una sola tabla.
o Sin utilizar la cláusula GROUP BY ni DISTINCT.
o 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…

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

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

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;

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);
En el siguiente capitulo revisaremos todo lo que hemos visto en la introducción del PL/SQL, pero
de una forma mas exhaustiva.

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

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.

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


Operadores
Asignación :=

AND
OR
Lógicos NOT

Concatenación ||

Is null
=
!=
<>
<
Comparación
>
<=
>=
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)

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.

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

Nos permite pasar valores a un subprograma. Dentro del subprograma, el parámetro actuá como
IN una constante. Puede ser una variable, constante, literal o expresión.

Permite devolver valores al bloque que llamó al subprograma. Dentro del subprograma, el
OUT parámetro actúa como una variable no inicializada. Solo puede ser una variable.

Permite pasar un valor inicial y devolver un valor actualizado. Dentro del subprograma, el
IN parámetro actuá como variable inicializada. Puede intervenir otras expresiones. El valor actual
OUT debe ser una variable.

El formato genérico es el siguiente:

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


[ { := | DEFAULT} <valor>]
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.

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

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íamoscomenzado
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


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

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.

{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;
Con este artículo damos por terminado todo lo referente a cursores y empezamos a tratar las
excepciones en el siguiente artículo.
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 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 ;
3. Tratar la excepción en el apartado EXCEPTION: WHEN THEN ;

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

Control de transacciones
 Por Sara Alvarez


 06 de noviembre de 2009
 0 Comentarios
 Oracle
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;
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.

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
: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;
En el siguiente articulo veremos los triggers de sustitución y los del sistema.

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

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,
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:

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 línea ejecutamos la sentencia y por último cerramos el cursor.

No os preocupéis si no habéis terminado de entenderlo ya que dedicaremos un artículo completo


a la utilización de DBSM_SQL.

S-ar putea să vă placă și