Documento ORACLE
Documento ORACLE
Manizales
2012
Oracle
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".
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.
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.
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:
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.
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.
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];
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;
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.
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;
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 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).
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 :
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.
Dictionary cache: mantiene datos de sus propias tablas y vistas ya que accede
constantemente a ellas al ejecutar cualquier sentencia.
Ejemplo:
CREATE TABLESPACE TS_DATOS
DATAFILE ‘/disco1/fichero1’ SIZE 100M,
DATAFILE ‘/disco2/fichero2’ SIZE 250M;
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.
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.
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.
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);
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.
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 );
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.
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.
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.
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.
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
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).
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).
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.
Alfanumérico Numérico
'50' 50
'41' 41
'21' 21
'1' 1
'5' 5
'20' 20
'100' 100
'13' 13
'10' 10
'2' 2
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
Alfanumérico Numérico
'001' 1
'002' 2
'005' 5
'010' 10
'013' 13
'020' 20
'021' 21
'041' 41
'050' 50
'100' 100
Por ejemplo, se podría definir la siguiente regla para almacenar las referencias
de las facturas:
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.
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.
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).
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.
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
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.
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
Podemos ver como el espacio que realmente se ocupa dentro del datafile es el
segment y que cada segment pertenece a un objeto.
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)
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.
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.
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.
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.
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.
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:
<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.
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'
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.
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.
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.
· 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.
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.
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.
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.
Entonces del result set anterior, sólo nos interesan los registros marcados en
negrita, y el select que nos retorna ese resultados es:
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.
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
Pseudocolumnas
Una pseudocolumna es una columna válida para poner en cualquier cláusula
SELECT, independientemente de las tablas incluidas en la clausula FROM.
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.
INSERT
La sentencia INSERT nos permite introducir nuevas filas en una tabla de base
de datos.
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 );
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.
CREATE INDEX
Crea un índice sobre una tabla de base de datos. La sintaxis básica es:
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.
CREATE VIEW
Una vista (view) es una consulta SELECT almacenada en base de datos con
un cierto nombre.
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};
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:
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:
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 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.
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.
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.
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).