0% encontró este documento útil (0 votos)
56 vistas

Documento ORACLE

Oracle es un sistema de gestión de base de datos relacional desarrollado por Oracle Corporation. Se considera uno de los sistemas de bases de datos más completos debido a su soporte de transacciones, estabilidad, escalabilidad y soporte multiplataforma. Oracle ha ido evolucionando a través de las versiones para agregar nuevas características como el soporte de objetos, almacenamiento de contenido multimedia, y capacidades para redes y la web.

Cargado por

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

Documento ORACLE

Oracle es un sistema de gestión de base de datos relacional desarrollado por Oracle Corporation. Se considera uno de los sistemas de bases de datos más completos debido a su soporte de transacciones, estabilidad, escalabilidad y soporte multiplataforma. Oracle ha ido evolucionando a través de las versiones para agregar nuevas características como el soporte de objetos, almacenamiento de contenido multimedia, y capacidades para redes y la web.

Cargado por

hrllanoj
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 62

ORACLE

Manizales
2012
Oracle

Oracle es un sistema de gestión de base de datos relacional (o RDBMS por el


acrónimo en inglés de Relational Data Base Management System),
desarrollado por Oracle Corporation.

Se considera a Oracle como uno de los sistemas de bases de datos más


completos, destacando:
• Soporte de transacciones,
• estabilidad,
• escalabilidad y
• Soporte multiplataforma.

Los ingenieros de Sillicon Valley, Larry Ellison, Bob Miner y Ed Oates fundan en
1977 una empresa de consultoría llamada Software DevelopmentLaboratories
(SDL) y tiempo después obtienen un contrato con la CIA para diseñar un
sistema especial de bases de datos con código clave "Oracle" 3 . Ellison y Miner
habían leído un artículo en la revista IBM Journal of Research and
Development donde se describía una versión preliminar del lenguaje SQL,
basado en el artículo de E. F. Codd donde propone el modelo relacional: "A
RelationalModel of Data forLargeShared Data Banks".

En 1978 y buscando la coherencia con sus objetivos empresariales, SDL


cambia de nombre a Relational Software Incorporated (RSI). La compañía
busca tener un producto que fuese compatible con el SQL de IBM, y además
enfocarse en un mercado de las minicomputadoras, abarcando así un
segmento que en ese momento IBM no le interesaba.

En 1982 RSI cambia su nombre a Oracle SystemsCorporation, y poco después


se acorta a su definitivo Oracle Corporation, el siguiente año empieza a
comercializar Oracle V3, agregando el manejo de transacciones a través de las
instrucciones COMMIT y ROLLBACK. De hecho, el producto es recodificado en
C lo que permite expandir las plataformas de ejecución para incluir los entornos
Unix, cuando hasta aquí era solo sobre Digital VAX/VMS.

En 1984, Oracle V4 soporta consistencia de lectura y en 1985 Oracle V5


empieza a soportar el modelo Client/Server para unirse al auge de la aparición
de las redes. Además se soporta la ejecución de queries distribuidos.

1989 trajo la aparición del ERP de Oracle, conocido como Oracle Financials,
junto a la versión 6 del motor, que agrega un lenguaje procedural (Pl/Sql),
bloqueo a nivel de fila y las posibilidades de hacer respaldos sin la necesidad
de terminar los procesos involucrado.
Para convertirse en una base de datos completa, en 1992 aparece Oracle V7h,
donde la h viene de datawareHouse, aunque lo más significativo es el soporte
de la integridad referencial, el almacenamiento y ejecución de programas
escritos en Pl/Sql dentro del motor y la definición de triggers de base de datos.

Siendo Internet ya una realidad y con los nuevos paradigmas de programación


empezando a aparecer para intentar desplazar a los paradigmas imperativos,
en 1997 Oracle V8 comienza a soportar desarrollos orientados a objetos y el
almacenamiento y ejecución de contenido multimedia y en 1999 sale a la luz
Oracle 8i para estar a tono con los requerimientos de la Internet, de donde se
derive la i del nombre. Además, el motor incorpora una Java Virtual
Machine interna para soportar el almacenamiento y ejecución de código Java
dentro del motor.

El nuevo siglo comienza y en 2001 Oracle 9i trae más de 400 nuevas


características incluyendo la habilidad de manipular documentos XML,
opciones de alta disponibilidad, bases de datos en Clúster. Un avance
importante se hace sobre la definición de Bases de Datos Virtuales (VPD),
autenticación vía LDAP y en el auto administración de la base de datos.

En 2003 Oracle Corporation lanza Oracle 10g, donde la "g" viene de "Grid",
incorporando el manejo y administración de bases de datos Grid, un conjunto
de bases de datos cuya administración de espacio, recursos y servicios pueden
administrarse como si fueran una sola.

En el 2007, Oracle anunció la última versión de su Base de Datos en la ciudad


de Nueva York, EU. La denomina Oracle 11g, el siguiente paso en la historia de
la innovación tecnológica de Oracle Corporation.

Primero el Oracle 10g Express


1. Es una versión reducida de la base de datos Oracle 10g, y por lo tanto
está limitada en su funcionalidad, con la diferencia que la versión Ex-
press es gratuita y de libre uso (no se requiere una licencia comercial
para su uso). Algunas de las limitaciones son:
2. Utiliza una sola CPU aunque el ordenador disponga de más de una.
3. Direcciona hasta 1GB en RAM.
4. Almacena hasta 4GB. de datos de usuario.
5. Disponible en ordenadores de 32 bits.
6. Una sola instancia por servidor.

Oracle XE puede usarse con las siguientes herramientas de desarrollo:

1. Oracle Application Express (formalmente HTMLDB).


2. Java.
3. C/C++
4. PHP.
5. ODBC.
6. .NET
Oracle XE puede emplearse como Base de Datos de producción en pequeños
negocios(Small Bussiness) tanto en intranets e internet, actualmente hay un
parche disponible para actualizar Oracle Database XE a la versión 10.3. El
soporte se da medante un foro del mismo Oracle Corp.

Una de las ventajas de usar Oracle XE es su probado rendimiento y


disponibilidad, como tambien su seguridad.

Oracle XE viene integrado con Oracle Application Express , una herramienta de


Rápido desarrollo que permite crear aplicaciones web robustas sin necesidad
de conocimientos avanzados programación debido a su entorno declarativo, sin
embargo, quienes tengan habilidades en PL/SQL y en Ajax, pueden potenciar
las aplicaciones.

Con todas estas características Oracle XE es la base de datos ideal para


inicarse en el mundo de Oracle y para desarrollar y distribuir aplicaciones
livianas de escritorio y en la Web.

Administración básica y seguridad en Oracle

Concepto de usuario, privilegio y rol:


A la hora de establecer una conexión con un servidor Oracle, es necesario que
utilicemos un modo de acceso, el cual describa de qué permisos dispondremos
durante nuestra conexión. Estos permisos se definen sobre un nombre de
usuario.

Un usuario no es más que un conjunto de permisos que se aplican a una


conexión de base de datos. Así mismo, el usuario también tiene otras
funciones:

· Ser el propietario de ciertos objetos.


· Definición del tablespace por defecto para los objetos de un usuario.
· Copias de seguridad.
· Cuotas de almacenamiento.

Un privilegio no es más que un permiso dado a un usuario para que realice


cierta operación. Estas operaciones pueden ser de dos tipos:

· Operación de sistema: necesita el permiso de sistema correspondiente.


· Operación sobre objeto: necesita el permiso sobre el objeto en cuestión.

Y por último un rol de base de datos no es más que una agrupación de


permisos de sistema y de objeto.

Creación de usuarios:
La creación de usuarios se hace a través de la sentencia SQL CREATE USER
Su sintaxis básica es:

CREATE USER nombre_usuario


IDENTIFIED [ BY clave | EXTERNALLY ]
{ DEFAULT TABLESPACE tablespace_por_defecto }
{ TEMPORARY TABLESPACE tablespace_temporal }
{ DEFAULT ROLE [ roles, ALL [EXCEPT roles], NONE ] };

La cláusula IDENTIFIED BY permite indicar que tipo de autentificación se


utilizará:

· Interna de Oracle: una clave para cada usuario de base de datos.


· Interna del SO: utilizando la seguridad del SO.

La cláusula DEFAULT TABLESPACE será el tablespace por defecto en la


creación de objetos del usuario que estamos creando. Si se omite se utilizará el
tablespace SYSTEM.

La cláusula TEMPORARY TABLESPACE indica el tablespace que se utilizará


para la creación de objetos temporales en la operación interna de Oracle. Si se
omite se utilizará el tablespace SYSTEM.

La cláusula DEFAULT ROLE permite asignar roles de permisos durante la


creación del usuario.

Ejemplos:
CREATE USER ADMINISTRADOR
IDENTIFIED BY MANAGER
DEFAULT TABLESPACE SYSTEM
TEMPORARY TABLESPACE TEMPORARY_DATA
DEFAULT ROLE DBA;
CREATE USER PEPOTE
IDENTIFIED BY TORO;
CREATE USER JUANCITO
IDENTIFIED BY PEREZ
DEFAULT TABLESPACE DATOS_CONTABILIDAD
TEMPORARY TABLESPACE TEMPORARY_DATA;

Creación de roles:
La creación de roles permite asignar un grupo de permisos a un usuario, y
poder modificar este grupo de permisos sin tener que ir modificando todos los
usuarios.
Si asignamos un rol con 10 permisos a 300 usuarios, y posteriormente
añadimos un permiso nuevo al rol, no será necesario ir añadiendo este nuevo
permiso a los 300 usuarios, ya que el rol se encarga automáticamente de
propagarlo.

La sintaxis básica es:


CREATE ROLE nombre_rol
{ [NOT IDENTIFIED | IDENTIFIED [BY clave | EXTERNALLY]] };
Una vez que el rol ha sido creado será necesario añadirle permisos a través de
instrucción GRANT.

Inicialmente Oracle tiene predefinidos los siguiente roles (entre otros):

Rol predefinido Descripción


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 Todos los permisos para un administrador de base de datos (DBA)
EXP_FULL_DATABASE Permisos para poder exportar toda la base de datos.
IMP_FULL_DATABASE Permisos para poder importar toda la base de datos.
Podemos decir que un usuarios normal, debe tener al menos los permisos de
CONNECT (para conectarse) y de
RESOURCE (para poder crear objetos).

Ejemplos:
CREATE ROL CONTROL_TOTAL;
CREATE ROL BASICO;
CREATE ROL ACCESO_CONTABILIDAD;

Privilegios de sistema
Ya hemos dicho que los privilegios de sistema son permisos para realizar
ciertas operaciones en la base de datos.

El modo de asignar un privilegio es a través de la instrucción GRANT y el modo


de cancelar un privilegio es a través de la instrucción REVOKE.

La sintaxis básica de ambas instrucciones es:


Instrucción GRANT
GRANT [privilegios_de_sistema | roles] TO [usuarios | roles |PUBLIC]
{ WITH ADMIN OPTION };

Es posible dar más de un privilegio de sistema o rol, separándolos por comas.

También es posible asignarle uno (o varios) privilegios a varios usuarios,


separándolos por comas.
Si se le asigna el privilegio a un rol, se asignará a todos los usuarios que
tengan ese rol.

Si se asigna el privilegio a PUBLIC, se asignará a todos los usuarios actuales y


futuros de la base de datos.

La cláusula WITH ADMIN OPTION permite que el privilegio/rol que hemos


concedido, pueda ser concedido a otros usuarios por el usuario al que estamos
asignando.

La lista de los privilegios de sistema existentes se puede encontrar en el


Oracle8 SQL Reference en la sección GRANT (System privileges and roles).

Ejemplos:
GRANT DBA TO ADMINISTRADOR;
GRANT CREATE USER TO PEPOTE WITH ADMIN OPTION;
GRANT DROP USER TO JUANCITO;
GRANT CONNECT, RESOURCE TO PEPOTE, JUANCITO;
GRANT CONNECT, RESOURCE, DBA, EXP_FULL_DATABASE,
IMP_FULL_DATABASE
TO CONTROL_TOTAL;
GRANT CONTROL_TOTAL TO ADMINISTRADOR;

Instrucción REVOKE
REVOKE [privilegios_de_sistema | roles] FROM [usuarios | roles |PUBLIC];

Es posible eliminar más de un privilegio de sistema o rol, separándolos por


comas. También es posible eliminar uno (o varios) privilegios a varios usuarios,
separándolos por comas.
Si se le elimina el privilegio de un rol, se eliminará de todos los usuarios que
tengan ese rol.

Si se elimina el privilegio de PUBLIC, se eliminará de todos los usuarios


actuales y futuros de la base de datos.

La lista de los privilegios de sistema existentes se puede encontrar en el


Oracle8 SQL Reference en la sección GRANT (System privileges and roles).

Como es lógico, sólo se podrá eliminar un privilegio/rol, si previamente ha sido


concedido a través de la instrucción GRANT.

Ejemplos:
REVOKE DBA FROM ADMINISTRADOR;
REVOKE CREATE USER FROM PEPOTE;
REVOKE DROP USER FROM JUANCITO;
RECOKE CONNECT, RESOURCE FROM PEPOTE, JUANCITO;
REVOKE CONNECT, RESOURCE, DBA, EXP_FULL_DATABASE,
IMP_FULL_DATABASE
FROM CONTROL_TOTAL;
REVOKE CONTROL_TOTAL FROM ADMINISTRADOR;

Privilegios sobre objetos


Los privilegios sobre objetos permiten que cierto objeto (creado por un usuario)
pueda ser accedido por otros usuarios.

El nivel de acceso depende del permiso que le demos: podemos darle permiso
de SELECT, de UPDATE, de DELETE, de INSERT o de todos ellos.

La sintaxis básica es:


GRANT [ALL {PRIVILEGES} | SELECT | INSERT | UPDATE | DELETE]
ON objeto
TO [usuario | rol | PUBLIC]
{WITH ADMIN OPTION};

Al igual que con los permisos de sistema, es posible asignar un permiso de


objeto sobre uno o varios (separados por comas) usuario y/o roles. Si se asigna
a PUBLIC será accesible en toda la base de datos.

Si se incluye la cláusula WITH ADMIN OPTION, este permiso podrá ser


concedido por el usuario al que se le ha asignado.

Ejemplos:
GRANT ALL ON FACTURA TO CONTROL_TOTAL;
GRANT SELECT, UPDATE ON ALUMNO TO PEPOTE, JUANCITO
WITH ADMIN OPTION;
GRANT SELECT ON PROFESOR TO PUBLIC;
GRANT SELECT ON APUNTE TO ACCESO_CONTABILIDAD;

El modo de eliminar permisos de objeto es con la instrucción REVOKE:


REVOKE [ALL {PRIVILEGES} | SELECT | INSERT | UPDATE | DELETE]
ON objeto FROM [usuario | rol | PUBLIC]
{WITH ADMIN OPTION};

Al igual que con los permisos de sistema, es posible asignar un permiso de


objeto sobre uno o varios (separados por comas) usuario y/o roles. Si se asigna
a PUBLIC será accesible en toda la base de datos.

Si se incluye la cláusula WITH ADMIN OPTION, este permiso podrá ser


concedido por el usuario al que se le ha asignado.

Ejemplos:
GRANT ALL ON FACTURA TO CONTROL_TOTAL;
GRANT SELECT, UPDATE ON ALUMNO TO PEPOTE, JUANCITO
WITH ADMIN OPTION;
GRANT SELECT ON PROFESOR TO PUBLIC;
GRANT SELECT ON APUNTE TO ACCESO_CONTABILIDAD;

Eliminación de usuarios:
La eliminación de usuarios se hace a través de la instrucción DROP USER.
Su sintaxis es:
DROP USER usuario {CASCADE};
La cláusula CASCADE permite borrar el usuario y todos los objetos que posea.

Estructura de una BD Oracle.


Una BD Oracle tiene una estructura física y una estructura lógica que se
mantienen separadamente.

• La estructura física se corresponde a los ficheros del sistema operativo: de


datos (datafiles), de redo log y de control (controlfiles).

• La estructura lógica está formada por los tablespace y los objetos de un


esquema de BD (tablas, vistas, índices,...).

Estructura lógica.
Una BD se divide en unidades de almacenamiento lógicas: Tablespaces.
Contienen distintos objetos relacionados (p.ej. todas las tablas de una
aplicación).
Cada BD estará formada por uno o mas tablespaces (al menos existe el
tablespace SYSTEM Æ catálogo del sistema).

Cada tablespace se corresponde con uno o más ficheros de datos.

Objetos: tablas, vistas, índices asociados a una tabla, clusters.

Oracle define esquema como la colección de objetos o estructuras lógicas


que corresponden directamente a los datos almacenados, y crea un nuevo
esquema por cada usuario que crea objetos en la base de datos.

No hay ninguna relación directa entre tablespace y esquema, objetos del


mismo esquema pueden estar en diferentes tablespaces y un mismo
tablespace puede almacenar distintos esquemas. El control del uso del espacio
del disco se obtiene mediante las estructuras lógicas de almacenamiento:
bloque de datos, extensión y segmento.

El nivel más pequeño de granularidad es el del bloque de datos: número


específico de bytes contiguos de espacio físico en el disco. (tamaño mínimo de
2K, el bloque físico del disco y que depende el sistema operativo no tiene
por que coincidir con éste).

El siguiente nivel es el de extensión, que es unnúmero específico de bloques


de datos contiguos en el disco.

Por último el segmento es un conjunto de extensiones utilizadas para


almacenar alguna estructura lógica.

Tendremos segmentos de datos para tablas o clusters, segmentos de índices


para índices, segmentos de rollback para poder deshacer / rehacer cambios
por
transacciones y segmentos temporales.

Hay varios tipos de sentencias en las que Oracle se ve en la obligación de


utilizar los segmentos temporales: ordenaciones.

SELECT ...ORDER BY...


CREATE INDEX.
SELECT ... GROUP BY...
SELECT ... UNION ...
SELECT DISTINCT ...
SELECT … INSERSEC ...
SELECT ... MINUS ...

Oracle va incrementando el espacio para los segmentos mediante extensiones.


Cuando una extensión está llena y necesita más espacio el sistema busca otra
extensión, que podrá estar o no estar contigua a la anterior en el disco
(dependerá simplemente del estado de éste). Estructura física

Una B.D. tiene uno o más ficheros de datos. Estos ficheros son de tamaño fijo y
se establecen en el momento en que se crea la base de datos o en el momento
en el que se crean tablespaces.

Los datos del fichero de datos son leídos cuando se necesitan y situados en
una caché de memoria compartida (llamada SGA, System Global Area:
db_block_buffers; recomendable tamaño SGA = 50% de la memoria principal)
para que el próximo acceso a los mismos sea más rápido.

Las modificaciones en los datos se guardan ante una petición o cuando los
datos son eliminados de la SGA por falta de memoria libre para atender más
peticiones. El conjunto de ficheros redo log sirven para registrar todos los
cambios (insert, update, delete, create, alter o drop) sobre la BD y poder
recuperarla ante un error.
Los ficheros de control almacenan información de la estructura física de la BD.
Los distintos elementos que forman parte del entorno de memoria de Oracle :

SGA: System Global Area o Shared Global Area.


Zona principal de la memoria de Oracle. Está dividida en varias
subareas desempeñando cada una de estas una tarea totalmente distinta: la
Shared Pool, la Database Buffer Cache (parámetro DB_BLOCK_BUFFERS) y
el Redo Log Buffer. Shared pool:

Library Cache: se encuentra a su vez dividida en varios apartados: zona


compartida de sql, zona privada de sql, procedimientos y paquetes pl/sql y, por
último, la zona de control y bloqueos propios de la library cache.

Sharedsqlarea o área de sql compartido, se guardan los árboles sintácticos de


las sentencias analizadas así como los planes de ejecución elegidos para cada
una.

Privatesqlarea o zona privada de sql: por cada sesión diferente que hay en la
base de datos se crea una zona de sql privado. Se mantiene información de las
sentencias que se están tratando en ese momento.

Procedimientos y Paquetes PL/SQL: existe un área diferenciada para el


tratamiento de los procedimientos, funciones y paquetes pl/sql. Se tratan en
esta zona igual que si fueran sentencias sql en la zona de sql compartido.

Dictionary cache: mantiene datos de sus propias tablas y vistas ya que accede
constantemente a ellas al ejecutar cualquier sentencia.

PGA: Program Global Area.


Destinada a guardar información de los procesos de usuario y procesos de
background que corren en una instancia de la base de datos y que a través de
distintos procesos intercambian la información con la SGA.

Sort Areas (parámetro SORT_AREA_SIZE.)


Son las zonas de memoria que Oracle reserva para realizar ordenaciones y
que resultan mucho más rápidas si se realizan en la memoria. Por supuesto, no
todas las ordenaciones caben en memoria y en esos casos debe utilizar
también el disco y, si hemos configurado bien el sistema, se realizarán el los
tablespaces que hemos definido como temporales. Elementos de Diseño Físico
en ORACLE Tablespace:

Como ya se ha comentado la BD se divide en varios tablespaces, y para cada


uno de ellos se asocian uno o varios ficheros. La capacidad total del tablespace
coincidirá con la suma de los tamaños de los ficheros.
Es pues una decisión de diseño especificar cuantos tablespace son necesarios
y cual debe de ser el tamaño de los ficheros asociados.

Ejemplo:
CREATE TABLESPACE TS_DATOS
DATAFILE ‘/disco1/fichero1’ SIZE 100M,
DATAFILE ‘/disco2/fichero2’ SIZE 250M;

En este caso se crea un tablespace TS_DATOS asociado a dos ficheros con


una
capacidad total de 350M.

Tablas y extensiones de una tabla:


En el momento en el que se creen las tablas y en la propia definición en SQL
se tendrá que indicar en qué tablespace se guardarán los datos. Las tablas no
se pueden asignar a los ficheros.

Ejemplo: La tabla alumno se asigna a TS_DATOS pero puede que los datos se
encuentren repartidos entre los dos ficheros. CREATE TABLE Alumnos (...)
TABLESPACE TS_DATOS;
Una parte importante del diseño será decidir el tamaño de las extensiones de
cada una de las tablas que vamos a crear. Evidentemente lo mas interesante
será tener las tuplas de una relación almacenadas en espacios
consecutivos en el disco, para aprovechar las ventajas de la recuperación de
bloques consecutivos.

De esta manera será interesante tener pocas extensiones pues como se ha


dicho una extensión es un conjunto de bloques consecutivos.

En la sentencia SQL de definición de las tablas se han de incluir los siguientes


parámetros de almacenamiento (cláusula STORAGE):

• INITIAL: denota el tamaño de la extensión inicial.


• NEXT: indica el tamaño de las extensiones siguientes.
• MINEXTENTS: indica el numero mínimo de extensiones.
• MAXEXTENTS: indica el numero máximo de extensiones.
• PCTINCREASE: es un factor de crecimiento de una extensión a la siguiente.
Ejemplo:

CREATE TABLE Alumnos (...) TABLESPACE TS_DATOS STORAGE ( INITIAL


20K NEXT 30K MINEXTENTS 1 MAXEXTENTS 10 PCTINCREASE 0);

En este ejemplo la tabla alumno se almacenara en una extensión inicial de


20K, y las extensiones sucesivas serán de 30K, hasta un máximo de 10
extensiones.
Encadenamiento de tuplas:
Las tuplas se almacenan en Oracle como registros de tamaño variable, es
decir, no se reserva espacio fijo para cada tupla. De esta manera y sobre todo
cuando se producen modificaciones sobre atributos que amplían su tamaño,
puede ocurrir que una tupla no quepa en un bloque, y haya que repartirla entre
dos bloques (row chaining, filas encadenadas). En este caso el recuperar esta
fila supondrá realizar
muchos más accesos al disco.

Para reducir la posibilidad de encadenamientos por modificaciones de filas en


el bloque es interesante dejar un porcentaje libre en cada bloque. El parámetro
PCTFREE en la sentencia SQL de la definición de la tabla indica este
porcentaje.

De la misma manera y para que varias inserciones se puedan hacer sobre un


mismo bloque y así evitar muchos accesos al disco, se puede establecer un
espacio mínimo para poder insertar filas en ese bloque, este porcentaje se
establece mediante el parámetro PCTUSED.

Ejemplo:
CREATE TABLE Alumnos (...) TABLESPACE TS_DATOS
PCTFREE 20 PCTUSED 40
STORAGE (INITIAL 20K NEXT 30K MINEXTENTS 1 MAXEXTENTS 10
PCTINCREASE 0);

En este ejemplo:
• Se reservará el 20% de cada bloque para evitar encadenamientos.
• Un bloque que se ha llenado previamente, no se volverá a utilizar para
inserciones hasta que ese porcentaje de utilización sea inferior al 40%.

Recomendaciones:
PCTFREE: Si la fila no va a sufrir modificaciones Æ valor entre 5 y 10; pero si
las filas pueden sufrir muchas variaciones en cuanto a tamaño Æ 20-40.
PCTUSED: Un valor entre 80 y 40; si no se van a producir muchas
modificaciones 80 y en caso contrario 40.

La suma entre este valor y el anterior no debe de superar a 100. Creación de


índices:

Los índices son estructuras sobre un conjunto de atributos de una tabla y que
permiten establecer una ordenación lógica de las tuplas de una relación por el
valor de los atributos que forman la clave del índice.

Oracle permite la creación de índices B* (similares a los B+). Como los índices
necesitan de espacio en el disco para almacenar sus valores, en la definición
de éstos se utilizarán los parámetros que acabamos de indicar en la creación
de tablas.

Ventajas de la estructura de B-tree


• Todos los nodos hoja están a la misma profundidad. La recuperación de
cualquier registro lleva aproximadamente el mismo tiempo.
• Permanecen automáticamente balanceados.
• Todos los bloques del árbol están llenos de media en ¾.
• Excelente desempeño para una amplia variedad de consultas, desde
emparejamiento exacto (exact match) a búsquedas por rango de valores.
• Inserts, updates, y deletes son eficientes, manteniéndose el órden de clave.

Ejemplo:
CREATE TABLESPACE TS_INDICES DATAFILE ‘/disco1/indices’ SIZE 100M;
CREATE INDEX nom_ind ON Alumnos ( ...atributos....)
TABLESPACE TS_INDICES PCTFREE 10
STORAGE ( INITIAL 10K NEXT 10K MINEXTENTS 1 MAXEXTENTS 10
PCTINCREASE 0);

Conviene por razones de eficiencia separar las tablas de los índices en


distintos tablespace que estén ubicados en discos diferentes para poder
realizar en paralelo peticiones de E/S sobre los discos.

Clusters:
Cuando dos tablas tienen atributos mediante los cuales es usual realizar
concatenaciones, puede resultar más eficiente guardar las tuplas que se
concatenan de ambas relaciones en el mismo bloque, el cluster es un método
que nos permite esto.

El utilizar clusters solamente afecta a la organización física de los datos y no a


la estructura lógica. Y en este caso la ventaja es doble pues se aceleran las
concatenaciones (joins) y se disminuye espacio de utilización en el disco pues
los atributos que se concatenan solamente se guardan una vez.

Ejemplo:
CREATE CLUSTER CL_1 ( clave number(4) ) SIZE 512
TABLESPACE TS_DATOS
PCTFREE 20
STORAGE ( INITIAL 20K NEXT 30K MINEXTENTS 1 MAXEXTENTS 10
PCTINCREASE 0);
CREATE TABLE Alumno( … ) CLUSTER CL_1( a1 );

Como vemos los parámetros de almacenamiento se asocian al cluster y no a


las tablas. El parámetro SIZE nos indica el tamaño máximo que ocuparán las
tuplas que se concatenan y este debe de ser una estimación.
Dispersión:
Existe una variación en el uso de los clusters y es el uso de dispersión. En este
caso las filas no se almacenaran por el valor de la clave del cluster sino por el
resultado de aplicar una función de dispersión a el valor de la clave del cluster.
La dispersión que implementa Oracle es estática y es necesario conocer
cuándo se crea el rango de valores de la función de dispersión, en este
momento se reserva espacio para todos los bloques del cluster y los conflictos
se resuelven mediante cubos de desborde.

Ejemplo:
CREATE CLUSTER CL_1 ( clavenumber(4) )
SIZE 512
HASH IS clave HASKEY 300
TABLESPACE TS_DATOS
PCTFREE 20
STORAGE ( INITIAL 20K NEXT 30K MINEXTENTS 1 MAXEXTENTS 10
PCTINCREASE 0);
En este ejemplo la función de dispersión devuelve valores entre 0 y 299.

Concepto de relación:
Se denomina relación a todo aquellos vínculos que establecen unas tablas con
otras, debidos a la aplicación de las formas normales.

En el ejemplo anterior, hemos creado relaciones entre unas tablas y otras


desde el momento en que se separan los datos en más de una tabla y se utiliza
el código como enlace entre unas y otras.

Una relación que hemos creado ha sido la que se establece entre la tabla
CLIENTE y la tabla PAIS. Ambas tablas están "intercomunicadas" por una de
sus columnas: CódPais para CLIENTE y Código para PAIS. Con esta relación
sabemos que todo campo Cód País de la tabla CLIENTE, tiene un registro
equivalente en la tabla PAIS.

Relación 1-1
La relación 1-1 se establece cuando un registro de la tabla A tiene un solo
registro relacionado en la tabla B.

Esta relación se podría establecer por ejemplo si creamos una tabla de Pagos
de facturas. Suponiendo que una factura se paga de una sola vez, podemos
definir la siguiente tabla para almacenar cuando se pagan las facturas:

PAGOS_FACTURA
Columna Tipo
(*) Referencia A(10)
Fecha pago F
Importe original N(12)
% Recargo por retraso N(3)
Importe final N(10)

Podemos ver que la clave de esta tabla sólo es la referencia de la factura. Esto
es el dato relevante que nos dice que la relación establecida entre una tabla y
otra es 1-1. En la tabla PAGOS_FACTURA sólo puede aparecer una vez cada
referencia. Y el la tabla FACTURA sólo puede aparecer una vez cada
referencia.

Desde el punto de vista conceptual, las relaciones 1-1 son necesarias y


convenientes, para que se cumpla la tercera forma normal y que en cada tabla
sólo aparezcan datos correspondientes a su nivel lógico.

Sin embargo, desde el punto de vista productivo y práctico, una relación 1-1 se
puede sustituir por más registros en la tabla principal. Ya que un registro de A
solo puede tener un registro en B, entonces las columnas de B pueden entrar a
formas parte de A.

En un análisis más práctico que exhaustivo podríamos haber definido facturas


de la siguiente manera:

FACTURA
Columna Tipo
(*) Referencia A(10)
Descripción A(50)
Cód país N(3)
Cód. Cliente N(5)
Importe N(12)
Fecha pago F
%Recargo por retraso N(3)
Importe final N(10)

Relación 1-N
Una relación 1-N es más común que 1-1, ya que, tanto desde el punto de vista
conceptual, como desde el práctico, es necesario hacerlas.

Volviendo al caso de los pagos de las facturas, podemos permitir que una
factura se pague fraccionada, por ejemplo a 30, 60 y 90 días. Para este caso
necesitamos que una referencia aparezca más de una vez en la tabla de
PAGOS, por lo que la clave primaria debe ser cambiada.

Si la definición de la tabla para una relación 1-N hubiese sido la siguiente:


PAGOS_FRACCIONADOS_FACTURA
Columna Tipo
(*) Referencia A(10)
(*) Fecha pago F
Importe original N(12)
% Recargo por retraso N(3)
Importe final N(10)

Entonces una referencia puede aparecer N veces, una por fecha distinta
introducida. Así podemos pagar una factura en las siguientes fracciones.

PAGOS_FRACCIONADOS_FACTURA
Referencia Fecha Importe orig. % Recargo Importe final
RF1102 1/5/2000 100.000 0% 100.000
RF1102 10/6/2000 100.000 10% 110.000
RF1102 1/7/2000 100.000 0% 100.000

Si la clave se hubiese definido sólo como "Referencia", no podríamos haber


insertado más de una fecha para la misma referencia. Sin embargo al definirla
como "Referencia, Fecha", podemos introducir tantas parejas Referencia-
Fecha como queramos.

En nuestro ejemplo se ha pagado una factura fraccionada en tres pagos con un


mes de diferencia entre ellos.

Las relaciones 1-N también son llamadas normalmente maestro-detalle, donde


el maestro es la tabla A (el 1 en la relación) y el detalle es la tabla B (el N en la
relación).

En nuestro ejemplo FACTURA es el maestro y


PAGOS_FRACCIONADOS_FACTURA un detalle de FACTURA.

Como norma general (lógicamente tiene sus excepciones) podemos decir que
las columnas de la clave primaria de una tabla detalle tienen que ser las
mismas que su maestro, añadiendo una (o varias) columnas a la clave (que
marcan la diferencia entre el maestro y el detalle).

Esta norma se cumple para nuestro ejemplo.


Las relaciones 1-N pueden ser optativas u obligatorias en ambos sentidos. Es
decir, la tabla A puede estar obligada (o no) a tener registros relacionados en la
tabla B, La tabla B puede estar obligada (o no) a tener registros relacionados
en la tabla A.

Una relación típica maestro-detalle, es optativa en sentido A-B pero obligatoria


en sentido B-A. Significa que un maestro puede tener o no tener detalles, pero
el detalle tiene que tener maestro obligatoriamente.

El concepto de relación es muy común dentro de las bases de datos y está


presente continuamente. Es preciso que se maneje con soltura a la hora de
definir las claves primarias para cada una de las tablas.
Claves foráneas
Una vez establecidas las relaciones entre las tablas, debemos estar seguros de
que éstas se cumplen siempre. En nuestro ejemplo anterior debemos de
asegurarnos de que si hay un registro en
PAGOS_FRACCIONADOS_FACTURA, debe existir la correspondiente factura,
y que si ésta es borrada, se haga lo mismo con sus pagos.
Las bases de datos nos ofrecen esta posibilidad a través de las claves
foráneas, que no son más que un tipo de clave (como la primaria) que hace
referencia a otras tablas.

Así la tabla PAGOS_FRACCIONADOS_FACTURA debe definir una clave que


compruebe que siempre que se inserte un pago, exista la factura
correspondiente (en la tabla FACTURA).

Además la base de datos se encarga de que si queremos borrar una factura


(en la tabla FACTURA) no nos deje si existen pagos o bien borre todos los
pagos correspondientes.

Las claves foráneas deben crearse sobre las tablas "hijo", o las tablas B en
cada relación, normalmente en los detalles. En nuestro ejemplo de las tablas
FACTURA, CLIENTE y PAIS se deben aplicar las siguientes claves foráneas
(restricciones).

CLIENTE: Comprobar que no se puede dar de alta un cliente a un país que no


exista. Además no se podrá borrar un país siempre que existan clientes dados
a ese país.

Clave foránea en CLIENTE(cod_pais ) hace referencia sobre PAIS( codigo )


FACTURA: Comprobar que no se puede dar de alta una factura a un cliente
(país, cliente) que no exista.

También se comprobará que no se pueda borrar un cliente que tenga facturas.


Clave foránea en FACTURA(cod_pais,cod_cliente) hace referencia sobre
CLIENTE(cod_pais,cod_cliente) Se puede ver como la tabla PAIS no tiene
ninguna clave foránea, ya que es "padre" o tabla A en todas las relaciones
establecidas.

Como norma general, cada relación debe tener una clave foránea, y debe
crearse sobre la tabla B de la relación que representa.

Normas básicas de codificación


A la hora de definir una tabla hay que tener en cuenta ciertos aspectos en la
codificación:
Sólo deben ser numéricas aquellas columnas que sean suscepti-
bles de operaciones aritméticas. Es decir, un código de factura,
no debe ser numérico ya que nunca se van a sumar los códigos.
 A la hora de codificar columnas alfanuméricas, hay que tener en
cuenta el sistema de ordenación:
Dada la siguiente lista de valores (de distinto tipo de dato):

Alfanumérico Numérico

'50' 50
'41' 41
'21' 21
'1' 1
'5' 5
'20' 20
'100' 100
'13' 13
'10' 10
'2' 2

La lista ordenada será la siguiente:

Alfanumérico Numérico

'1' 1
'10' 2
'100' 5
'13' 10
'2' 13
'20' 20
'21' 21
'41' 41
'5' 50
'50' 100

El orden, como vemos, difiere mucho uno de otro. Sin embargo, dada la
siguiente lista de valores (de distinto tipo de dato):

Alfanumérico Numérico

'050' 50
'041' 41
'021' 21
'001' 1
'005' 5
'020' 20
'100' 100
'013' 13
'010' 10
'002' 2

La lista ordenada será la siguiente:

Alfanumérico Numérico

'001' 1
'002' 2
'005' 5
'010' 10
'013' 13
'020' 20
'021' 21
'041' 41
'050' 50
'100' 100

La diferencia está en que el método alfanumérico ordena por posiciones, no por


valores absolutos.
 Las descripciones deben ser lo suficientemente largas como para
almacenar el caso más desfavorable para la columna, aunque
tampoco se deben crear columnas demasiado largas.

Por ejemplo: para albergar nombre y apellidos nos valdrá un 2 nombres de 10


caracteres cada uno, más dos apellidos de 15 caracteres cada uno. Total 35
caracteres. Para darnos un margen de error podemos poner 40 caracteres.
Más de esta estimación será una longitud exagerada para el campo.

Codificación compuesta o "claves inteligentes"


En bases de datos antiguas había una práctica muy común que consistía en
utilizar una sola columna con varios significados. El significado de la columna
dependía de las posiciones de los dígitos.

Por ejemplo, se podría definir la siguiente regla para almacenar las referencias
de las facturas:

Dígitos 1-2 Día de emisión.


Dígitos 3-4 Mes de emisión.
Dígitos 5-8 Año de emisión.
Dígitos 9-14 Código de cliente.
Dígitos 14-20 Número de factura.
Así la referencia de la factura número 1, emitida a 23/8/1999, para el cliente
código 567 sería:
23081999000567000001

Esto no tiene ningún sentido, ya que queda mucho más claro separar cada
valor a su columna correspondiente, y si es necesario, definir todas las
columnas necesarias como clave.

Fecha Cliente Número


23/8/1999 567 1

El origen de esta práctica viene de la época de las bases de datos jerárquicas


en las que la clave sólo podía estar formada por un campo. Entonces era la
única manera de definir una clave compuesta.

Estándar de nomenclatura de objetos


Cuando un equipo de desarrollo da los primeros pasos en un proyecto
informático (de bases de datos o de cualquier otro tipo), lo primero que se debe
definir es qué estándar de nomenclatura de objetos se va a utilizar.

El objetivo principal de esta tarea es que el esquema sea consistente y


homogéneo, además de permitir una memorización más rápida de los objetos.
El estándar debe responder a las siguientes preguntas:

 ¿Los nombres de objetos van en mayúsculas o minúsculas?


 ¿Debo utilizar nombres lo más descriptivos posibles o sin embar-
go nombres muy cortos?
 ¿Puedo usar abreviaturas?
 ¿Los nombres deben ir en singular o en plural?

El estándar debe ser un documento que tengan presente en todo momento el


equipo de desarrollo, y siempre debe aplicarse salvo contadas excepciones.

A continuación daremos ciertas normas, que aunque no pretenden ser un


estándar, si que son de recomendado uso:

1. Los nombres de objetos (tablas, índices, claves primarias, claves forá-


neas…) deben ir en mayúscula. Oracle interpreta por defecto todos los
objetos en mayúscula a no ser que se escriba su nombre entre comillas
dobles:

Nombres Interpretación de Oracle


Factura, factura y FACTURA Equivalente.
"FACTURA", "factura", "Factura" Distintos objetos.

2. Los nombres de objetos deben ir en singular ya que el nombre represen-


ta a la entidad que almacena, y no las entidades que almacena. Una ra-
zón práctica es que con los nombres en minúscula se ahorra 1 ó 2 le-
tras, lo cual no es despreciable.

Entidad Nombre recomendado


Facturas FACTURA
Facturas de proveedores FACTURA_PROVEEDOR
Facturas que no han sido pagadas FACTURA_PENDIENTE_PAGO
Facturas caducadas FACTURA_CADUCADA

3. Los nombres a utilizar deben ser descriptivos, aunque no deben ser de-
masiado largos. Oracle admite hasta un máximo de 30 caracteres para
los identificadores, aunque no es recomendable llegar hasta el límite.

Entidad Nombre recomendado


Empresas pertenecientes al sector de la construcción
EMPRESA_CONSTRUCCION
Clientes que han tenido algún impago CLIENTE_MOROSO
Proveedores que se suelen retrasar en sus entregas PROVEEDOR_LENTO,
PROVEEDOR_RETRASO
Facturas caducadas de empresas del sector de la construcción
FACTURA_CONSTRUCCION_CADUCADA

4. Es recomendable utilizar abreviaturas, sobre todo si el nombre más des-


criptivo es demasiado largo. Para nombres cortos no es necesario utili-
zar abreviaturas.

Entidad Nombre recomendado


Empresas pertenecientes al sector de la construcción que han tenido alguna
demolición EMPRESA_CONSTR_DEMOLICION
Clientes que han tenido algún impago CLIENTE_MOROSO
Proveedores que se suelen retrasar en sus entregas de empresas del sector de
la construcción
PROVEEDOR_CONSTR_LENTO,
PROVEEDOR_ CONSTR _RETRASO
Facturas caducadas de empresas del sector de la construcción
FACTURA_CONSTR_CADUCADA
Almacén de productos terminados para empresas del sector de la construcción
ALMACEN_ CONSTR _PROD_TERM
5. A la hora de nombrar tablas relacionadas entre si, es recomendable que
el nombre empiece por el sufijo que representa la entidad principal.

Entidad Nombre recomendado


Facturas FACTURA
Líneas de Factura (detalle de FACTURA) FACTURA_LINEA
Desglose de las líneas de factura (detalle de
FACTURA_LINEA)
FACTURA_LINEA_DESGLOSE
Factura impagadas (Relación 1-1 con FACTURA) FACTURA_IMPAGADA,
FACTURA_IMPAGO

6. Se pueden establecer ciertas abreviaturas para los nombres de colum-


nas: Columnas típicas Abreviatura

Código de… C_xxx


Descripción de… D_xxx
Referencia de …REF_xxx
Importe de …IMP_xxx
Precio de …PRC_xxx
Porcentaje de …PCT_xxx
Unidades de …UDS_xxx
Tipo de …TIP_xxx
Número de …NUM_xxx
Cualquiera que aparezca un elevado número de veces en el esquema

7. Los nombres de clave primaria deben ir precedidos del prefijo PK_ (Pri-
marykey), los de índices por IND_, y los de clave foránea por FK_ (Fo-
reingkey).

El nombre restante será el de la propia tabla para las claves primarias, el de la


tabla referenciada para las claves foráneas y para los índices una o dos
palabras descriptivas que indiquen la razón por la que se crea ese índice (si es
posible).

Conceptos de almacenamiento en Oracle


Concepto de Tablespace Una base de datos se divide en unidades lógicas
denominadas TABLESPACES.

Un tablespace no es un fichero físico en el disco, simplemente es el nombre


que tiene un conjunto de propiedades de almacenamiento que se aplican a los
objetos (tablas, secuencias…) que se creen en la base de datos bajo el
tablespace indicado (tablas, secuencias…).
Un objeto en base de datos debe estar almacenado obligatoriamente dentro de
un tablespace.

Las propiedades que se asocian a un tablespace son:


- Localización de los ficheros de datos.
- Especificación de máximas cuotas de consumo de disco.
- Control de la disponibilidad de los datos (en línea o fuera de línea).
- Backup de datos.

Cuando un objeto se crea dentro de un cierto tablespace, este objeto adquiere


todas las propiedades antes descritas deltablespace utilizado.
En este esquema podemos ver que, por ejemplo, la tabla ARTICULO se
almacena dentro del tablespace A, y que por lo tanto tendrá todas las
propiedades del tablespace A que pueden ser:

- Sus ficheros de datos están en $ORACLE_HOME/datos/datos_tablespace_A


- Los objetos no pueden ocupar más de 10Mb de espacio de base de datos.
- En cualquier momento se puede poner fuera de línea todos los objeto de un
cierto tablespace.
- Se pueden hacer copiar de seguridad sólo de ciertos tablespaces.

Si nos fijamos, se puede apreciar que es posible tener una tabla en un


tablespace, y los índices de esa tabla en otro tablespace. Esto es debido a que
los índices no son más que objetos independientes dentro de la base de datos,
como lo son las tablas. Y al ser objetos independientes, pueden ir en
tablespaces independientes.

El tablespace SYSTEM es un tablespace por defecto en todas las bases de


datos Oracle. En él se almacenan todos los datos de sistema, el catálogo y
todo el código fuente y compilado de procedimientos PL/SQL. También es
posible utilizar el mismo tablespace para guardar datos de usuario.

En el esquema también vemos que hay un tablespace Temporal (en gris


oscuro). Este tablespace representa las propiedades que tendrán los objetos
que la base de datos cree temporalmente para sus cálculos internos
(normalmente para ordenaciones y agrupaciones). La creación de un
tablespace temporal difiere en una de sus cláusulas de creación.

El tablespace RO (en gris claro) difiere de los demás en que es un tablespace


de solo lectura (ReadOnly), y que por lo tanto todos los objetos en él
contenidos pueden recibir órdenes de consulta de datos, pero no de
modificación de datos.

Estos tablespaces puede residir es soportes de sólo lectura, como pueden ser
CDROMs, DVDs, etc.
Cuando se crea un tablespace, éste se crea de lectura/escritura. Después se
puede modificar para que sea de solo lectura.

Un tablespace puede estar en línea o fuera de ella (Online oOffLine), esto es


que el tablespace completo está a disposición de los usuarios o está
desconectado para restringir su uso.

Cualquier objeto almacenado dentro de un tablespace no podrá ser accedido si


el tablespace está fuera de línea.

Base de datos
Tablespace Temporal
Tablespace A
Tabla ARTICULO
Índice en ARTICULO
Índice en FACTURA
Índice 2 en FACTURA
Índice en PROVEEDOR
Tablespace RO
Tabla PAIS
Tablespace SYSTEM
Tabla FACTURA Tabla CLIENTE
Índice en CLIENTE
Tabla PROVEEDOR
Tablas y catálogo de
sistema de ORACLE

Concepto de Datafile (fichero de datos)


Un datafile es la representación física de un tablespace. Son los "ficheros de
datos" donde se almacena la información físicamente.

Un datafile puede tener cualquier nombre y extensión (siempre dentro de las


limitaciones del SO), y puede estar localizado en cualquier directorio del disco
duro, aunque so localización típica suele ser $ORACLE_HOME/Database.

Un datafile tiene un tamaño predefinido en su creación (por ejemplo 100Mb) y


este puede ser alterado en cualquier momento.

Cuando creemos un datafile, este ocupará tanto espacio en disco como


hayamos indicado en su creación, aunque internamente esté vacío. Oracle
hace esto para direccionar espacio continuo en disco y evitar así la
fragmentación.

Conforme se vayan creando objetos en ese tablespace, se irá ocupando el


espacio direccionado. Un datafile está asociado a un solo tablespace y un
tablespace está asociado a uno o varios datafiles. Es decir, la relación lógica
entre Tablespaces y datafiles es de 1-N, maestro-detalle.

En el esquema podemos ver como el Tablespace A está compuesto


(físicamente) por tres datafiles (DATOS_1.ORA, DATOS_2.ORA y
DATOS_3.ORA). Estos tres datafiles son los ficheros físicos que soportan los
objetos contenidos dentro deltablespace A.

Aunque siempre se dice que los objetos están dentro del tablespace, en
realidad las tablas están dentro del datafile, pero tienen la propiedades
asociadas al tablespace. Cada uno de los datafiles utilizados está ocupando su
tamaño en disco (50 Mb los dos primeros y 25 Mb el último) aunque en realidad
sólo contengan dos objetos y estos objetos no llenen el espacio que está
asignado para los datafiles.

Los datafiles tienen una propiedad llamada AUTOEXTEND, que se si está


activa se encarga de que el datafile crezca automáticamente (según un tamaño
indicado) cada vez que se necesite espacio y no exista.

Al igual que los tablespaces, los datafiles también puede estar en línea o fuera
de ella. Nivel físico: Soporte de almacenamiento (disco duro, cinta…)

Datafile: $ORACLE_HOME/Database/DATOS_1.ORA
Tamaño: 50Mb
Datafile: $ORACLE_HOME/Database/DATOS_2.ORA
Tamaño: 50Mb
Datafile: $ORACLE_HOME/Database/DATOS_3.ORA
Tamaño: 25Mb
Tablespace A
Tabla FACTURA
Índice en FACTURA

Concepto de Segment (segmento, trozo, sección)


Un segment es aquel espacio direccionado por la base de datos dentro de un
datafile para ser utilizado por un solo objeto. Así una tabla (o cualquier otro
objeto) está dentro de su segment, y nunca podrá salir de él, ya que si la tabla
crece, el segment también crece.

Físicamente, todo objeto en base de datos no es más que un segment


(segmento, trozo, sección) en un datafile. Se puede decir que un segmento es
a un objeto de base de datos, como un datafile a un tablespace: el segmento
es la representación física del objeto en base de datos (el objeto no es más que
una definición lógica).

Podemos ver como el espacio que realmente se ocupa dentro del datafile es el
segment y que cada segment pertenece a un objeto.

Existen tres tipos de segments (principalmente):


Segmentos de tipo TABLE: aquellos que contienen tablas
Segmentos de tipo INDEX: aquellos que contienen índices
Segmentos de tipo ROLLBACK: aquellos se usan para almacenar información
de la transacción activa.

Concepto de Extent (extensión)


Para cualquier objeto de base de datos que tenga cierta ocupación en disco, es
decir, cualquier objeto que tenga un segment relacionado, existe el concepto de
extent.
Extent es un espacio de disco que se direcciona de una sola vez, un segment
que se direcciona en un momento determinado de tiempo.

El concepto de extent es un concepto físico, unos extent están separados de


otros dentro del disco. Ya dijimos que todo objeto tiene su segment asociado,
pero lo que no dijimos es que este segment, a su vez, se compone de extents.
Un segment, puede ser direccionado de una sola vez (10 Mb de golpe), o de
varias veces (5 Mb hoy y 5 Mb mañana). Cada uno de las veces que se
direcciona espacio se denomina Extent.

Segment FACTURA
DataFile 1
Segment de índ. FACTURA
DataFile 2
Tablespace A
Índice en FACTURA
700 K 700 K
Tabla FACTURA
Tablespace A
DataFile A-1
FACTURA
1 Mb 700 K
Extensiones (3)

En el esquema vemos como el objeto (tabla) FACTURA tiene un segment en el


datafile A-1, y este segment está compuesto de 3 extents.
Una de estas extensiones tiene un color distinto. Esto es porque existen dos
tipos de extents:
 INITIAL (extensiones iniciales): estas son las extensiones que se
direccionan en el momento de la creación del objeto. Una vez que
un objeto está creado, no se puede modificar su extensión inicial.
 NEXT (siguientes o subsiguientes extensiones): toda extensión di-
reccionada después de la creación del objeto. Si la INITIAL EX-
TENT de una tabla está llena y se está intentando insertar más fi-
las, se intentará crear una NEXT EXTENT (siempre y cuando el
datafile tenga espacio libre y tengamos cuota de ocupación sufi-
ciente).

Sabiendo que las extensiones se crean en momentos distintos de tiempo, es


lógico pensar que unas extensiones pueden estar fragmentadas de otras. Un
objeto de base de datos no reside todo junto dentro del bloque, sino que
residirá en tantos bloque como extensiones tenga. Por eso es crítico definir un
buen tamaño de extensión inicial, ya que, si es lo suficientemente grande, el
objeto nunca estará defragmentado.
Si el objeto tiene muchas extensiones y éstas están muy separadas en disco,
las consultas pueden retardarse considerablemente, ya que las cabezas
lectoras tienes que dar saltos constantemente.

El tamaño de las extensiones (tanto las INITIAL como las NEXT), se definen
durante la creación del objeto y no puede ser modificado después de la
creación.

Oracle recomienda que el tamaño del INITIAL EXTENT sea igual al tamaño del
NEXT EXTENT.

Concepto de Data block(bloque de datos)


Un data block es el último eslabón dentro de la cadena de almacenamiento. El
concepto de Data block es un concepto físico, ya que representa la mínima
unidad de almacenamiento que es capaz de manejar Oracle.

Igual que la mínima unidad de almacenamiento de un disco duro es la unidad


de asignación, la mínima unidad de almacenamiento de Oracle es el data
block. En un disco duro no es posible que un fichero pequeño ocupe menos de
lo que indique la unidad de asignación, así si la unidad de asignación es de 4
Kb, un fichero que ocupe 1 Kb, en realidad ocupa 4 Kb.

Siguiendo con la cadena, cada segment (o cada extent) se almacena en uno o


varios data blocks, dependiendo del tamaño definido para el extent, y del
tamaño definido para el data block.
(*) Espacio ocupado en data block por la primera NEXT EXTENSION.
(#) Espacio ocupado en unidades de asignación del SO por los data blocks
anteriores.
(#)
(*)
700 K 700 K
Tablespace A
DataFile A-1
FACTURA
1 Mb 700 K Disco Duro (como está particionado según el SO)
Disco Duro (como lo ve Oracle)

El esquema muestra toda la cadena de almacenamiento de Oracle:


Desde el nivel más físico al más lógico:
· Unidades de asignación del SO (El más físico. No depende de Oracle)
· Data blocks de Oracle
· Extents
· Segments
· DataFiles
· Tablespaces (El más lógico)
El tamaño de las unidades de asignación del SO se define durante el
particionado del disco duro (FDISK, FIPS…), y el espacio de los data blocks de
Oracle se define durante la instalación y no puede ser cambiado.

Como es lógico, el tamaño de un data block tiene que ser múltiplo del tamaño
de una unidad de asignación, es decir, si cada unidad de asignación ocupa 4 K,
los data blocks pueden ser de 4K, 8K, 12K… para que en el SO ocupen 1, 2,
3…

unidades de asignación.
Tipos de datos en Oracle
Los tipos de datos soportados por Oracle se agrupan en los siguientes
conjuntos.
Los valores alfanuméricos van encerrados entre comilla simple: 'Alfanumérico'
Los valores numéricos son número simples: 123
Las fechas van encerradas entre comillas simples: '1/12/2000'
Los valores binarios no pueden ser representados (son fotos, videos…)
Tipo de dato CHAR(b)
Almacena cadenas de caracteres de longitud fija, desde 1 a 2.000 bytes de
ocupación. El número de caracteres que se pueden almacenar se rige según la
siguiente fórmula.
nº caracteres = bytes / character set
Para ASCII, el conjunto de caracteres ocupa un byte, por lo que coincide el
número de caracteres máximos con la ocupación del tipo de dato.
Si se introduce un valor de 10 caracteres en un campo de CHAR(100), se
rellenará con espacios las 90 posiciones restantes.

Así la siguiente expresión es cierta:


'Hola pepe' = 'Hola pepe '
Si se intenta introducir un valor demasiado grande para el campo, se intentará
eliminar los espacios finales, y si cabe sin espacios, se introduce. Si aún así no
cabe, se retorna un error.

Tipo de dato VARCHAR2(b)


Almacena cadenas de caracteres de longitud variable.
Si se define una columna de longitud 100 bytes, y se introduce en ella un valor
de 10 bytes, la columna ocupará 10 y no 100 como hacía con el tipo de dato
CHAR.

Tipo de dato VARCHAR(b)


En Oracle8 es equivalente a VARCHAR2, en futuras versiones permitirá
distintos criterios de comparación.

Tipo de dato NCHAR(b)


Almacena un valor alfanumérico de longitud fija con posibilidad de cambio de
juego de caracteres. Puede almacenar
tanto caracteres ASCII, EBCDIC, UNICODE…

Tipo de dato NVARCHAR2(b)


Almacena un valor alfanumérico de longitud variable con posibilidad de cambio
de juego de caracteres. Puede almacenar tanto caracteres ASCII, EBCDIC,
UNICODE…

Tipo de dato NUMBER(p,s)


Almacena valores numéricos en punto flotante que pueden ir desde 1.0 x 10-
130 hasta 9.9…(38 nueves)… 9 x 10125.

El almacenamiento interno de los valores numéricos en notación científica:


Mantisa x 10exponente La mantisa puede contener cualquier número, entero o
decimal, positivo o negativo. El exponente podrá contener cualquier número
entero, positivo o negativo.

Tipos de datos Oracle


CHAR
VARCHAR2
VARCHAR
NCHAR
NVARCHAR2
LONG
Alfanuméricos
NUMBER
FLOAT
Numéricos
DATE
Fecha
RAW
LONG RAW
BLOB
CLOB
NLOB
BFILE
Binarios
ROWID
Otros

El parámetro p indica la precisión (número de dígitos contando los decimales)


que contendrá el número como máximo. Oracle garantiza los datos con
precisiones de 1 a 38.

El parámetro s indica la escala, esto es, el máximo de dígitos decimales. Hay


que tener en cuenta que una columna definida NUMBER(10,5), podrá contener
como máximo cualquier número siempre y cuando el número de dígitos enteros
más el número de dígitos decimales no supere 10 (y no 15).

La escala puede ir de -84 a 127. Para definir número enteros, se puede omitir
el parámetro s o bien poner un 0 en su lugar.

Se puede especificar una escala negativa, esto lo que hace es redondear el


número indicado a las posiciones indicadas en la escala. Por ejemplo un
número definido como NUMBER(5,-2), redondeará siempre a centenas. Así si
intentamos introducir el valor 1355, en realidad se almacenará 1400.

Tipo de dato FLOAT(b)


Almacena un número en punto decimal sin restricción de dígitos decimales. El
parámetro b indica la precisión binaria máxima que puede moverse en el rango
1 a 126. Si se emite el defecto será
126. Una columna FLOAT(126) es equivalente a una columna NUMBER(38),
aunque la diferencia está en que la columna NUMBER no podrá contener
decimales y la columna FLOAT si y en con cualquier escala.
Tipo de dato DATE
Almacena un valor de fecha y hora.
Para un tipo de dato DATE, Oracle almacena internamente los siguiente datos:
Siglo
Año
Mes
Día
Hora
Minuto
Segundo

El formato por defecto de las fechas es:


'DD-MON-YYYY'
Esto es:
Dos dígitos para el día
Las tres primeras siglas del año (depende del idioma instalado).
Cuatro dígitos para el año.
Por ejemplo:
'1-JAN-2001'
'2-DEC-1943'

Este formato puede ser alterado en cualquier momento. Internamente un fecha


se almacena como el número de días desde cierto punto de inicio (por ejemplo
el año 0). Esto permite que las fechas puedan ser tratadas en operaciones
aritméticas normales:
'1-JAN-2001' + 10 = '11-JAN-2001'
'1-JAN-2000' - 1 = '31-DEC-1999'
'10-MAY-2000' - '1-MAY-2000' = 9
Tipos de datos binarios
Permiten almacenar información en formato "crudo", valores binarios tal y como
se almacenan en el disco duro o como residen en memoria. Estas columnas se
pueden utilizar tanto para almacenar grandes cantidades de datos (hasta
4Gb.), como para almacenar directamente cualquier tipo de fichero
(ejecutables, sonidos, videos, fotos, documentos Word, DLLs…) o para
transportar datos de una base de datos a otra, ya que el formato binario es el
único formato común entre cualquier sistema informático.

Tipo de dato LONG


Almacena caracteres de longitud variable hasta 2 Gb. Este tipo de dato se
soporta para compatibilidad con versiones anteriores. En Oracle8 y siguientes
versiones de debe usar los tipos de datos CLOB y NLOB para almacenar
grandes cantidades de datos alfanuméricos.
Tipo de dato ROWID
Representa una dirección de la base de datos, ocupada por una única fila. El
ROWID de una fila es un identificador único para una fila dentro de una base
de datos. No hay dos filas con el mismo ROWID. Este tipo de dato sirve para
guardar punteros a filas concretas.

Lenguaje estructurado de consultas SQL


SQL es un conjunto de sentencias u órdenes que todos los programas y
usuarios deben utilizar para acceder a bases de datos Oracle. No hay otra
manera de comunicarse con Oracle si no es a través de SQL. Dado que SQL
es un estándar, todas las bases de datos comerciales de la actualidad utilizan
SQL como puente de comunicación entre la base de datos y el usuario.

Historia
SQL nació como a partir de una publicación de 1970 escrita por E.F. Cood, y
titulada "A relationalmodel of data for largeshared data banks" (El modelo de
datos relacionales para grandes bancos de datos compartidos). IBM utilizó el
modelo planteado por Codd para desarrollar un lenguaje capaz de soportar el
recién nacido modelo relacional y así apareció SEQUEL (Structured English
QUEry Language). SEQUEL más tarde se convirtió en SQL (StructuredQuery
Language) que continuó pronunciándose en inglés como su predecesor:
SEQUEL. En 1979, una desconocida empresa llamadaRelational Software,
sacó por sorpresa al mercado la primera implementación comercial de SQL.
Relational Software más tarde pasó a llamarse Oracle.

Después de 20 años, SQL todavía es (y será) siendo el estándar en lenguajes


de acceso a base de datos relacionales. En 1992, ANSI e ISO (organizaciones
que se encargan de establecer estándares de todo tipo), completaron la
estandarización de SQL y se definió un conjunto de sentencias básicas que
debía tener toda implementación para ser llamada estándar. Este SQL se le
denominó ANSI-SQL o SQL92.
Hoy en día todas las bases de datos comerciales cumplen el estándar ANSI,
aunque cada fabricante añade sus mejoras al lenguaje SQL.

SQL como lenguaje estructurado


En realidad SQL no es un lenguaje en si, como podría ser un lenguaje de
programación de 3ª generación (C, Pascal…), sino que en un sublenguaje
orientado a acceso y manipulación de base de datos relacionales. Con SQL
como única herramienta sólo podemos acceder a las bases de datos, pero no
tenemos las estructuras típicas de un lenguaje de programación.

Una buena analogía podría ser un sistema operativo. El interfaz de comandos


de un SO nos da todo lo que necesitamos para acceder al sistema de ficheros,
pero sólo podemos hacer eso, acceder a ficheros.

SQL actúa de la misma manera, nos da todo lo que necesitamos para acceder
a bases de datos, pero no podemos hacer más.

Se dice que SQL es estructurado porque trabaja con conjuntos de resultados


(result set) abstractos como unidades completas. Un conjunto de resultados es
el esquema básico de una tabla: N filas x N columnas. Este esquema se trata
como un todo y es la idea principal de SQL.

A la hora de recuperar un conjunto de resultados, éste se trata de la misma


forma tenga el número de filas que tenga (0-N) y tenga el número de columnas
que tenga (1-N). Además SQL es consistente, esto significa que los "estilos" de
las distintas sentencias son uniformes, por lo que el aprendizaje es rápido.

Operadores SQL
Ya hemos visto anteriormente qué tipos de datos se pueden utilizar en Oracle.
Y siempre que haya datos, habrá operaciones entre ellos, así que ahora se
describirán qué operaciones y con qué operadores se realizan:

Los operadores se pueden dividir en dos conjuntos:


· Aritméticos: utilizan valores numéricos
· Lógicos (o booleanos o de comparación): utilizan valores booleanos o lógicos.
· Concatenación: para unir cadenas de caracteres.
· Operadores arítméticos:
Retornan un valor numérico
Símbolo Significado Ejemplo
+ Operación suma 1 + 2
- Operación resta 1 - 2
* Operación
Multiplicación 1 * 2
/ Operador división 1 / 2
· Operadores lógicos:
Retornan un valor lógico (verdadero o falso)

Símbolo Significado Ejemplo


= Igualdad 1 = 2
!=
<>
^=
Desigualdad 1 != 2
1 <> 2
1 ^= 2
> Mayor que 1 > 2
< Menor que 1 < 2
>= Mayor o igual que 1 >= 2
<= Menor o igual que 1 <= 2
IN (RS) Igual a algún elemento del result set. 1 IN (1,2)
[TRUE]
<op.> ANY
<op.> SOME
<op> a algúnelemento del result set (derecha).

Debe ser estar precedido por


=, !=, <, <=, >, >=
Hace un OR lógico entre todos los elementos.
10 >= ANY (1,2,3,10)
[TRUE]
<op.> ALL <op> a todos los elementos del result set (derecha),
Debe ser estar precedido por
=, !=, <, <=, >, >=
Hace un AND lógico entre todos los elementos.
10 <= ALL (1,2,3,10)
[TRUE]
BEETWEEN
x AND y
Operando de la izquierda entre x e y.
Equivalente a op >= x AND op <= y
10 BETWEEN 1 AND 100
EXISTS

<subconsulta>
Si la <subconsulta> retorna al menos una fila EXISTS(
SELECT 1 FROM DUAL)
LIKE(*) Escomo 'pepe' LIKE 'pe%'
IS NULL Si es nulo 1 IS NULL
IS NOT NULL Si es No nulo 1 IS NOT NULL
NOT cond. Niega la condición posterios NOT EXISTS…
NOT BETWEEN
NOT IN
NOT =
cond AND condHace un AND lógico entre dos condiciones 1=1 AND 2 IS NULL
Cond OR condHaceun OR lógico entre dos condiciones 1=1 OR 2 IS NULL
(*) El operador LIKE sirve para hacer igualdades con comodines, al estilo * y ?
de MS-DOS.

Existen los siguientes comodines:


%: Conjunto de N caracteres (de 0 a ¥)
_: Un solo carácter

Ejemplo:
Las siguientes condiciones retornan TRUE
'significado LIKE 's_gn%fi%d_'
'pepe' LIKE 'pep%' (todos los que empiecen por 'pep')
'pepote' LIKE 'pep%'
'pepote' LIKE 'pe%te' (todos los que empiecen por 'pe' y terminen por 'te')
'pedrote' LIKE 'pe%te'

Operador de concatenación:
Retornan una cadena de caracteres Símbolo Significado Ejemplo
|| Concatena una cadena a otra 'juan' || 'cito'
['Juancito']
Oracle puede hacer una conversión automática cuando se utilice este operador
con valores numéricos:
10 || 20 = '1020'

Este proceso de denomina CASTING y se puede aplicar en todos aquellos


casos en que se utiliza valores numéricos en puesto de valores alfanuméricos o
incluso viceversa.

La ausencia de valor: NULL


Todo valor (sea del tipo que sea) puede contener el valor NULL que no es más
que la ausencia de valor. Así que cualquier columna (NUMBER, VARCHAR2,
DATE…) puede estar a NULL.

Una operación retorna NULL si cualquiera de los operandos es NULL. Para


comprobar si una valor es NULL se utiliza el operador IS NULL o IS NOT NULL.

Lenguaje de manipulación de datos: DML


El DML (Data ManipulationLanguage) es el conjunto de sentencias que está
orientadas a la consulta, y manejo de datos de los objetos creados.
El DML es un subconjunto muy pequeño dentro de SQL, pero es el más
importante, ya que su conocimiento y manejo con soltura es imprescindible.
Básicamente consta de cuatro sentencias: SELECT, INSERT, DELETE,
UPDATE.

SELECT
La sentencia SELECT es la encargada de la recuperación (selección) de datos,
con cualquier tipo de condición, agrupación u ordenación.

Una sentencia SELECT retorna un result set (conjunto de resultados), por lo


que podrá ser aplicada en cualquier lugar donde se espere un result set.

La sintaxis básica es:


SELECT columnas
FROM tablas
WHERE condición
GROUP BY agrupación
HAVING condición agrupada
ORDER BY ordenación;

Todas las cláusulas son opcionales excepto SELECT y FROM.

A continuación vamos a hacer una descripción breve de cada cláusula:

· SELECT: se deben indicar las columnas que se desean mostrar en el


resultado. Las distintas columnas deben aparecer separadas por coma (",").

Opcionalmente puede ser cualificadas con el nombre de su tabla utilizando la


sintaxis:

TABLA.COLUMNA
Si se quieren introducir todas las columnas se podrá incluir el carácter *, o bien
TABLA.* Existe la posibilidad de sustituir los nombres de columnas por
constantes (1, 'pepe' o '1-may-2000'), expresiones, pseudocolumnas o
funciones SQL.

A toda columna, constante, pseudocolumna o función SQL, se le puede


cualificar con un nombre adicional:
COLUMNA NOMBRE
CONSTANTE NOMBRE
PSEUDOCOLUMNA NOMBRE
FUNCION SQL NOMBRE

Si se incluye la cláusula DISTINCT después de SELECT, se suprimirán


aquellas filas del resultado que tenga igual valor que otras.

Así
SELECT C_CLIENTE FROM FACTURA;
Puede retornar
1355
17329
Sin embargo:
SELECT DISTINCT C_CLIENTE FROM FACTURA;
Retornará (suprimiendo las repeticiones)
135729

Ejemplos:
SELECT REFERENCIA REF, DESCRIPCION
SELECT FACTURA.REFERENCIA, DESCRIPCION
SELECT *
SELECT FACTURA.*
SELECT 1 UN_NUMERO_CTE_CUALIFICADO, REFERENCIA
SELECT 1+1-3*5/5.4 UNA_EXPRESION_SIN_CUALIFICADA
SELECT DESCRIPCION, ROWNUM
UNA_PSEUDOCOLUMNA_CUALIFICADA
SELECT TRUNC( '1-JAN-2001'+1, 'MON' ) UNA_FUNCION_CUALIFICADA
SELECT DISTINCT *
SELECT DISTINCT DESCRIPCION, IMPORTE
SELECT REFERENCIA||DESCRIPCION
· FROM: se indican el(los) result set(s) que interviene(n) en la consulta.
Normalmente se utilizan tablas, pero se
admite cualquier tipo result set (tabla, select, vista…).
Si apareciese más de una tabla, deben ir separadas por coma.
Las tablas deben existir y si no existiera alguna aparecería el siguiente error:
ORA-00942: table or view does not exist
Al igual que a las columnas, también se puede cualificar a las tabla

TABLA NOMBRE
Oracle tiene definida una tabla especial, llamada DUAL, que se utiliza para
consultar valores que no dependen de
ningún result set.
SELECT (1+1.1*3/5)-1-2 FROM DUAL;
Ejemplos:
FROM FACTURA FAC
FROM FACTURA FAC, CLIENTE CLI
FROM DUAL
FROM ( SELECT C_CLIENTE FROM FACTURA ) CLIENTE_FAC
· WHERE: indica qué condiciones debe cumplirse para que una fila entre
dentro del result set retornado.

Para construir las condiciones se podrán utilizar todos los operadores lógicos
vistos anteriormente.
Es posible construir condiciones complejas uniendo dos o más condiciones
simples a través de los operadores lógicos AND y OR.
Ejemplos:
WHERE FACTURA.REFERENCIA = 'AA3455'
WHERE FACTURA.C_CLIENTE IS NULL
WHERE C_CLIENTE BETWEEN '12' AND '20'
WHERE C_CLIENTE IS NULL AND
REFERENCIA IN ('AA23344', 'BB23345')
WHERE C_CLIENTE != 55 OR
REFERENCIA LIKE 'AA%5_'
· GROUP BY: La expresión GROUP BY se utiliza para agrupar valores que es
necesario procesar como un grupo.

Por ejemplo, puede darse el caso de necesitar procesar todas las facturas de
cada cliente para ver su total, o para contarlas, o para incrementarles un 10%…
Para estos casos se haría un SELECT agrupando por C_CLIENTE.

Un SELECT con GRUOP BY es equivalente a un SELECT DISTINCT, siempre


y cuando en el SELECT no aparezcan consultas sumarias (ver apartado
Funciones SQL).

Trataremos con más profundidad este tipo de consultas en el apartado


"Consultas agrupadas".

· HAVING: Se utiliza para aplicar condiciones sobre agrupaciones. Sólo puede


aparecer si se ha incluido la cláusula GROUP BY.

· ORDER BY: Se utiliza para ordenar las filas del result set final. Dentro de esta
cláusula podrá aparecer cualquier expresión que pueda aparecer en el
SELECT, es decir, pueden aparecer columnas, pseudocolumnas, constantes
(no tiene sentido, aunque está permitido), expresiones y funciones SQL. Como
característica adicional, se pueden incluir números en la ordenación, que serán
sustituidos por la columna correspondiente del SELECT en el orden que
indique el número.

La ordenación es el último paso en la ejecución de una consulta SQL, y para


ello Oracle suele necesitar crear objetos temporales que son creados en el
tablespace Temporal. Por eso es recomendable hacer las ordenaciones del
lado de cliente (siempre que sea posible), ya que el servidor puede cargarse
bastante si tiene que hacer, por ejemplo, 300 ordenaciones de tablas de 2
millones de registros.

Después de cada columna de ordenación se puede incluir una de las palabras


reservadas ASC o DESC, para hacer ordenaciones ASCendentes o
DESCendentes. Por defecto, si no se pone nada se hará ASC.

Ejemplos:
ORDER BY REFERENCIA ASC
ORDER BY REFERENCIA DESC, C_CLIENTE DES, IMPORTE ASC
ORDER BY C_CLIENTE
ORDER BY 1, C_CLIENTE, 2
ORDER BY TRUNC( '1-JAN-2001'+1, 'MON' )
ORDER BY 1.1+3-5/44.3 -- no tiene sentido ordenar por una cte.

Consultas agrupadas
Una consulta agrupada se utiliza para considerar los registros cuyos ciertos
campos tienen el mismo valor, y procesarlos de la misma manera, para
contarlos, sumarlos, hacer la media… Las consultas típicas son para contar los
registros de cierto tipos, sumar los importes de cierto cliente, etc.

Por ejemplo, vamos a sacar el total del importe de las factura, por cliente:
SELECT C_CLIENTE, SUM(IMPORTE)
FROM FACTURA
GROUP BY C_CLIENTE;

Esto nos sumará (la función SUM suma su parámetro) los registro agrupando
por cliente. Internamente Oracle tiene que hacer una ordenación interna de los
registros, según las columnas incluidas en el GROUP BY, así que todo lo dicho
para el ORDER BY se puede aplicar para el GROUP BY (sobrecarga del
servidor). Cuando en la cláusula SELECT no se incluyen funciones SQL (para
más información ver el apartado Funciones SQL), una consulta GROUP BY es
equivalente a una consulta SELECT DISTINCT.

Un error muy común cuando se construyen consultas agrupadas, es el


siguiente: ORA-00979: not a GROUP BY expression Esto es debido al modo
que tiene Oracle de analizar las consultas agrupadas:

Lo que hace es comprobar que todos las columnas incluidos en la cláusula


SELECT fuera de funciones sumarias, estén dentro de la cláusula GROUP BY,
aunque pueden estar en cualquier orden y en el GROUP BY pueden aparecer
columnas que no estén en el SELECT.

Si encuentra alguna columna en el SELECT (que no esté dentro de una función


sumaria) que no aparezca en el GROUP BY, entonces nos retorna el error
anterior.
Si pensamos la situación, es lógico que nos retorne un error, porque no
podemos agrupar por la columna C_CLIENTE, si luego queremos mostrar otras
columnas que estén sin agrupar. O agrupamos por todo, o mostramos sin
agrupar, pero ambas a la vez no es posible.

Ejemplos de consultas agrupadas:


SELECT C_CLIENTE, SUM( IMPORTE )
FROM FACTURA
GROUP BY C_CLIENTE;
SELECT C_PAIS, SUM( IMPORTE )
FROM FACTURA
GROUP BY C_PAIS;
SELECT C_CLIENTE, COUNT(*)
FROM FACTURA
GROUP BY C_CLIENTE;
SELECT C_CLIENTE, SUM(1)
FROM FACTURA
GROUP BY C_CLIENTE;
SELECT C_PAIS, AVG( IMPORTE )
FROM FACTURA
GROUP BY C_PAIS;
SELECT C_PAIS, COUNT(*)
FROM CLIENTE
GROUP BY C_PAIS,
SELECT C_CLIENTE + AVG( IMPORTE )
FROM FACTURA;

Consultas multitabla
El posible que para consultas sencillas, todos los datos que necesitemos estén
en una sola tabla. Pero… ¿y si están repartidos por una, dos o muchas tablas?
Es posible hacer consultas que incluyan más de una tabla (o result set) dentro
de la cláusula FROM, como ya vimos anteriormente.

Pero en estas consultas hay que tener en cuenta ciertos factores. Vemos lo que
hacer Oracle para esta consulta.

SELECT F.REFERENCIA, F.C_CLIENTE, C.C_CLIENTE, C.D_CLIENTE


FROM FACTURA F, CLIENTE C;
Suponiendo que tenemos los siguientes datos:
FACTURA CLIENTE
Referencia C_ClienteC_ClienteD_Cliente
A111 1 1 Pepote
A112 2 2 Juancito
A113 1 5 Toñete
A114 5
A115 2
El select anterior nos retornará el siguiente result set
F.REFERENCIA F.C_CLIENTE C.C_CLIENTE C.D_CLIENTE
A111 1 1 Pepote
A111 1 2 Juancito
A111 1 5 Toñete
A112 2 1 Pepote
A112 2 2 Juancito
A112 2 5 Toñete
A113 1 1 Pepote
A113 1 2 Juancito
A113 1 5 Toñete
A114 5 1 Pepote
A114 5 2 Juancito
A114 5 5 Toñete
A115 2 1 Pepote
A115 2 2 Juancito
A115 2 5 Toñete

Podemos ver que el resultado es el producto cartesiano de una tabla por otra
tabla, es decir, todas las combinaciones posibles de la tabla FACTURA con la
tabla CLIENTE.

Pero en realidad lo que a nosotros nos interesa es mostrar todas las facturas,
pero con la descripción del cliente de cada factura, es decir, que cada factura
seleccione sólo su registro correspondiente de la tabla CLIENTE.

Los registros que a nosotros nos interesan están marcados en negrita en el


esquema anterior, y en todos ellos se cumple que F.C_CLIENTE =
C.C_CLIENTE. O dicho de otro modo, los campos que componen la relación
igualados.

Entonces del result set anterior, sólo nos interesan los registros marcados en
negrita, y el select que nos retorna ese resultados es:

SELECT F.REFERENCIA, F.C_CLIENTE, C.C_CLIENTE, C.D_CLIENTE


FROM FACTURA F, CLIENTE C
WHERE F.C_CLIENTE = C.C_CLIENTE;
El resultado final es:
F.REFERENCIA F.C_CLIENTE C.C_CLIENTE C.D_CLIENTE
A111 1 1 Pepote
A112 2 2 Juancito
A113 1 1 Pepote
A114 5 5 Toñete
A115 2 2 Juancito

Esto son con la descripción del cliente. Como norma general se puede decir
que para combinar dos o más tablas hay que poner como condición la igualdad
entre las claves de una tabla y el enlace de la otra.

Las condiciones dentro del WHERE que sirven para hacer el enlace entre
tablas se denominan JOIN (unión, enlace). Nota: en el ejemplo utilizado hemos
omitido por simplicidad la columna C_PAIS que también forma parte de la
clave, así que el join debería hacerse con las columnas C_PAIS y C_CLIENTE.
Existe un caso especial cuando se establece un "join" entre tablas: el outer-join.
Este caso se da cuando los valores de los campos enlazados en alguna de las
tablas, contiene el valor NULL.

Al realizar un join, si algún campo enlazado contiene el valor NULL, es registro


quedará automáticamente excluído, ya que una condición en la que un
operando sea NULL siempre se evalúa como falso.

Supongamos que las tablas utilizadas en el ejemplo anterior ahora tienen los
siguientes datos:

FACTURA CLIENTE
Referencia C_ClienteC_ClienteD_Cliente
A111 1 1 Pepote
A112 NULL 2 Juancito
A113 1 5 Toñete
A114 NULL
A115 7

Si realizamos la misma consulta (las facturas con la descripción de cliente), no


aparecerán las facturas "A112" y "A114", ya que su campo C_CLIENTE
contiene un NULL, y al evaluar la condición de join (WHERE
FACTURA.C_CLIENTE = CLIENTE.C_CLIENTE), no se evaluará como
verdadero.

Además, tampoco aparecerá la factura "A115", porque el cliente "7" no existe


en la tabla de clientes. Sin embargo, puedes ser que necesitemos mostrar
todas las facturas de la base de datos, independientemente de si el cliente
existe o si el campo está a NULL. Para ello debemos utilizar un outer-join, que
no es más que un JOIN con un modificador (+), indicando que queremos
considerar aquellos registros que se descarten por existencia de nulos.
El select final sería así
SELECT F.REFERENCIA, F.C_CLIENTE, C.C_CLIENTE, C.D_CLIENTE
FROM FACTURA F, CLIENTE C
WHERE F.C_CLIENTE = C.C_CLIENTE(+);
El resultado de ejecutar este select es:
F.REFERENCIA F.C_CLIENTE C.C_CLIENTE C.D_CLIENTE
A111 1 1 Pepote
A113 1 1 Pepote
A115 2 7 NULL
A112 NULL NULLNULL
A114 NULL NULLNULL

Esta consulta podría leerse con el siguiente enunciado:


"Selecionar las facturas que tengan cliente (el join) y aquellas que no
encuentren su referencia en la tabla cliente (en outer-join)".
Es importante fijarse en la posición en que se ha colocado el modificador (+). Si
se sitúa detrás del campo de la tabla cliente, significa que se recuperen las
todas las facturas, aunque no encuentren referencia al cliente, sin embargo, si
lo ponemos detrás del campo de la tabla factura:

SELECT F.REFERENCIA, F.C_CLIENTE, C.C_CLIENTE, C.D_CLIENTE


FROM FACTURA F, CLIENTE C
WHERE F.C_CLIENTE(+) = C.C_CLIENTE;
Significaría que recupere todos los clientes, aunque no encuentre la referencia
de la factura. Sólo queda por comentar que si en join entre las tablas es de
varios campos, debe indicarse el símbolo del outer (+) en todos los campos, y
en la misma posición en todos ellos.

Pseudocolumnas
Una pseudocolumna es una columna válida para poner en cualquier cláusula
SELECT, independientemente de las tablas incluidas en la clausula FROM.

Las pseudocolumnas válidas para Oracle8 son:


· CURRVAL y NEXTVAL: sólo válidas si el objeto del FROM es una secuencia.
Permiten recuperar el valor actual y siguiente (respectivamente) de una
secuencia. Para más información sobre las secuencias ir a al apartado
CREATE SEQUENCE.
· LEVEL: Retorna el nivel para consultas jerárquicas. Las consultas jerárquicas
se realizan utilizando las cláusulas START WITH y CONNECT BY de la
sentencia SELECT. Para más información sobre consultas jerárquicas, dirigirse
a la ayuda se la sentencia SELECT en el Oracle8 SQL Reference.
· ROWID: Retorna una dirección de disco donde se encuentra la fila
seleccionada. Es un valor único para cada fila de la base de datos.
· ROWNUM: Es un valor consecutivo para cada fila retornada por una consulta.
La primera fila tendrá un 1, la segunda un 2, etc.

Se suele utilizar para restringir el tamaño del result set, por ejemplo, si
queremos que sólo retorne las 5 Primeras facturas:

SELECT *
FROM FACTURA
WHERE ROWNUM <= 5;
Hay que tener en cuenta que una consulta de este estilo:
SELECT *
FROM FACTURA
WHRE ROWNUM > 1;

Nunca retornará resultado, porque siempre habrá una fila que sea la primera.
Después de que el WHERE elimine la primera fila, el ROWNUM de todas las
filas restantes de recalculará y volverá a haber otra nueva primera fila. Así se
seguirá aplicando la condición de filtro hasta que no queden filas. Por eso no
retorna ninguna fila.

El valor de ROWNUM se aplica antes de que se ordene el result set (por la


cláusula ORDER BY).
· SYSDATE: Nos retorna un tipo de dato DATE con la fecha y hora del sistema
(según el reloj del servidor de base de datos).
· USER, UID: Nos retorna el nombre e identificador de usuarios de la sesión
activa.

INSERT
La sentencia INSERT nos permite introducir nuevas filas en una tabla de base
de datos.

La sintaxis básica es:


INSERT INTO tabla{( campos )}
VALUES( lista de valores );
Los nombres de los campos detrás del nombre de tabla son opcionales y si no
se ponen se supondrá todos los campos de la tabla en su orden original. Si se
ponen, se podrán indicar cualquier número de columnas en cualquier orden.

La lista de valores es el registro que se insertará en la tabla. Los tipos de datos


deben coincidir con la definición dada en la cláusula INTO o con la definición de
la tabla si omitimos dicha cláusula. Las columnas que no se incluyan en el
INTO, de inicializarán con NULL, (si no se ha definido valor en el DEFAULT).
Existe otra sintaxis que se denomina INSERT masivo:
INSERT INTO tabla{( campos )}
SELECT . . .
Este tipo de INSERT permite introducir un gran número de registros en una
sola sentencia.

Al igual que con el INSERT normal, los tipos de datos del SELECT deben
coincidir con la definición de la cláusula INTO.

Ejemplos:
INSERT INTO FACTURA
VALUES( 'A111', 'Factura nueva', 1, 5, 50000 );
INSERT INTO FACTURA( C_PAIS, REFERENCIA, IMPORTE, C_CLIENTE,
DESCRIPCIPCION )
VALUES( 1, 'A111', 50000, 5, 'Factura nueva' );
INSERT INTO FACTURA( REFERENCIA, IMPORTE )
VALUES( 'A111', 50000 );
INSERT INTO FACTURA( C_PAIS, C_CLIENTE )
SELECT C_PAIS, C_CLIENTE
FROM CLIENTE;
DELETE
La sentencia DELETE nos permite eliminar nuevas filas en una tabla de base
de datos conforme a una condición. Es equivalente al SELECT, pero en vez de
mostrar las filas que cumplan la condición, las elimina.

Su sintaxis es:
DELETE {FROM} tabla
{WHERE condición};
Si se omite la cláusula WHERE se borrarán todas las filas de la tabla. Las
condiciones pueden ser las mismas que las aplicadas en una sentencia
SELECT. En la cláusula FROM no puede haber más de una tabla, por lo que no
es posible hacer joins en un DELETE. Para hacer un "pseudojoin" hay que
utilizar el operador IN comparando los campos clave de la tabla a borrar con el
subselect de la tabla con la que se quiere hacer el join.

Ejemplos:
DELETE FROM FACTURA
WHERE REFERENCIA = 'A111';
DELETE FACTURA;
DELETE FACTURA
WHERE C_PAIS = 1 AND C_CLIENTE = 5;
DELETE FROM FACTURA
WHERE REFERENCIA NOT IN ( SELECT REFERENCIA
FROM FACTURA
WHERE C_CLIENTE = 4 );
DELETE FROM FACTURA
WHERE C_CLIENTE != 4;
DELETE FROM FACTURA
WHERE (C_PAIS,C_CLIENTE) IN ( SELECT C_PAIS, C_CLIENTE
FROM CLIENTE
WHERE D_CLIENTE LIKE '%Fernández%' );
DELETE FROM FACTURA
WHERE (C_PAIS,C_CLIENTE) IN ( SELECT C_PAIS, C_CLIENTE
FROM CLIENTE
WHERE CLIENTE.C_PAIS = FACTURA.C_PAIS AND
CLIENTE.C_CLIENTE = FACTURA.C_CLIENTE AND
D_CLIENTE LIKE '%Fernández%' );

UPDATE
La sentencia UPDATE se encarga de modificar registros ya existentes en una
tabla. Es equivalente a la sentencia DELETE, pero en vez de borrar, actualiza
las columnas indicadas que cumplan la condición impuesta.

Sintaxis:
UPDATE tabla
SET campo = valor,
campo = valor,
...
{WHERE condición};
El valor puede ser tanto un valor discreto (1, 'pepe', '1-jan-2000', etc), un valor
dependiente de otra una columna (IMPORTE*10) o un subselect que retorne un
result set de 1x1 (1 fila y 1 una columna). Si se utiliza un subselect se puede
hacer join entre este subselect y la tabla del UPDATE. Si se omite la cláusula
WHERE, se actualizarán todas las filas de la tabla.

Ejemplos:
UPDATE FACTURA
SET IMPORTE = 1000
WHERE C_PAIS = 1 AND
C_CLIENTE = 5;
UPDATE FACTURA
SET IMPORTE = IMPORTE * 0.5
WHERE C_PAIS = 1 AND
C_CLIENTE = 5;
UPDATE FACTURA F1
SET IMPORTE = ( SELECT AVG(IMPORTE) * 1.10
FROM FACTURA F2
WHERE F1.C_PAIS = F2.C_PAIS AND
F1.C_CLIENTE = F2.C_CLIENTE );
UPDATE FACTURA F1
SET IMPORTE = ( SELECT AVG(F2.IMPORTE) + F1.IMPORTE
FROM FACTURA F2
WHERE F1.C_PAIS = F2.C_PAIS AND
F1.C_CLIENTE = F2.C_CLIENTE );

Lenguaje de definición de datos: DDL


El DDL (Data DefinitionLanguage) es el conjunto de sentencias que está
orientadas a la creación, modificación y configuración de objetos en base de
datos.

El DDL es el subconjunto más extenso dentro de SQL así que sólo vamos a
hacer una referencia rápida a algunas sentencias.

CREATE TABLE
Crea una tabla en base de datos.
La sintaxis básica es:
CREATE TABLE nombre_tabla(
COLUMNA TIPO [NOT NULL],
COLUMNA TIPO [NOT NULL],
...
{CONSTRAINT nombre_clave_primaria PRIMARY KEY (columnas_clave)}
{CONSTRAINT nombre_clave_foránea
FOREIGN KEY(columnas_clave) REFERENCES
tabla_detalle( columnas_clave )
{ON DELETE CASCADE} } )
{TABLESPACE tablespace_de_creación}
{STORAGE( INITIAL XX{K|M} NEXT XX{K|M} )}
La creación de la tabla FACTURA definida en la pág. 10 sería la siguiente:
CREATE TABLE FACTURA(
REFERENCIA VARCHAR2(10) NOT NULL,
DESCRIPCION VARCHAR2(50),
C_PAIS NUMBER(3),
C_CLIENTE NUMBER(5),
IMPORTE NUMBER(12),
CONSTRAINT PK_FACTURA PRIMARY KEY( REFERENCIA )
CONSTRAINT FK_CLIENTE(C_PAIS,C_CLIENTE) REFERENCES
CLIENTE( C_PAIS, C_CLIENTE)
ON DELETE CASCADE
TABLESPACE tab_facturas
STORAGE( INITIAL 1M NEXT 500K );
Los campos que van a formar parte de la clave se tienen que definir como NOT
NULL ya que no tiene sentido que éstas columnas carezcan de valor.

Además se crea la clave primaria y la clave foránea que hace referencia a


CLIENTE (como ya dijimos en el apartado de claves foráneas). Con la cláusula
ON DELETE CASCADE hacemos que si se borra un cliente, se borren
automáticamente todas sus facturas.

Si no la incluyésemos, al borrar el cliente, nos daría el siguiente error: ORA-


02292: integrity constraint (FK_CLIENTE) violated - child record found Hay que
tener en cuenta que aunque la clave foránea se crea sobre la tabla FACTURA,
también actúa cuando se hacen operaciones sobre CLIENTE.

Al intentar insertar una factura a un cliente inexistente nos dará el siguiente


error: ORA-02291: integrity constraint (FK_CLIENTE) violated - parent key not
found Se puede encontrar una descripción detallada de todos los errores en el
Oracle8 Error Messages.

CREATE INDEX
Crea un índice sobre una tabla de base de datos. La sintaxis básica es:

CREATE {UNIQUE} INDEX nombre_índice


ON tabla(columnas_indexadas )
{TABLESPACE tab_indices}
{STORAGE( INITIAL XX{K|M} NEXT XX{K|M} )}

La cláusula UNIQUE actúa como si los campos indexados fuesen clave


primaria, es decir, no permite que el conjunto de campos indexados se repita
en la tabla. Ya dijimos que un índice es como una tabla auxiliar que sólo
contiene ciertas columnas de búsqueda. Por eso también es posible (y
recomendable) indicar tanto el tablespace como las cláusula STORAGE para
las características de almacenamiento de disco. Si no se incluyera, se utilizará
el STORAGE indicado en la creación del tablespace sobre el que se crea el
índice.

Así mismo Oracle recomienda que los índices residan en un tablespace


separado al de las tablas. Esto es debido a la siguiente razón: Dos tablespaces
distintos están soportados físicamente por al menos un datafile cada uno. Si
nuestro servidor de base de datos tiene más de un disco duro (algo muy
normal), es posible crear un tablespace con sus datafiles en un disco y otro
tablespace con los datafiles en otro disco.

Esto permite que se puedan hacer lecturas de disco simultáneamente sobre


dos disco físicos, ya que cada disco tiene su propio bus de datos. Al meter los
índices en un disco físico y los datos en otro, se facilita que se puedan hacer
lecturas simultaneas. Este proceso (de poner los índices y datos en discos
separados), se denomina balanceado.

Oracle crea automáticamente un índice cuando se define la clave primaria.


Esto es porque la condición más habitual en una consulta a cualquier tabla es
por los campos de su clave primaria. De esta forma se aceleran la gran
mayoría de las consultas (recordar que un índice actúa del mismo modo que el
de un libro).

Pero pueden darse casos en los que se hagan gran cantidad de consultas por
campos distintos a los de la clave primaria. En este caso es necesario crear un
índice por los campos por lo que se accede.

Por ejemplo, puede ser que en nuestra tabla FACTURA sea muy común
recuperar aquellas facturas de un cierto cliente.

En este caso la consulta SELECT ha realizar sería la siguiente:


SELECT *
FROM FACTURA
WHERE C_PAIS = 1 AND
C_CLIENTE = ‘A111’;

En este caso se está accediendo la tabla FACTURA por campos distintos a la


clave primaria (que es Referencia). Si este tipo de consultas son muy
habituales es necesario crear un índice por estos campos:

CREATE INDEX ind_factura_cliente


ON FACTURA( C_PAIS, C_CLIENTE )
TABLESPACE tab_factura_ind
STORAGE( INITIAL 500K NEXT 500K );

No podemos poner la cláusula UNIQUE porque si no, no podríamos insertar


más de una factura por cliente.

CREATE VIEW
Una vista (view) es una consulta SELECT almacenada en base de datos con
un cierto nombre.

Si tenemos la siguiente consulta:


SELECT C.D_CLIENTE, SUM( F.IMPORTE )
FROM FACTURA F, CLIENTE C
WHERE F.C_PAIS = C.C_PAIS AND
F.C_CLIENTE = C.C_CLIENTE
GROUP BY F.C_PAIS, F.C_CLIENTE, C.D_CLIENTE;
Si esta consulta se repite es necesaria muchas veces, entonces podemos
guardar esta definición en base de datos con un nombre (crear una vista), y
después hacer la consulta sobre la vista.

CREATE VIEW TOTAL_FACTURA_CLIENTE AS


SELECT C.D_CLIENTE, SUM( F.IMPORTE )
FROM FACTURA F, CLIENTE C
WHERE F.C_PAIS = C.C_PAIS AND
F.C_CLIENTE = C.C_CLIENTE
GROUP BY F.C_PAIS, F.C_CLIENTE, C.D_CLIENTE;
Y después hacer la consulta sobre la vista:
SELECT *
FROM TOTAL_FACTURA_CLIENTE;
La sintaxis de creación de vista es:

CREATE {OR REPLACE} {FORCE} VIEW nombre_vista AS Subconsulta;


La cláusula OR REPLACE permite sobrescribir una definición existente con
otra nueva definición.

La cláusula FORCE permite crear una vista aunque las tablas de la


subconsulta no existan.

Ejemplos:
CREATE OR REPLACE FORCE VIEW VISTA_INCORRECTA AS
SELECT * FROM FACTURA_ADICIONAL;
CREATE OR REPLACE VIEW FACTURA_CLIENTE_A111 AS
SELECT * FROM FACTURA
WHERE C_PAIS = 1 AND C_CLIENTE = ‘A111’;

CREATE SYNONYM
Un sinónimo (synonym) es una redefinición de nombre de un objeto en base de
datos. Así al objeto FACTURA podemos crearle un sinónimo y entonces se
podrá acceder a él tanto con el nombre de FACTURA como con el nombre del
sinónimo.

Sintaxis:
CREATE {PUBLIC} SYNONYM nombre_sinónimo FOR {usuario.}objeto;
La cláusula PUBLIC permite que todos los usuarios de base de datos puedan
acceder al sinónimo creado. Para más información sobre los usuario de base
de datos ir a la sección Administración básica y seguridad en Oracle.

Ejemplos:
CREATE SYNONYM FACTURAS
FOR FACTURA;
CREATE SYNONYM FACTURA_SCOTT
FOR SCOTT.FACTURA;
CREATE PUBLIC SYNONYM BILL
FOR FACTURA;

CREATE SEQUENCE
Una secuencia (sequence) es un objeto de base de datos que genera números
secuenciales. Se suele utilizar para asignar valores a campos autonuméricos.
En realidad una secuencia no es más que una tabla con una columna numérica
en la que se almacena un valor. Cada vez que se consulta la secuencia se
incrementa el número para la siguiente consulta.

Sintaxis:
CREATE SEQUENCE nombre_secuencia
{START WITH entero}
{INCREMENT BY entero}
{MAXVALUE entero | NOMAXVALUE}
{MINVALUE entero | NOMINVALUE }
{CYCLE | NOCYCLE};

· La cláusula START WITH define el valor desde el que empezará la


generación de números. Si no se incluye, se empezará a partir de MINVALUE.
· La cláusula INCREMENT BY indica la diferencia que habrá entre un número y
el siguiente. Puede ser cualquier número entero (positivo o negativo) distinto de
0.
· La cláusula MAXVALUE indica el valor máximo que podrá alcanzar la
secuencia. Se podrá incluir la cláusula

NOMAXVALUE para no definir máximo de 1027.


· La cláusula MINVALUE indica el valor mínimo de la secuencia. Se podrá
incluir la cláusula NOMINVALUE para definir un mínimo de –1026.

La cláusula CYCLE permite que se empiece a contar en MINVALUE cuando se


llegue a MAXVALUE. Por defecto las secuencias se crean NOCYCLE.

Ejemplos:
CREATE SEQUENCE REF_FACTURA
START WITH 1
INCREMENT BY 1
MAXVALUE 999999
MINVALUE 1;
CREATE SEQUENCE COD_CLIENTE
INCREMENT BY 10;
CREATE SEQUENCE COD_PAIS
INCREMENT BY 10
CYCLE;

Acceso a secuencias:
Las secuencias al ser tablas se acceden a través de consultas SELECT. La
única diferencia es que se utilizan pseudocolumnas para recuperar tanto el
valor actual como el siguiente de la secuencia. Al ser pseudocolumnas se
puede incluir en el FROM cualquier tabla o bien la tabla DUAL.
Nombre_secuencia.CURRVAL: retorna el valor actual de la secuencia.
Nombre_secuencia.NEXTVAL: incrementa la secuencia y retorna el nuevo
valor.

Ejemplos:
SELECT REF_FACTURA.CURRVAL
FROM DUAL;
SELECT COD_CLIENTE.NEXTVAL
FROM DUAL;
SELECT COD_CLIENTE.NEXTVAL, D_CLIENTE
FROM CLIENTE;
UPDATE CLIENTE
SET CODIGO = SECUENCIA_CLIENTE.NEXTVAL;
INSERT INTO CLIENTE
VALUES( SECUECIA_CLIENTE.NEXTVAL, ‘Juancito Pérez Pí’ );

CREATE TABLESPACE
Ya hemos visto el concepto de tablespace y su importancia en el acceso a
datos en Oracle. Ahora vamos a ver cómo se crean los tablespaces. La sintaxis
básica es:

CREATE TABLESPACE nombre_tablespace


DATAFILE ‘ruta\fichero_datafile.ext’ SIZE XX{K|M}
{DEFAULT STORAGE( INITIAL XX{K|M} NEXT XX{K|M} )}
{ONLINE | OFFLINE}
{PERMANENT | TEMPORARY};

La cláusula DATAFILE indica la localización del fichero que soportará el


tablespace. Para añadir más datafiles al tablespace lo podremos hacer a través
de la sentencia ALTER TABLESPACE. Cuando indicamos el tamaño a través
de la cláusula SIZE, le estamos diciendo al datafile que reserve cierto espacio
en disco, aunque inicialmente ese espacio esté vacío. Conforme vayamos
creando objetos sobre este tablespace, ese espacio reservado se irá llenando.
La cláusula DEFAULT STORAGE indica qué características de
almacenamiento por defecto se aplicará a los objetos creados sobre el
tablespace. Si no incluimos la cláusula STORAGE en la creación de un objeto
(por ejemplo en el CREATE TABLE), se aplicarán las características definidas
en la creación del tablespace.

El tablespace inicialmente podrá estar en línea o fuera de línea a través de las


cláusulas ONLINE y OFFLINE. Por defecto el tablespace se creará en estado
ONLINE. Para tablespaces temporales se deberá incluir la cláusula
TEMPORARY, para los de datos la cláusula PERMANENT. Por defecto el
tablespace será PERMANENT.

Ejemplo:
CREATE TABLESPACE tab_factura
DATAFILE ‘C:\ORANT\DATABASE\tablespace_facturas.dat’ SIZE 100M
DEFAULT STORATE( INITIAL 100K NEXT 100K )
ONLINE
PERMANENT;
CREATE TABLESPACE tab_temporal
DATAFILE ‘C:\ORANT\DATABASE\tablespace_tmp.ora’ SIZE 50M
OFFLINE
TEMPORARY;
CREATE TABLESPACE tab_indices
DATAFILE ‘C:\ORANT\DATABASE\tab_indices.tab’ SIZE 10M;

SENTENCIAS DROP
Toda sentencia de creación CREATE tiene su equivalente para eliminar el
objeto creado. Todas estas sentencias tienen la misma sintaxis:
DROP tipo_objetoobjeto_a_borrar.

Por ejemplo:
DROP TABLE FACTURA;
DROP SEQUENCE COD_CLIENTE;
DROP SYNONYM BILL;
DROP VIEW TOTAL_FACTURA_CLIENTE;
DROP TABLESPACE tab_indices;
Ciertas sentencias DROP (como DROP TABLE o DROP TABLESPACE) tienen
cláusulas adicionales para ciertas situaciones especiales.

SENTENCIAS ALTER
Al igual que existe una sentencia DROP para cada objeto creado, también
existe una sentencia ALTER para cada objeto de base de datos. Con estos tres
grupos de sentencias se hace la gestión completa de los objeto: creación,
modificación y borrado. La sintaxis básica de las sentencias ALTER es:
ALTER tipo_objetonombre_objeto
Cláusulas específicas de cada tipo de ALTER;
Las cláusulas propias de cada sentencia ALTER son muchas y variadas, por lo
que aquí no se citarán más que ciertos ejemplos

Ejemplos:
ALTER TABLE FACTURA ADD(
NUEVA_COLUMNA VARCHAR2(10) NOT NULL );
ALTER VIEW BILL COMPILE;
ALTER TABLESPACE tab_indicesADD(
DATAFILE ‘C:\ORANT\DATABASE\otro_datafile.ora’ SIZE 5M;
ALTER TABLESPACE tab_indices
RENAME DATAFILE
‘C:\ORANT\DATABASE\nombre.ora’ TO ‘C:\ORANT\DATABASE\
otro_nombre.ora’
ALTER TABLESPACE tab_indices COALESCE;
ALTER SEQUENCE NOCYCLE;

LA SENTENCIA TRUNCATE
La sentencia TRUNCATE pertenece al conjunto de las sentencias DDL, y
permite vaciar todos los registros de una tabla. Aparentemente es equivalente a
hacer un DELETE sin condición, pero en realidad no es igual, ya que DELETE
pertenece al subconjunto de DDL y TRUNCATE al DML. La sintaxis básica es:

TRUNCATE nombre_tabla {DROP|REUSE STORAGE} La cláusula DROP


STORAGE eliminará todas las extents creadas durante la vida de la tabla.

Ejemplos:
TRUNCATE FACTURA DROP STORAGE;
TRUNCATE CLIENTE;

CLÁUSULA STORAGE
Todo objeto que tenga ocupación física en la base de datos, tendrá una
cláusula storage en su sintaxis de creación. El objetivo de esta cláusula es
definir ciertas propiedades de almacenamiento para el objeto creado, como
puede ser tamaño de la extensión inicial, tamaño de las siguientes
extensiones…
Sintaxis:
STORAGE( INITIAL entero{K|M} NEXT entero{K|M}
{MINEXTENTS entero}
{MAXEXTENTS entero|UNLIMITED}
{PCTINCREASE %entero} )
La cláusula INITIAL define el tamaño que tendrá al extensión inicial y NEXT el
tamaño de las siguientes extensiones.
La cláusula MINEXTENTS indica el número mínimo de extensiones para el
objeto, y MAXEXTENTS indica el máximo número de extensiones (puede ser
UNLIMITED, aunque no es aconsejable). PCTINCREASE indica el porcentaje
en que se aumentará el tamaño de un “nextextent”. Para que todas las
extensiones adicionales sean del mismo tamaño se debe indicar 0.

Funciones SQL
Las funciones SQL permiten mostrar columnas calculadas dentro de sentencias
DML (SELECT, INSERT, DELETE y UPDATE).

Funciones de tratamiento numérico


Función Descripción
ABS( n ) Retorna el valor absoluto del parámetro.
CEIL( n ) Retorna el entero mayor del parámetro.
FLOOR( n ) Retorna el entero menor del parámetro.
MOD(m,n ) Retorna el resto de la división m/n
POWER(m,n ) Retorna mn
ROUND( m[,n] ) Retorna m, redondeado a n decimales. Si m se omite es 0.
SIGN( n ) Retorna 1 si n es positivo, -1 si negativo y 0 si es 0.
TRUNC( n[,m] ) Trunca un número a m decimales. Si m se omite es 0.

Funciones de tratamiento alfanumérico


Función Descripción
CHR( n ) Retorna el carácter equivalente al código n en la tabla de conjunto de
caracteres utilizado (ASCII, UNICODE...)
CONCAT( s1, s2 ) Concatena dos cadenas de caracteres. Equivalente al
operador ||
INITCAP( s ) Pasa el mayúscula la primera letra de cada palabra
LOWER( s ) Pasa a minúsculas toda la cadena de caracteres
LPAD( s, n ) Retorna los n primeros caracteres de la cadena s.
RPAD( s, n ) Retorna los n últimos caracteres de la cadena s.
LTRIM( s1[, s2] ) Elimina todas las ocurrencias de s2 en s1 por la izquierda. Si
se omite s2, se eliminarán los espacios.
RTRIM( s1[, s2] ) Elimina todas las ocurrencias de s2 en s1 por la derecha. Si
se omite s2, se eliminarán los espacios.
REPLACE( s1, s2, s3 ) Retorna s1 con cada ocurrencia de s2 reemplazada por
s3.
SUBSTR( s, m, n ) Retorna los n caracteres de s desde la posición m.
UPPER( s ) Pasa a mayúsculas toda la cadena de caracteres
LENGTH( s ) Retorna la longitud (en caracteres) de la cadena pasada.

Funciones de tratamiento de fechas


Función Descripción
ADD_MONTHS( d, n ) Suma un número (positivo o negativo) de meses a una
fecha.
LAST_DAY( d ) Retorna el ultimo día de mes de la fecha pasada.
MONTHS_BETWEEN( d1, d2 ) Retorna la diferencia en meses entre dos
fechas.
ROUND( d, s ) Redondea la fecha d según el formato indicado en s. (*)
TRUNC( d, s ) Trunca la fecha d según el formato indicado en s. (*)
Formatos para ROUND y TRUNC para fechas:
Formato Descripción
‘MONTH’, ‘MON’, ‘MM’ Principio de mes
‘DAY’, ‘DY’, ‘D’ Principio de semana
‘YEAR’, ‘YYYY’, ‘Y’ Principio de año

Funciones de grupo
Estas funciones actúan sobre un conjunto de valores, retornando sólo un
registro.
Función Descripción
SUM( valores ) Retorna la suma.
AVG( valores ) Retorna la media aritmética
MAX( valores ) Retorna el máximo.
MIN( valores ) Retorna el mínimo
COUNT(valores|* ) Retorna la cuenta.
Todas estas funciones permite incluir el modificador DISTINCT delante de la
lista de valores para que omita los repetidos.

Funciones de conversión
Función Descripción
CHARTOROWID( s ) Convierte una cadena en tipo de dato ROWID.
ROWIDTOCHAR(rowid ) Convierte un tipo de dato ROWID en cadena de
caracteres.
TO_CHAR( *[, s] ) Convierte el tipo de dato * en cadena de caracteres. Si * es
una fecha, se podrá utilizar la cadena s como formato de conversión.
TO_DATE( s1[, s2] ) Convierte la cadena s1 en fecha, conforme al formato de
convesión s2.
TO_NUMBER( s ) Convierte una cadena de caracteres en valor numérico.
§ Otras funciones
Función Descripción
DUMP( columna ) Retorna información de almacenamiento para la columna
indicada.
GREATEST( expr1, expr2,
... exprN )
Retorna la expresión mayor.
LEAST( expr1, expr2, ...
exprN )
Retorna la expresión menor.
NVL( expr1, expr2 ) Retorna expr2 si expr1 es NULL, sino retorna expr1.
USEREVN( s ) Retorna opciones de entorno de la sesión activa:
Los valores para s pueden ser:
· ‘ISDBA’: Retorna ‘TRUE’ si el usuario activo tiene el rol DBA.
· ‘LANGUAGE’: Idioma activo.
· ‘TERMINAL’: Nombre de terminal donde se realiza la consulta.
· ‘SESSIONID’: Número de sesión activa.
DECODE(expr_ev,
Caso_1, ret_1,
Caso_2, ret_2,
...
Caso_N, ret_N,
Caso_else )
Permite hace una evaluación de valores discretos. Es similar a la
estructuraswitch de C/C++ o case of de Pascal.

Ejemplo:
DECODE( COLOR,
‘R’, ‘Rojo’,
‘V’, ‘Verde’,
‘A’, ‘Azul’,
‘Color desconocido’ )

Control de transacciones
Debido a que en las operaciones normales con la base de datos puede
corromper la información, todas las bases de datos tiene un sistema de control
de transacción.

Se denomina transacción al espacio de tiempo que hay desde que se hace la


primera sentencia DML que no sea SELECT (INSERT, UPDATE, DELETE),
hasta que damos por finalizada la transacción explícitamente (con las
sentencias apropiadas) o implícitamente (terminando la sesión).

Durante la transacción, todas las modificaciones que hagamos sobre base de


datos, no son definitivas, más concretamente, se realizan sobre un tablespace
especial que se denomina tablespace de ROLLBACK, o RBS (RollBack
Segment). Este tablespace tiene reservado un espacio para cada sesión activa
en el servidor, y es en ese espacio donde se almacenan todas las
modificaciones de cada transacción. Una vez que la transacción se ha
finalizado, las modificaciones temporales almacenadas en el RBS, se vuelcan
al tablespace original, donde está almacenada nuestra tabla.
Esto permite que ciertas modificaciones que se realizan en varias sentencias,
se puedan validar todas a la vez, o rechazar todas a la vez.

Las sentencias de finalización de transacción son:


COMMIT: la transacción termina correctamente, se vuelcan los datos al
tablespace original y se vacía el RBS.

ROLLBACK: se rechaza la transacción y el vacía el RBS.


Opcionalmente existe la sentencia SAVEPOINT para establecer puntos de
transacción.

La sintaxis de SAVEPOINT es:


SAVEPOINT nombre_de_punto;
A la hora de hacer un ROLLBACK o un COMMIT se podrá hacer hasta cierto
punto con la sintaxis:

COMMIT TO nombre_de_punto;
ROLLBACK TO nombre_de_punto;
Ejemplo de transacción:
Histórico de sentencias:
SELECT;
SELECT;
SELECT;
UPDATE;
SELECT;
INSERT;
UPDATE;
SELECT;
UPDATE;
COMMIT;
UPDATE;
SELECT;
SAVEPOINT pepe
INSERT;
UPDATE;
SELECT;
UPDATE;
ROLLBACK TO pepe;
UPDATE;
INSERT;
DELETE;
COMMIT TO pepe;
SELECT;
COMMIT
Si nuestro número de sentencias es tan grande que el RBS se llena, Oracle
hará un ROLLBACK, por lo que perderemos todos los datos. Así que es
recomendable hacer COMMIT cada vez que el estado de la base de datos sea
consistente. Si terminamos la sesión con una transacción pendiente, Oracle
consultará el parámetro AUTOCOMMIT, y si éste está a TRUE, se hará
COMMIT, si está FALSE se hará ROLLBACK.

Modelo Entidad Relación E-R


"Modelo de datos basado en una percepción del mundo real que consiste en un
conjunto de objetos básicos llamados entidades y relaciones entre estos
objetos" [Kor98]. Describe los datos en los niveles conceptual y de vista. El
modelo E-R, tiene su implementación grafica en el Diagrama Entidad-Relación.

Componentes y Diagrama E-R


Entidad: Representa un objeto que tiene vida propia en el sistema que se está
modelando, tanto tangible como intangibles. Ejemplo: cliente, producto,
estudiante, vacación.

Conjunto de entidades: Grupo (conjunto) de entidades del mismo tipo. Ejemplo:


Todos los estudiantes de un curso, representan el conjunto de entidades
estudiante.

Relación: Asociación o vinculación entre dos o más entidades. Ejemplo: La


relación comprar entre las entidades cliente y producto. Generalmente
representa acciones entre las entidades.

Conjunto de relaciones: Son relaciones del mismo tipo.


Atributos: Características o propiedades asociadas al conjunto de entidades o
relaciones y que toman valor en una entidad en particular. Ejemplo: nombre,
cédula, teléfono.

Los posibles valores puede tomar un atributo para un conjunto de entidades se


denomina dominio.

Los atributos se pueden clasificar en:


- Simples o atómicos: Son aquellos que no contienen otros atributos
- Compuestos: Son los que incluyen otros atributos simples.. Ejemplo: dirección
(Se puede dividir en calle, número, ciudad).
- Monovalorados o Univalorados: Atributo que toma un solo valor, para una
entidad en particular.
- Multivalorados: Atributo que para una misma entidad puede tomar muchos
valores.
- Derivados o calculados: Son aquellos atributos cuyos valores se pueden
conseguir con operaciones sobre valores de otros atributos.
- Nulos: Son aquellos atributos para los cuales en algún momento no existe o
no se conoce su valor.
Diagrama Entidad - Relación.
Es la representación gráfica del Modelo Entidad-Relación y permite ilustrar la
estructura de la base de datos del negocio modelado.

Escribe Johnson "los diagramas ER constituyen una notación para documentar


un diseño tentativo de bases de datos. Los analistas los utilizan para facilitar el
proceso de diseño"

Está compuesto por los siguientes elementos.

Rectángulo que representa un conjunto de entidades.

Elipse que representa los atributos de cada entidad.

Rombos que representan conjuntos de relaciones.

Estos elementos se unen a través de líneas para formar así el diagrama.

Ejemplo:
Dependiendo del tipo de atributo representan en forma diferente:
- Simples y monovalorados: Se simbolizan con una elipse sencilla .
- Compuestos: Se representan por una elipse de la cual salen otras elipses con
los atributos simples.
- Multivalorados: Se representan con una elipse doble.
- Derivados: Se representan con una elipse punteada.

Otra forma de representar los conjuntos de entidades y sus atributos consiste


mostrar los atributos en forma de lista dentro del rectángulo:

Funciones, procedimientos y paquetes:


Una vez que tenemos escrito un bloque de código, podemos guardarlo en un
fichero .SQL para su posterior uso, o bien guardarlo en base de datos para que
pueda ser ejecutado por cualquier aplicación. A la hora de guardar un bloque
de código hay que tener en cuenta ciertas normas:

 Palabra reservada DECLARE desaparece


 Podremos crear procedimientos y funciones. Los procedimientos
no podrán retornar ningún valor, mientras que las funciones de-
ben retornar un valor de un tipo de dato básico.

Para crear un procedimiento (storedprocedure: procedimiento almacenado)


usaremos la siguiente sintaxis:
CREATE {OR REPLACE} PROCEDURE nombre_proc(tipo_dato param1, tipo
dato_param2... ) IS
<Sección DECLARE>
BEGIN
{EXCEPTION}
END;

Para crear una función usaremos la siguiente sintaxis:


CREATE {OR REPLACE} FUNCTION nombre_func(tipo_dato param1, tipo
dato_param2... )
RETURN tipo_dato IS
<Sección DECLARE>
BEGIN
{EXCEPTION}
END;
Una vez que tenemos creados nuestros procedimientos y funciones podemos
almancenarlos dentro de librerías de funciones. Estas librerías tienen el nombre
de paquetes o packages.

Un paquete puede contener procedimientos, funciones, variables, tipos y


subtipos, en general, cualquier objeto que se pueda declarar dentro de la
sección DECLARE de un bloque de código.

La creación de un paquete pasa por dos fases:


 Crear la cabecera del paquete donde se definen que procedi-
mientos, funciones, variables, etc. Contendrá el paquete.
 Crear el cuerpo del paquete, donde se definen los bloques de có-
digo de las funciones y procedimientos definidos en la cabecera
del paquete.

Para crear la cabecera del paquete utilizaremos la siguiente instrucción:


CREATE {OR REPLACE} PACKAGE nombre_de_paquete IS
< Declaraciones >
END;

Para crear el cuerpo del paquete utilizaremos la siguiente instrucción:


CREATE {OR REPLACE} PACKAGE BODY nombre_paquete IS
< Bloques de código>
END;

Hay que tener en cuenta que toda declaración de función o procedimiento debe
estar dentro del cuerpo del paquete, y que todo bloque de código contenido
dentro del cuerpo debe estar declarado dentro de la cabecera de paquete.
Cuando se quiera acceder a las funciones, procedimientos y variables de un
paquete se debe anteponer el nombre de este:

Nombre_paquete.función(x)
Nombre_paquete.procedimiento(x)
Nombre_paquete.variable
Oracle8 define los siguientes paquetes de funciones predefinidos:
DBMS_ALERT
DBMS_APPLICATION_INFO
DBMS_AQ
DBMS_AQADM
DBMS_DDL
DBMS_DEFER
DBMS_DEFER_QUERY
DBMS_DEFER_SYS
DBMS_DESCRIBE
DBMS_JOB
DBMS_LOB
DBMS_LOCK
DBMS_OUTPUT
DBMS_PIPE
DBMS_REFRESH
DBMS_REPCAT
DBMS_REPCAT_ADMIN
DBMS_REPCAT_AUTH
DBMS_ROWID
DBMS_SESSION
DBMS_SHARED_POOL
DBMS_SNAPSHOT
DBMS_SQL
DBMS_UTILITY
UTL_FILE

Disparadores:
Los disparadores (o triggers) son bloques de código almacenados en base de
datos y que se ejecutan automáticamente. Un disparador está asociado a una
tabla y a una operación DML específica (INSERT, UPDATE o DELETE).

En definitiva, los disparadores son eventos a nivel de tabla que se ejecutan


automáticamente cuando se realizan ciertas operaciones sobre la tabla.

Para crear un disparador utilizaremos la siguiente instrucción:


CREATE {OR REPLACE} TRIGGER nombre_disp
[BEFORE|AFTER|INSTEAD OF] [DELETE|INSERT|UPDATE {OF columnas}]
ON tabla
{DECLARE}
BEGIN
{EXCEPTION}
END;

También podría gustarte