TRABAJANDO CON SQL*PLUS Acceso a SQL*PLUS Creación de

Anuncio
TRABAJANDO CON SQL*PLUS
El objetivo de este tema es simplemente, hacer una revisión de los conceptos avanzados de
SQL, para ello, empezaremos por ver como se accede a SQL*PLUS y como crear usuarios,
para posteriormente, crear las tablas con las que vamos a trabajar y luego mostrar dichos
conceptos avanzados de SQL como son las vistas, índices, clusters, disparadores, …
Acceso a SQL*PLUS
Dentro del grupo de programas del menú inicio Oracle – OraHome90 podemos encontrar
Application Development y dentro de él un enlace a SQL*PLUS. Si no se cambió la clave
durante la instalación, para acceder al sistema podremos usar el superusuario sys cuya clave
es change_on_install.
Si queremos modificar la contraseña de sys, una vez que accedamos al sistema como sys,
escribiremos la sentencia:
ALTER USER sys IDENTIFIED BY <nuevo password>
A continuación debemos crear una cuenta de usuario para que tengamos un acceso restringido
a las propiedades del sistema. Esto lo podemos hacer conectados como sys con las siguientes
sentencias:
CREATE USER <login> IDENTIFIED BY <password> DEFAULT TABLESPACE
USERS TEMPORARY TABLESPACE TEMP QUOTA 4M ON USERS QUOTA 1M ON TEMP;
GRANT CONNECT, RESOURCE TO <login>
Como podemos imaginar, para eliminar un usuario tenemos que escribir.
DROP USER <login>
Creación de las tablas e inserción de datos
Vamos a utilizar el ejemplo de proveedor-pieza-proyecto-ventas para el usuario que hemos
creado anteriormente, las tablas correspondientes son:
create table proveedor(
codpro varchar2(3) not null primary key,
nompro varchar2(30) not null,
status number check(status>=1 and status<=10),
ciudad varchar2(15)
);
create table pieza(
codpie varchar2(3) not null primary key,
nompie varchar2(10) not null,
color varchar2(10),
peso number(5,2) check(peso>0 and peso<=100),
ciudad varchar2(15)
);
1
create table proyecto(
codpj varchar2(3) not null primary key,
nompj varchar2(20) not null,
ciudad varchar2(15)
);
create table ventas(
codpro references proveedor(codpro),
codpie references pieza(codpie),
codpj references proyecto(codpj),
cantidad number(4),
primary key(codpro, codpie, codpj)
);
Si la descripción anterior se encuentra en un archivo de nombre tablas.sql, podremos cargarlo
escribiendo:
@tablas
o bien
start tablas
Tras ejecutar la sentencia anterior, si no hay errores sintácticos, el sistema nos dirá que la tabla
se ha creado correctamente. Si queremos eliminar alguna tabla, escribiremos:
DROP TABLE <nombre de la tabla>
Para ver la estructura de la tabla creada podemos usar:
DESCRIBE <nombre de la tabla>
Si una vez creadas las tablas nos encontramos con el problema de que tenemos que insertar
algún cambio sobre alguna de ellas tendremos que usar la sentencia alter, por ejemplo, vamos
a añadir el campo fecha a la tabla ventas:
alter table ventas add(fecha date default sysdate);
Para insertar datos usamos la sentencia insert:
insert
insert
insert
insert
into
into
into
into
proveedor values('S1','Jose Fernandez',2,'Madrid');
pieza values('P1','Tuerca','Gris',2.5,'Madrid');
proyecto values('J1','Proyecto1','Londres');
ventas values('S1','P1','J2',100,TO DATE('25/12/2000'));
Veamos cuáles son los datos insertados en las tablas:
SQL> select * from proveedor;
COD
--S1
S2
S3
S4
S5
NOMPRO
STATUS CIUDAD
------------------------------ ---------- -------Jose Fernandez
2 Madrid
Manuel Vidal
1 Londres
Luisa Gomez
3 Lisboa
Pedro Sanchez
4 Paris
Maria Reyes
5 Roma
2
SQL> select * from pieza;
COD
--P1
P2
P3
P4
P5
NOMPIE
---------Tuerca
Tornillo
Arandela
Clavo
Alcayata
COLOR
PESO CIUDAD
---------- ---------- -------Gris
2,5 Madrid
Rojo
1,25 Paris
Blanco
3 Londres
Gris
5,5 Lisboa
Blanco
10 Roma
SQL> select * from proyecto;
COD
--J1
J2
J3
J4
NOMPJ
-------------------Proyecto1
Proyecto2
Proyecto3
Proyecto4
CIUDAD
--------------Londres
Londres
Paris
Roma
SQL> select * from ventas;
COD
--S1
S1
S1
S2
S4
S1
S5
S1
S1
S2
S2
S3
S3
S3
S4
S4
S4
S1
S1
S1
COD
--P1
P1
P2
P2
P2
P3
P3
P4
P4
P5
P2
P1
P2
P5
P5
P3
P1
P1
P4
P2
COD
CANTIDAD FECHA
--- ---------- -------J2
100 25/12/00
J3
500 30/01/00
J1
200 02/02/00
J2
15 25/05/00
J3
1700 14/12/00
J1
800 12/01/00
J2
30 10/12/00
J1
10 25/11/00
J3
250 12/05/00
J2
300 10/08/00
J1
4500 25/07/00
J1
90 01/07/00
J1
190 30/05/00
J3
20 26/06/00
J1
15 14/04/00
J1
100 22/09/00
J3
1500 21/08/00
J1
150 28/02/00
J4
290 02/01/00
J4
175 13/12/00
20 filas seleccionadas.
Consultas de ejemplo
1. Encontrar las ventas cuya cantidad esté entre 200 y 1000 inclusive, que pertenezcan al
proveedor de nombre Jose Fernandez y mostrar los resultados ordenados por fecha:
select V.codpro, codpie, codpj, cantidad, fecha
from ventas V, proveedor P
where V.codpro=P.codpro and
P.nompro LIKE 'Jose Fernandez' and
cantidad between 200 and 1000
order by fecha;
3
3. Encontrar los proveedores que hayan hecho al menos dos pedidos:
select codpro
from ventas
group by codpro
having count(codpro)>=2;
4. Encontrar la cantidad total de cada pieza enviada a cada proyecto ordenado
descendentemente por dicho total:
select codpie, codpj, sum(cantidad)
from ventas
group by codpie, codpj
order by sum(cantidad) DESC;
Gestión de vistas
Una vista es una tabla lógica cuya información se deriva de una tabla, de un conjunto de tablas
o bien de otras vistas de la base de datos. Si el contenido de las tablas cambia, este cambio se
ve reflejado en las vistas. A diferencia de una tabla, una vista no contiene ningún dato:
únicamente contiene una consulta SQL. Los datos que se recuperan de esa consulta se
presentan en forma de tabla. En realidad, si nosotros no hemos creado esa vista, podemos
pensar que estamos trabajando directamente con la tabla. Al igual que una tabla, se pueden
insertar, actualizar, borrar y seleccionar los datos de una vista.
¿Por qué usar vistas?:
•
Las vistas pueden proporcionar un nivel adicional de seguridad. Por ejemplo, podemos
tener una tabla de empleados de nuestra empresa y podemos querer usar una vista
para que los jefes de departamento sólo puedan visualizar la información de sus
subordinados.
•
Las vistas permiten ocultar la complejidad de los datos. Una base de datos Oracle está
formada por muchas tablas. Se puede recuperar la información de dos o más tablas
haciendo una combinación, pero esta combinación puede llevar a gran confusión a un
usuario final. Muchas veces tendremos que crear vistas que son combinaciones de
varias tablas, de modo que el usuario final lo verá como una sola tabla.
Para crear una vista en Oracle se utiliza la sentencia create_view. Como ejemplo vamos a
crear una vista que representa el conjunto de piezas de Londres:
create view PiezasLondres as
select codpie,nompie,color,peso from pieza
where pieza.ciudad like 'Londres';
En la cláusula as se especifica la consulta que determina qué filas y columnas de la tabla o
tablas almacenadas forman parte de la vista. A partir de ahora PiezasLondres podrá ser tratada
como una tabla sin serlo en realidad.
Por ejemplo, podemos hacer una consulta del estilo:
SQL> select * from PiezasLondres;
COD NOMPIE
COLOR
PESO
--- ---------- ---------- ---------P3 Arandela
Blanco
3
Pero, ¿cómo modificamos una vista? Se pueden utilizar los comandos delete, insert y update
sólo en determinadas ocasiones. La razón de esto es que, puesto que la tabla no existe como
una entidad física (relación almacenada), para el caso de insertar una nueva tupla, la cuestión
es dónde se colocaría un campo nulo. Por ejemplo, en nuestro ejemplo si hacemos una
inserción del tipo:
4
SQL> insert into PiezasLondres values('P9','Rodamiento', 'Rojo', 90);
1 fila creada.
SQL> select * from PiezasLondres;
COD NOMPIE
COLOR
PESO
--- ---------- ---------- ---------P3 Arandela
Blanco
3
SQL> select * from pieza;
COD
--P1
P2
P3
P4
P5
P9
NOMPIE
---------Tuerca
Tornillo
Arandela
Clavo
Alcayata
Rodamiento
COLOR
PESO CIUDAD
---------- ---------- --------------Gris
2,5 Madrid
Rojo
1,25 Paris
Blanco
3 Londres
Gris
5,5 Lisboa
Blanco
10 Roma
Rojo
90
6 filas seleccionadas.
vamos a tener un problema a la hora de rellenar el campo ciudad de la tabla pieza, ya que por
ningún lado lo hemos definido, con lo que se insertaría null y si volvemos a hacer un select
sobre la vista, no se nos mostrará esta inserción.
Lo que tenemos que hacer para solucionarlo es modificar la vista para insertarle el campo
ciudad en la consulta:
SQL> delete from pieza where codpie='P9';
1 fila suprimida.
SQL> drop view PiezasLondres;
Vista borrada.
SQL> create view PiezasLondres as
2
select codpie,nompie,color,peso,ciudad from pieza
3
where pieza.ciudad like 'Londres';
Vista creada.
SQL> select * from PiezasLondres;
COD NOMPIE
COLOR
PESO CIUDAD
--- ---------- ---------- ---------- --------------P3 Arandela
Blanco
3 Londres
SQL> insert into PiezasLondres values
2
('P9','Rodamiento','Rojo',90,'Londres');
1 fila creada.
SQL> select * from PiezasLondres;
COD
--P3
P9
NOMPIE
---------Arandela
Rodamiento
COLOR
PESO CIUDAD
---------- ---------- --------------Blanco
3 Londres
Rojo
90 Londres
5
SQL> select * from pieza;
COD
--P1
P2
P3
P4
P5
P9
NOMPIE
---------Tuerca
Tornillo
Arandela
Clavo
Alcayata
Rodamiento
COLOR
PESO CIUDAD
---------- ---------- --------------Gris
2,5 Madrid
Rojo
1,25 Paris
Blanco
3 Londres
Gris
5,5 Lisboa
Blanco
10 Roma
Rojo
90 Londres
6 filas seleccionadas.
Índices
Del mismo modo que el índice de un libro ayuda a buscar rápidamente la información, un
índice asociado a una tabla ayuda a recuperar los datos más rápidamente. Si una aplicación se
ejecuta lentamente, un índice adecuadamente situado hará que se ejecute con mayor
velocidad. La ausencia o presencia de un índice asociado a una tabla no influye sobre la
sintaxis de las sentencias SQL para trabajar con la tabla, un índice en Oracle no es más que un
mecanismo para acelerar la velocidad de acceso a la información de una tabla (pensad en las
aplicaciones bancarias si no usasen índices para las tablas de clientes lo que ocurriría).
Aunque los índices agilizan la recuperación de los datos (data retrieval) de los datos de las
tablas, sin embargo, ralentizan las actualizaciones y ocupan espacio en disco, ya que, cuando
se realizan actualizaciones de una tabla de la base de datos, cada uno de los índices basados
en esa tabla necesita también una actualización.
Vemos, por tanto, que un índice es un arma de doble filo, así que se debe realizar un análisis
de para que va a ser utilizada cada tabla antes de asociarle un índice.
NO SE DEBEN CREAR ÍNDICES SOBRE LAS CLAVES PRIMARIAS, ya que cada tabla posee
un índice asociado a la clave primaria y lo único que conseguiríamos es ralentizar el proceso al
tener más de un índice para una clave.
Cuando se crea un índice lo único que tenemos que hacer es pensar que es Oracle el que se
encarga de mantenerlo, nosotros sólo hemos de definirlo.
Para crear un índice utilizamos la sentencia create index, cuya sintaxis es:
CREATE INDEX nombre_del_indice ON tabla(campo [ASC | DESC], ...)
Por ejemplo, si queremos acelerar las consultas cuando busquemos a un proveedor por su
nombre, podemos crear un índice asociado al campo nompro de la tabla proveedor.
create index indice_proveedores on proveedor(nompro);
Cuando se crea una tabla es más eficiente insertar los registros y después crear el registro,
porque si se hace al revés, cada vez que se inserte un registro, se deberá actualizar el índice.
Tenemos la posibilidad de crear también índices compuestos, es decir, un índice que se crea
sobre más de un campo de la tabla. Por ejemplo, supongamos que sobre la tabla proveedor
consultamos habitualmente los campos nompro, status y ciudad. Podríamos entonces crear un
índice como el siguiente, para que cada vez que accedamos al campo nompro, a los campos
nompro y status o a los campos nompro, status y ciudad haya un incremento de velocidad.
create index index_proveedor on proveedor(nompro,status,ciudad);
6
Si embargo, no se producirá una mejora si la consulta se refiere a status o a ciudad
individualmente o a nompro y ciudad, o a status y ciudad. Esto es, siempre se debe consultar
de izquierda a derecha sin dejar ninguno de la izquierda sin referenciar.
Para eliminar un índice podemos tener varias razones:
•
El índice no se necesita más,
•
Por las características de la tabla, el índice no mejora la eficiencia,
•
Necesitamos cambar los campos que se indexan,
•
Necesitamos rehacer un índice muy fragmentado.
La sentencia para eliminarlo es:
DROP INDEX nombre del indice
Se debe tener en cuenta que cuando se borra una tabla, también se borran los índices
asociados a dicha tabla.
Clusters
Un cluster proporciona un método alternativo de almacenar información en las tablas. Un
cluster lo forman un conjunto de tablas que se almacenan en los mismos bloques de datos
porque comparten campos comunes (llave del cluster) y que son frecuentemente accedidas de
forma conjunta. Por ejemplo, las tablas proveedor y ventas comparten el campo codpro. Si se
incluyen las dos tablas en el mismo cluster, Oracle físicamente almacena todas las filas de
cada codpro de ambas tablas en los mismos bloques de datos.
Como los clusters almacenan registros relacionados en los mismos bloques, los beneficios son:
se reduce el acceso a disco y se mejora el rendimiento; y la llave del cluster (columnas
comunes entre las tablas del cluster) almacena cada valor una sola vez de modo independiente
al número de registros de las tablas que contengan dicho valor.
Después de crear un cluster se pueden crear las tablas que pertenecen al cluster. No
obstante, antes de que se puedan insertar registros en las tablas del cluster es necesario
indexar el cluster.
Dos restricciones sobre los clusters, se deben usar para tablas que se van a consultar mucho y
se van a modificar poco, si no se cumple esto, el cluster resultante tendrá un efecto negativo
sobre el rendimiento porque no aprovechamos las ventajas que nos ofrece. Ejemplo:
SQL> drop table ventas;
Tabla borrada.
SQL> drop table proveedor;
Tabla borrada.
SQL> create cluster cluster_codpro(codpro varchar2(3));
Agrupamiento creado.
SQL> create table proveedor(
2
codpro varchar2(3) not null primary key,
3
nompro varchar2(30) not null,
4
status number check(status>=1 and status<=10),
5
ciudad varchar2(15))
6
cluster cluster_codpro(codpro);
Tabla creada.
7
SQL> create table ventas(
2
codpro varchar2(3) references proveedor(codpro),
3
codpie varchar2(3) references pieza(codpie),
4
codpj varchar2(3) references proyecto(codpj),
5
cantidad number(4),
6
primary key(codpro, codpie, codpj))
7
cluster cluster_codpro(codpro);
Tabla creada.
SQL> create index indice_cluster on cluster cluster_codpro;
Índice creado.
Para eliminar un cluster tenemos que usar drop cluster. Cuando se borra un cluster, se borra
también el índice asociado a él. La sintaxis es:
DROP CLUSTER nombre_del_cluster
[INCLUDING TABLES [CASCADE CONSTRAINTS]];
Si un cluster contiene tablas no podrá ser eliminado a menos que se eliminen antes las tablas o
que se incluyan en la sentencia de eliminanción INCLUDING TABLES.
El cluster no podrá ser eliminador si las tablas contienen campos que son referencados por
llaves externas. Solucionable con CASCADE CONSTRAINTS.
Podemos eliminar las tablas del cluster sin afectar al cluster. También podemos eliminar el
índice, pero no podremos acceder a la información contenida en las tablas del cluster hasta
que se reconstruya el índice.
8
Descargar