Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Oracle SQL
Oracle SQL
Oracle SQL
Manual de referencia
Este trabajo est protegido bajo una licencia de Creative Commons del tipo Attribution-NonCommercial-ShareAlike. Para ver una copia de esta licencia visite: http://creativecommons.org/licenses/by-nc-sa/2.0/ o enve una carta a: Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Los contenidos de este documento estn protegidos bajo una licencia de Creative Commons del tipo Attribution-Noncomercial-Share Alike. Con esta licencia: Eres libre de:
Noncommercial (No comercial). No puedes utilizar este trabajo con propsitos comerciales.
Share Alike (Compartir igual). Si modificas, alteras o construyes nuevos trabajos a partir de este, debes distribuir tu trabajo con una licencia idntica a sta
Si estas limitaciones son incompatible con tu objetivo, puedes contactar con el autor para solicitar el permiso correspondiente
No obstante tu derecho a un uso justo y legtimo de la obra, as como derechos no se ven de manera alguna afectados por lo anteriormente expuesto.
Esta nota no es la licencia completa de la obra, sino una traduccin del resumen en formato comprensible del texto legal. La licencia original completa (jurdicamente vlida y pendiente de su traduccin oficial al espaol) est disponible en http://creativecommons.org/licenses/by-ncsa/2.0/legalcode
ndice
ndice.............................................................................................. 5 notas previas.................................................................................. 7 introduccin.................................................................................... 9 Historia del lenguaje SQL..................................................................... 9 estructura del lenguaje SQL................................................................ 12 normas de escritura ........................................................................... 12 tablas ........................................................................................... 13 esquemas de usuario y objetos ........................................................... 13 creacin de tablas ............................................................................. 13 orden DESCRIBE ............................................................................... 14 orden INSERT.................................................................................... 14 consultar las tablas del usuario........................................................... 14 borrar tablas ..................................................................................... 14 tipos de datos ................................................................................... 15 modificar tablas................................................................................. 18 valor por defecto ............................................................................... 19 restricciones ...................................................................................... 19 consultas SELECT .......................................................................... 27 capacidades ..................................................................................... 27 sintaxis sencilla .................................................................................. 27 clculos ............................................................................................ 27 condiciones....................................................................................... 28 ordenacin ....................................................................................... 31 funciones .......................................................................................... 31 obtener datos de mltiples tablas........................................................ 39 agrupaciones .................................................................................... 43 subconsultas ..................................................................................... 46 combinaciones especiales .................................................................. 48 comandos internos en SQL e iSQL*Plus ....................................... 50 variables de sustitucin ...................................................................... 50 comando SET.................................................................................... 51 encabezado y pie de informe.............................................................. 52
5
notas previas
COLUMN .........................................................................................53 BREAK...............................................................................................54 COMPUTE ........................................................................................55 DML .............................................................................................. 59 introduccin ......................................................................................59 insercin de datos ..............................................................................59 actualizacin de registros....................................................................60 borrado de registros ...........................................................................61 comando MERGE ..............................................................................61 transacciones.....................................................................................63 objetos de la base de datos ......................................................... 65 vistas.................................................................................................65 secuencias.........................................................................................67 ndices ..............................................................................................69 sinnimos..........................................................................................70 consultas avanzadas .................................................................... 73 consultas con ROWNUM....................................................................73 consultas sobre estructuras jerrquicas.................................................73 subconsultas avanzadas......................................................................76 consultas de agrupacin avanzada......................................................77
notas previas
En este manual en muchos apartados se indica sintaxis de comandos. Esta sintaxis sirve para aprender a utilizar el comando, e indica la forma de escribir dicho comando en el programa utilizado para escribir SQL. En el presente manual la sintaxis de los comandos se escribe en prrafos sombreados de gris con el reborde en gris oscuro. Ejemplo: SELECT * | {[DISTINCT] columna | expresin [alias], ...} FROM tabla; Otras veces se describen cdigos de ejemplo de un comando. Los ejemplos se escriben tambin con fondo gris, pero sin el reborde. Ejemplo: SELECT nombre FROM cliente; Los ejemplos sirven para escenificar una instruccin concreta, la sintaxis se utiliza para indicar las posibilidades de un comando. Para indicar la sintaxis de un comando se usan smbolos especiales. Los smbolos que utiliza este libro (de acuerdo con la sintaxis que se utiliza normalmente en cualquier documentacin de este tipo) son: PALABRA Cuando en la sintaxis se utiliza una palabra en negrita, significa que es un comando que hay que escribir literalmente. texto El texto que aparece en cursiva sirve para indicar que no hay que escribirle literalmente, sino que se refiere a un tipo de elemento que se puede utilizar en el comando. Ejemplo: SELECT columna FROM tabla; El texto columna hay que cambiarlo por un nombre concreto de columna (nombre, apellidos,...) , al igual que tabla se refiere a un nombre de tabla concreto. [] (corchetes). Los corchetes sirven para encerrar texto que no es obligatorio en el comando, es decir para indicar una parte opcional. | (barra vertical). Este smbolo (|) , la barra vertical, indica opcin, es decir que se puede elegir entre varias opciones ... (puntos suspensivos) Indica que se puede repetir el texto anterior en el comando continuamente (significara, y as sucesivamente) {} (llaves) Las llaves sirven para indicar opciones mutuamente exclusivas pero obligatorias. Es decir, opciones de las que slo se puede elegir una opcin, pero de las que es obligado elegir una. Ejemplo: SELECT { * | columna | expresin } FROM tabla;
notas previas El ejemplo anterior indicara que se debe elegir obligatoriamente el asterisco o un nombre de columna o una expresin. Si las llaves del ejemplo fueran corchetes, entonces indicaran que incluso podra no aparecer ninguna opcin.
introduccin
Historia del lenguaje SQL
El nacimiento del lenguaje SQL data de 1970 cuando E. F. Codd publica su libro: "Un modelo de datos relacional para grandes bancos de datos compartidos". Ese libro dictara las direcrices de las bases de datos relacionales. Apenas dos aos despus IBM (para quien trabajaba Codd) utiliza las directrices de Codd para crear el Standard English Query Language (Lenguaje Estndar Ingls para Consultas) al que se le llam SEQUEL. Ms adelante se le asignaron las siglas SQL (aunque en ingls se siguen pronunciando SEQUEL, en espaol se le llama esecuele). Poco despus se converta en un estndar en el mundo de las bases de datos avalando por los organismos ISO y ANSI. An hoy sigue siendo uno de los estndares ms importantes de la industria informtica. Actualmente el ltimo estndar es el SQL del ao 1999 que ampli el anterior estndar conocido como SQL 92. El SQL de Oracle es compatible con el SQL del ao 1999 e incluye casi todo lo dictado por dicho estndar.
SQL*Plus
Para poder escribir sentencias SQL al servidor Oracle, ste incorpora la herramienta SQL*Plus. Toda instruccin SQL que el usuario escribe, es verificada por este programa. Si la instruccin es vlida es enviada a Oracle, el cual enviar de regreso la respuesta a la instruccin; respuesta que puede ser transformada por el programa SQL*Plus para modificar su salida. Para que el programa SQL*Plus funcione en el cliente, el ordenador cliente debe haber sido configurado para poder acceder al servidor Oracle. En cualquier caso al acceder a Oracle con este programa siempre preguntar por el nombre de usuario y contrasea. Estos son datos que tienen que nos tiene que proporcionar el administrador (DBA) de la base de datos Oracle. Para conectar mediante SQL*Plus podemos ir a la lnea de comandos y escribir el texto sqlplus. A continuacin aparecer la pantalla:
tablas En esa pantalla se nos pregunta el nombre de usuario y contrasea para acceder a la base de datos (informacin que deber indicarnos el administrador o DBA). Tras indicar esa informacin conectaremos con Oracle mediante SQL*Plus, y veremos aparecer el smbolo: SQL> Tras el cual podremos comenzar a escribir nuestros comandos SQL. Ese smbolo puede cambiar por un smbolo con nmeros 1, 2, 3, etc.; en ese caso se nos indica que la instruccin no ha terminado y la lnea en la que estamos. Otra posibilidad de conexin consiste en llamar al programa SQL*Plus indicando contrasea y base de datos a conectar. El formato es: slplus usuario/contrasea@nombreServicioBaseDeDatos Ejemplo: slplus usr1/miContra@inicial.forempa.net En este caso conectamos con SQL*Plus indicando que somos el usuario usr1 con contrasea miContra y que conectamos a la base de datos inicial de la red forempa.net. El nombre de la base de datos no tiene porque tener ese formato, habr que conocer como es el nombre que representa a la base de datos como servicio de red en la red en la que estamos.
Como en el caso anterior, se nos solicita el nombre de usuario y contrasea. La cadena de Host es el nombre completo de red que recibe la instancia de la base de datos a la que queremos acceder en la red en la que nos encontramos. Tambin podremos llamar a este entorno desde la lnea de comandos utilizando la sintaxis comentada anteriormente. En este caso: slplusw usuario/contrasea@nombreServicioBaseDeDatos 10
Esta forma de llamar al programa permite entrar directamente sin que se nos pregunte por el nombre de usuario y contrasea.
iSQL*Plus
Es un producto ideado desde la versin 9i de Oracle. Permite acceder a las bases de datos Oracle desde un navegador. Para ello necesitamos tener configurado un servidor web Oracle que permita la conexin con la base de datos. Utilizar iSQL*Plus es indicar una direccin web en un navegador, esa direccin es la de la pgina iSQL*Plus de acceso a la base de datos. Desde la pgina de acceso se nos pedir nombre de usuario, contrasea y nombre de la base de datos con la que conectamos (el nombre de la base de datos es el nombre con el que se la conoce en la red). Si la conexin es vlida aparece esta pantalla:
11
tablas En esa pantalla en el apartado Introducir Sentencias, se escribe la sentencia que deseamos enviar. El botn Ejecutar hace que se valide y se enve a Oracle. Se pueden almacenar sentencias SQL usando el botn Examinar y cargar sentencias previamente guardadas mediante Cargar archivos de comandos.
normas de escritura
En SQL no se distingue entre maysculas y minsculas. Da lo mismo como se escriba. El final de una instruccin lo calibra el signo del punto y coma Los comandos SQL (SELECT, INSERT,...) no pueden ser partidos por espacios o saltos de lnea antes de finalizar la instruccin. El intrprete SQL plus indicas Se pueden tabular lneas para facilitar la lectura si fuera necesario Los comentarios en el cdigo SQL comienzan por /* y terminan por */
12
tablas
esquemas de usuario y objetos
Cada usuario de una base de datos posee un esquema. El esquema tiene el mismo nombre que el usuario y sirve para almacenar los objetos de esquema, es decir los objetos que posee el usuario. Esos objetos pueden ser: tablas, vistas, secuencias, ndices, sinnimos e instantneas. Esos objetos son manipulados y creados por los usuarios. En principio slo los administradores y los usuarios propietarios pueden acceder a cada objeto, salvo que se modifiquen los privilegios del objeto para permitir su acceso por parte de otros usuarios.
tablas
orden DESCRIBE
El comando DESCRIBE, permite obtener la estructura de una tabla. Ejemplo: DESCRIBE proveedores; Y aparecern los campos de la tabla proveedores.
orden INSERT
Permite aadir datos a las tablas. Ms adelante se comenta de forma ms detallada. Su sintaxis bsica es: INSERT INTO tabla [(columna1 [, columna2...])] VALUES (valor1 [,valor2]); Indicando la tabla se aaden los datos que se especifiquen tras el apartado values en un nuevo registro. Los valores deben corresponderse con el orden de las columnas. Si no es as se puede indicar tras el nombre de la tabla y entre parntesis. Ejemplo: INSERT INTO proveedores(nombre, CIF) VALUES (Araja SA,14244223Y);
borrar tablas
La orden DROP TABLE seguida del nombre de una tabla, permite eliminar la tabla en cuestin. Al borrar una tabla: Desaparecen todos los datos Cualquier vista y sinnimo referente a la tabla seguirn existiendo, pero ya no funcionarn (conviene eliminarlos) Las transacciones pendientes son aceptadas (COMMIT) Slo es posible realizar esta operacin si se es el propietario de la tabla o se posee el privilegio DROP ANY TABLE El borrado de una tabla es irreversible, y no hay ninguna peticin de confirmacin, por lo que conviene ser muy cuidadoso con esta operacin.
14
NVARCHAR2(n)
NUMBER(p,s) NUMBER(38)
NUMBER
LONG
textos
Para los textos disponemos de los siguientes tipos: VARCHAR2. Para textos de longitud variable de hasta 4000 caracteres CHAR. Para textos de longitud fija de hasta 2000 caracteres. NCHAR. Para el almacenamiento de caracteres nacionales de texto fijo NVARCHAR2. Para el almacenamiento de caracteres nacionales de longitud variable. En todos estos tipos se indican los tamaos entre parntesis tras el nombre del tipo. Ese tamao en el caso de los tipos VARCHAR2 es obligatorio, en el caso de los tipos CHAR son opcionales (de no ponerlos se toma el uno).
15
tablas Conviene poner suficiente espacio para almacenar los valores. En el caso de los VARCHAR, Oracle no malgasta espacio por poner ms espacio del deseado ya que si el texto es ms pequeo que el tamao indicado, el resto del espacio se ocupa.
nmeros
El tipo NUMBER es un formato verstil que permite representar todo tipo de nmeros. Su rango recoge nmeros de entre 10-130 y 9,99999999999 * 10128. Fuera de estos rangos Oracle devuelve un error. Los nmeros decimales (nmeros de coma fija) se indican con NUMBER(p,s), donde p es la precisin mxima y s es la escala (nmero de decimales a la derecha de la coma). Por ejemplo, NUMBER (8,3) indica que se representan nmeros de ocho cifras de precisin y tres decimales. Los decimales en Oracle se presenta con el punto y no con la coma. Para nmeros enteros se indica NUMBER(p) donde p es el nmero de dgitos. Eso es equivalente a NUMBER(p,0). Para nmeros de coma flotante (equivalentes a los flota o double de muchos lenguajes de programacin) simplemente se indica el texto NUMBER sin precisin ni escala.
precisin y escala
La cuestin de la precisin y la escala es compleja. Para entenderla mejor, se muestran estos ejemplos: Formato NUMBER NUMBER(9) NUMBER(9,2) NUMBER(7) NUMBER(7,-2) NUMBER(7,2) Nmero escrito por el usuario Se almacena como 345255.345 345255.345 345255.345 345255 345255.345 345255.36 345255.345 Da error de precisin 345255.345 345300 345255.345 Da error de precisin
En definitiva, la precisin debe incluir todos los dgitos del nmero (puede llegar hasta 38 dgitos). La escala slo indica los decimales que se respetarn del nmero, pero si es negativa indica ceros a la izquierda del decimal.
tipo LONG
Se trata de un tipo de datos que actualmente se mantiene por compatibilidad. Se recomienda encarecidamente utilizar en su lugar el tipo CLOB (que se comentar ms adelante). En cualquier caso este tipo permite almacenar textos de hasta 2 GB de tamao. Pero no puede formar clave, ni ndice, ni ser parte de la clusula WHERE, ni GROUP BY, ni SELECT con DISTINCT, ni pueden ser UNIQUE y slo puede haber un campo de este tipo en una misma tabla entre otras limitaciones.
16
fechas y horas
DATE
El tipo DATE permite almacenar fechas. Las fechas se pueden escribir en formato da, mes y ao entre comillas. El separador puede ser una barra de dividir, un guin y casi cualquier smbolo. Para almacenar la fecha actual basta con utilizar la funcin SYSDATE que devuelve esa fecha.
TIMESTAMP
Es una extensin del anterior, almacena valores de da, mes y ao, junto con hora, minuto y segundos (incluso con decimales). Con lo que representa un instante concreto en el tiempo. Un ejemplo de TIMESTAMP sera 2/2/2004 18:34:23,34521. En este caso si el formato de fecha y hora del sistema est pensado para el idioma espaol, el separador decimal ser la coma (y no el punto).
intervalos
Hay unos cuantos tipos de datos en Oracle que sirven para almacenar intervalos de tiempo (no fechas, sino una suma de elementos de tiempo).
RAW
Sirve para almacenar valores binarios de hasta 2000 bytes (se puede especificar el tamao mximo entre parntesis). El valor LONG RAW almacena hasta 2GB.
LOB
Son varios tipos de datos que permiten almacenar valores muy grandes. Ms adelante se comentan en su totalidad. Incluye a BLOB, CLOB, NCLOB y BFILE.
ROWID
Valor hexadecimal que representa la direccin nica de una fila en su tabla.
17
tablas
modificar tablas
La verstil ALTER TABLE permite hacer cambios en la estructura de una tabla.
aadir columnas
ALTER TABLE nombreTabla ADD(nombreColumna TipoDatos [Propiedades] [,columnaSiguiente tipoDatos [propiedades]...) Permite aadir nuevas columnas a la tabla. Se deben indicar su tipo de datos y sus propiedades si es necesario (al estilo de CREATE TABLE). Las nuevas columnas se aaden al final, no se puede indicar otra posicin.
borrar columnas
ALTER TABLE nombreTabla DROP(columna); Elimina la columna indicada de manera irreversible e incluyendo los datos que contena. No se puede eliminar la ltima columna (habr que usar DROP TABLE).
modificar columna
Permite cambiar el tipo de datos y propiedades de una determinada columna. Sintaxis: ALTER TABLE nombreTabla MODIFY(columna tipo [propiedades] [columnaSiguiente tipo [propiedades] ...] Los cambios que se permiten son: Incrementar precisin o anchura de los tipos de datos Slo se puede reducir la anchura si la anchura mxima de un campo si esa columna posee nulos en todos los registros, o todos los valores so o no hay registros 18
Se puede pasar de CHAR a VARCHAR2 y viceversa (si no se modifica la anchura) Se puede pasar de DATE a TIMESTAMP y viceversa
restricciones
Una restriccin es una condicin de obligado cumplimiento para una o ms columnas de la tabla. A cada restriccin se le pone un nombre, en el caso de no poner un nombre (en las que eso sea posible) entonces el propio Oracle le coloca el nombre que es un mnemotcnico con el nombre de tabla, columna y tipo de restriccin. Su sintaxis general es: {CREATE TABLE nombreTabla | ALTER TABLE nombreTabla {ADD | MODIFY}} (campo tipo [propiedades] [,...] CONSTRAINT nombreRestriccin tipoRestriccin (columnas) [,CONSTRAINT nombrerestriccin tipoRestriccin (columnas) ...) 19
tablas Las restricciones tienen un nombre, se puede hacer que sea Oracle el que les ponga nombre, pero entonces ser crptico. Por eso es mejor ponerle uno mismo. Los nombres de restriccin no se pueden repetir para el mismo esquema, por lo que es buena idea incluir de algn modo el nombre de la tabla, los campos involucrados y el tipo de restriccin en el nombre de la misma. Por ejemplo pieza_id_pk podra indicar que el campo id de la tabla pieza tiene una clave principal (PRIMARY KEY).
prohibir nulos
La restriccin NOT NULL permite prohibir los nulos en una determinada tabla. Eso obliga a que la columna tenga que tener obligatoriamente un valor para que sea almacenado el registro. Se puede colocar durante la creacin (o modificacin) del campo aadiendo la palabra NOT NULL tras el tipo: CREATE TABLE cliente(dni VARCHAR2(9) NOT NULL); En ese caso el nombre le coloca Oracle. La otra forma (que admite nombre) es: CREATE TABLE cliente(dni VARCHAR2(9) CONSTRAINT dni_sinnulos NOT NULL(dni));
valores nicos
Las restricciones de tipo UNIQUE obligan a que el contenido de uno o ms campos no puedan repetir valores. Nuevamente hay dos formas de colocar esta restriccin: CREATE TABLE cliente(dni VARCHAR2(9) UNIQUE); En ese caso el nombre de la restriccin la coloca el sistema Oracle. Otra forma es: CREATE TABLE cliente(dni VARCHAR2(9) CONSTRAINT dni_u UNIQUE); Esta forma permite poner un nombre a la restriccin. Si la repeticin de valores se refiere a varios campos, la forma sera: CREATE TABLE alquiler(dni VARCHAR2(9), cod_pelicula NUMBER(5), CONSTRAINT alquiler_uk UNIQUE(dni,cod_pelicula) ; La coma tras la definicin del campo cod_pelicula hace que la restriccin sea independiente de ese campo. Eso obliga a que, tras UNIQUE se indique la lista de campos. Los campos UNIQUE son las claves candidatas de la tabla (que habrn sido detectadas en la fase de diseo de la base de datos).
clave primaria
La clave primaria de una tabla la forman las columnas que indican a cada registro de la misma. La clave primaria hace que los campos que la forman sean NOT NULL (sin posibilidad de quedar vacos) y que los valores de los campos sean de tipo UNIQUE (sin posibilidad de repeticin). Si la clave est formada por un solo campo basta con: 20
CREATE TABLE cliente( dni VARCHAR2(9) PRIMARY KEY, nombre VARCHAR(50)) ; O, poniendo un nombre a la restriccin: CREATE TABLE cliente( dni VARCHAR2(9) CONSTRAINT cliente_pk PRIMARY KEY, nombre VARCHAR(50)) ; Si la clave la forman ms de un campo: CREATE TABLE alquiler(dni VARCHAR2(9), cod_pelicula NUMBER(5), CONSTRAINT alquiler_pk PRIMARY KEY(dni,cod_pelicula) ;
tablas Esta definicin de clave secundario es idntica a la anterior, slo que no hace falta colocar el texto FOREIGN KEY. La integridad referencial es una herramienta imprescindible de las bases de datos relacionales. Pero provoca varios problemas. Por ejemplo, si borramos un registro en la tabla principal que est relacionado con uno o varios de la secundaria ocurrir un error, ya que de permitrsenos borrar el registro ocurrir fallo de integridad (habr claves secundarios refirindose a una clave principal que ya no existe). Por ello Oracle nos ofrece dos soluciones a aadir tras la clusula REFERENCES: ON DELETE SET NULL. Coloca nulos todas las claves secundarias relacionadas con la borrada. ON DELETE CASCADE. Borra todos los registros cuya clave secundaria es igual que la clave del registro borrado. Si no se indica esta clusula, no se permite el borrado de registros relacionados. El otro problema ocurre si se desea cambiar el valor de la clave principal en un registro relacionado con claves secundarias. En muchas bases de datos se implementan soluciones consistentes en aadir ON UPDATE CASCADE o ON UPDATE SET NULL. Oracle no implementa directamente estas soluciones. Por lo que hay que hacerlo de otra forma. Las soluciones son: Implementar un TRIGGER para que cuando se actualice el registro se actualicen las claves secundarias (el mecanismo de funcionamiento es parecido al que se muestra en el siguiente prrafo). Aadir un registro igual que el que se quiere cambiar en la tabla principal, pero con el nuevo valor de la clave. Mediante una instruccin UPDATE actualizar a ese valor de clave todos los registros de la tabla secundaria cuyo valor coincida con la antigua clave. Finalmente borrar el registro en la tabla principal con el valor antiguo de la clave. La sintaxis completa para aadir claves forneas es: CREATE TABLE tabla(lista_de_campos CONSTRAINT nombreRestriccion FOREIGN KEY (listaCampos) REFERENCES tabla(clavePrincipalRelacionada) [ON UPDATE {SET NULL | CASCADE}] ); Si es de un solo campo existe esta alternativa: CREATE TABLE tabla(lista_de_campos tipos propiedades, nombreCampoClaveSecundaria CONSTRAINT nombreRestriccion REFERENCES tabla(clavePrincipalRelacionada) [ON UPDATE {SET NULL | CASCADE}] ); 22
restricciones de validacin
Son restricciones que dictan una condicin que deben cumplir los contenidos de una columna. La expresin de la condicin es cualquier expresin que devuelva verdadero o falso, pero si cumple estas premisas: No puede hacer referencia a nmeros de fila No puede hacer referencia a objetos de SYSTEM o SYS No se permiten usar las funciones SYSDATE, UID, USER y USERENV No se permiten referencias a columnas de otras tablas (si a las de la misma tabla) Una misma columna puede tener mltiples CHECKS en su definicin (se pondran varios CONSTRAINT seguidos, sin comas). Ejemplo: CREATE TABLE ingresos(cod NUMBER(5) PRIMARY KEY, concepto VARCHAR2(40) NOT NULL, importe NUMBER(11,2) CONSTRAINT importe_min CHECK (importe>0) CONSTRAINT importe_max CHECK (importe<8000) ); Para poder hacer referencia a otras columnas hay que construir la restriccin de forma independiente a la columna: CREATE TABLE ingresos(cod NUMBER(5) PRIMARY KEY, concepto VARCHAR2(40) NOT NULL, importe_max NUMBER(11,2), importe NUMBER(11,2), CONSTRAINT importe_maximo CHECK (importe<importe_max) );
aadir restricciones
Es posible querer aadir restricciones tras haber creado la tabla. En ese caso se utiliza la siguiente sintaxis: ALTER TABLE tabla ADD [CONSTRAINT nombre] tipoDeRestriccin(columnas); tipoRestriccin es el texto CHECK, PRIMARY KEY o FOREIGN KEY. Las restricciones NOT NULL deben indicarse mediante ALTER TABLE .. MODIFY colocando NOT NULL en el campo que se modifica.
23
tablas
borrar restricciones
Sintaxis: ALTER TABLE tabla DROP PRIMARY KEY | UNIQUE(campos) | CONSTRAINT nombreRestriccin [CASCADE] La opcin PRIMARY KEY elimina una clave principal (tambin quitar el ndice UNIQUE sobre las campos que formaban la clave. UNIQUE elimina ndices nicos. La opcin CONSTRAINT elimina la restriccin indicada. La opcin CASCADE hace que se eliminen en cascada las restricciones de integridad que dependen de la restriccin eliminada. Por ejemplo en: CREATE TABLE curso( cod_curso CHAR(7) PRIMARY KEY, fecha_inicio DATE, fecha_fin DATE, tItulo VARCHAR2(60), cod_siguientecurso CHAR(7), CONSTRAINT fecha_ck CHECK(fecha_fin>fecha_inicio), CONSTRAINT cod_ste_fk FOREIGN KEY(cod_siguientecurso) REFERENCES curso ON DELETE SET NULL); Tras esa definicin de tabla, esta instruccin: ALTER TABLE curso DROP PRIMARY KEY; Produce este error: ORA-02273: a esta clave nica/primaria hacen referencia algunas claves ajenas Para ello habra que utilizar esta instruccin: ALTER TABLE curso DROP PRIMARY KEY CASCADE; Esa instruccin elimina la clave secundaria antes de eliminar la principal. Tambin produce error esta instruccin: ALTER TABLE curso DROP(fecha_inicio); ERROR en lnea 1: ORA-12991: se hace referencia a la columna en una restriccin de multicolumna
24
El error se debe a que no es posible borrar una columna que forma parte de la definicin de una instruccin. La solucin es utilizar CASCADE CONSTRAINT elimina las restricciones en las que la columna a borrar estaba implicada: ALTER TABLE curso DROP(fecha_inicio) CASCADE CONSTRAINTS; Esta instruccin elimina la restriccin de tipo CHECK en la que apareca la fecha_inicio y as se puede eliminar la columna.
desactivar restricciones
A veces conviene temporalmente desactivar una restriccin para saltarse las reglas que impone. La sintaxis es: ALTER TABLE tabla DISABLE CONSTRAINT nombre [CASCADE] La opcin CASCADE hace que se desactiven tambin las restricciones dependientes de la que se desactiv.
activar restricciones
Anula la desactivacin. Formato: ALTER TABLE tabla ENABLE CONSTRAINT nombre [CASCADE] Slo se permite volver a activar si los valores de la tabla cumplen la restriccin que se activa. Si hubo desactivado en cascada, habr que activar cada restriccin individualmente.
mostrar restricciones
La vista del diccionario de datos USER_CONSTRAINTS permite identificar las restricciones colocadas por el usuario (ALL_CONSTRAINTS permite mostrar las restricciones de todos los usuarios, pero slo est permitida a los administradores). En esa vista aparece toda la informacin que el diccionario de datos posee sobre las restricciones. En ella tenemos las siguientes columnas interesantes:
Columna
OWNER CONSTRAINT_NAME
Tipo de datos
VARCHAR2(20) VARCHAR2(30)
Descripcin
Indica el nombre del usuario propietario de la tabla Nombre de la restriccin
25
tablas
Columna
CONSTRAINT_TYPE
Tipo de datos
VARCHAR2(1)
Descripcin
Tipo de restriccin: C. De tipo CHECK o NOT NULL P. PRIMARY KEY R. FOREIGN KEY U. UNIQUE Nombre de la tabla en la que se encuentra la restriccin
TABLE_NAME
VARCHAR2(30)
En el diccionario de datos hay otra vista que proporciona informacin sobre restricciones, se trata de USER_CONS_COLUMNS, en dicha tabla se muestra informacin sobre las columnas que participan en una restriccin. As si hemos definido una clave primaria formada por los campos uno y dos, en la tabla USER_CONS_COLUMNS aparecern dos entradas, una para el primer campo del ndice y otra para el segundo. Se indicar adems el orden de aparicin en la restriccin. Ejemplo:
OWNER JORGE JORGE JORGE JORGE JORGE JORGE JORGE CONSTRAINT_NAME EXIS_PK EXIS_PK EXIS_PK PIEZA_FK PIEZA_FK PIEZA_PK PIEZA_PK TABLE_NAME EXISTENCIAS EXISTENCIAS EXISTENCIAS EXISTENCIAS EXISTENCIAS PIEZA PIEZA COLUMN_NAME TIPO MODELO N_ALMACEN TIPO MODELO TIPO MODELO POSITION 1 2 3 1 2 1 2
En esta tabla USER_CONS_COLUMNS aparece una restriccin de clave primaria sobre la tabla existencias, esta clave est formada por las columnas (tipo, modelo y n_almacen) y en ese orden. Una segunda restriccin llamada pieza_fk est compuesta por tipo y modelo de la tabla existencias. Finalmente la restriccin pieza_pk est formada por tipo y modelo, columnas de la tabla pieza. Para saber de qu tipo son esas restricciones, habra que acudir a la vista USER_CONSTRAINTS.
26
consultas SELECT
capacidades
Sin duda el comando ms verstil del lenguaje SQL es el comando SELECT. Este comando permite: Obtener datos de ciertas columnas de una tabla (proyeccin) Obtener registros (filas) de una tabla de acuerdo con ciertos criterios (seleccin) Mezclar datos de tablas diferentes (asociacin, join)
sintaxis sencilla
SELECT * | {[DISTINCT] columna | expresin [[AS] alias], ...} FROM tabla; Donde: *. El asterisco significa que se seleccionan todas las columnas DISTINCT. Hace que no se muestren los valores duplicados. columna. Es el nombre de una columna de la tabla que se desea mostrar expresin. Una expresin vlida SQL alias. Es un nombre que se le da a la cabecera de la columna en el resultado de esta instruccin. Ejemplos: /* Seleccin de todos los registros de la tabla clientes */ SELECT * FROM Clientes; /* Seleccin de algunos campos*/ SELECT nombre, apellido1, apellido2 FROM Clientes;
clculos aritmticos
Los operadores + (suma), - (resta), * (multiplicacin) y / (divisin), se pueden utilizar para hacer clculos en las consultas. Cuando se utilizan como expresin en una consulta SELECT, no modifican los datos originales sino que como resultado de la vista generada por SELECT, aparece un nueva columna. Ejemplo: SELECT nombre, precio,precio*1.16 FROM articulos 27
comandos internos SQL e iSQL*Plus Esa consulta obtiene tres columnas. La tercera tendr como nombre la expresin utilizada, para poner un alias basta utilizar dicho alias tras la expresin: SELECT nombre, precio, precio*1.16 AS precio_con_iva FROM articulos; Los nombres pueden llevar espacios si se ponen con comillas dobles: SELECT nombre, precio, precio*1.16 AS "precio con iva" FROM articulos; Esas comillas dobles cumplen otra funcin y es la de hacer que se respeten las maysculas y minsculas del nombre (de otro modo el nombre de la columna aparece siempre en maysculas La prioridad de esos operadores es: tienen ms prioridad la multiplicacin y divisin, despus la suma y la resta. En caso de igualdad de prioridad, se realiza primero la operacin que est ms a la izquierda. Como es lgico se puede evitar cumplir esa prioridad usando parntesis; el interior de los parntesis es lo que se ejecuta primero. Cuando una expresin aritmtica se calcula sobre valores NULL, el resultado de la expresin es siempre NULL.
concatenacin
El operador || es el de la concatenacin. Sirve para unir textos. Ejemplo: SELECT tipo, modelo, tipo || '-' || modelo "Clave Pieza" FROM piezas; El resultado puede ser:
TIPO AR AR AR AR AR AR AR AR BI BI BI BI MODELO 6 7 8 9 12 15 20 21 10 20 38 57 Clave Pieza AR-6 AR-7 AR-8 AR-9 AR-12 AR-15 AR-20 AR-21 BI-10 BI-20 BI-38 BI-57
condiciones
Se pueden realizar consultas que restrinjan los datos de salida de las tablas. Para ello se utiliza la clusula WHERE. Esta clusula permite colocar una condicin que han de cumplir todos los registros, los que no la cumplan no aparecen en el resultado. 28
operadores de comparacin
Se pueden utilizar en la clusula WHERE, son:
Operador
> < >= <= = <> !=
Significado
Mayor que Menor que Mayor o igual que Menor o igual que Igual Distinto Distinto
Se pueden utilizar tanto para comparar nmeros como para comparar textos y fechas. En el caso de los textos, las comparaciones se hacen en orden alfabtico. Slo que es un orden alfabtico estricto. Es decir el orden de los caracteres en la tabla de cdigos. As la letra y las vocales acentuadas nunca quedan bien ordenadas ya que figuran con cdigos ms altos. Las maysculas figuran antes que las minsculas (la letra 'Z' es menor que la 'a').
valores lgicos
Son:
Operador
AND
Significado
Devuelve verdadero si las expresiones a su izquierda y derecha son ambas verdaderas Devuelve verdadero si cualquiera de las dos expresiones a izquierda y derecha del OR, son verdaderas Invierte la lgica de la expresin que est a su derecha. Si era verdadera, mediante NOT pasa a ser falso.
OR
NOT
Ejemplo: /* Obtiene a las personas de entre 25 y 50 aos SELECT nombre,apellidos FROM personas WHERE edad>=25 AND edad<=50; /*Obtiene a la gente de ms de 60 aos o de menos de 20 SELECT nombre,apellidos FROM personas WHERE edad>60 OR edad<20;
29
BETWEEN
El operador BETWEEN nos permite obtener datos que se encuentren en un rango. Uso: SELECT tipo,modelo,precio FROM piezas WHERE precio BETWEEN 3 AND 8; Saca piezas cuyos precios estn entre 3 y 8 (ambos incluidos).
IN
Permite obtener registros cuyos valores estn en una lista: SELECT tipo,modelo,precio FROM piezas WHERE precio IN (3,5, 8); Obtiene piezas cuyos precios sea 3, 5 u 8, slo uno de esos tres.
LIKE
Se usa sobre todo con textos, permite obtener registros cuyo valor en un campo cumpla una condicin textual. LIKE utiliza una cadena que puede contener estos smbolos:
Smbolo
% _ Ejemplos:
Significado
Una serie cualquiera de caracteres Un carcter cualquiera
/* Selecciona nombres que empiecen por S */ SELECT nombre FROM personas WHERE nombre LIKE 'A%'; /*Selecciona las personas cuyo apellido sea Sanchez, Senchez, Stnchez,...*/ SELECT apellido1 FROM Personas WHERE apellido1 LIKE 'S_nchez';
IS NULL
Devuelve verdadero si una expresin contiene un nulo: SELECT nombre,apellidos FROM personas WHERE telefono IS NULL Esa instruccin selecciona a la gente que no tiene telfono
Precedencia de operadores
A veces las expresiones que se producen en los SELECT son muy extensas y es difcil saber que parte de la expresin se evala primero, por ello se indica la siguiente tabla de precedencia: 30
Orden de precedencia
1 2 3 4 5 6 7 8
Operador
*(Multiplicar) / (dividir) + (Suma) - (Resta) || (Concatenacin) Comparaciones (>, <, !=, ...) IS [NOT] NULL, [NOT ]LIKE, IN NOT AND OR
ordenacin
El orden inicial de los registros obtenidos por un SELECT no guarda ms que una relacin respecto al orden en el que fueron introducidos. Para ordenar en base a criterios ms interesantes, se utiliza la clusula ORDER BY. En esa clusula se coloca una lista de campos que indica la forma de ordenar. Se ordena primero por el primer campo de la lista, si hay coincidencias por el segundo, si ah tambin las hay por el tercero, y as sucesivamente. Se puede colocar las palabras ASC O DESC (por defecto se toma ASC). Esas palabras significan en ascendente (de la A a la Z, de los nmeros pequeos a los grandes) o en descendente (de la Z a la a, de los nmeros grandes a los pequeos) respectivamente. Sintaxis completa de SELECT: SELECT expresiones FROM tabla [WHERE condicin] ORDER BY listaDeCamposOAlias;
funciones
Oracle incorpora una serie de instrucciones que permiten realizar clculos avanzados, o bien facilitar la escritura de ciertas expresiones. Todas las funciones reciben datos para poder operar (parmetros) y devuelven un resultado (que depende de los parmetros enviados a la funcin. Los argumentos se pasan entre parntesis: nombreFuncin[(parmetro1[, parmetro2,...])] Si una funcin no precisa parmetros (como SYSDATE) no hace falta colocar los parntesis. Las hay de dos tipos: Funciones que operan con una sola fila Funciones que operan con varias filas. 31
comandos internos SQL e iSQL*Plus Slo veremos las primeras (ms adelante se comentan las de varias filas).
funciones de caracteres
conversin del texto a maysculas y minsculas
Son:
Funcin
LOWER(texto) UPPER(texto) INITCAP(texto)
Descripcin
Convierte el texto a minsculas (funciona con los caracteres espaoles) Convierte el texto a maysculas Coloca la primera letra de cada palabra en maysculas
Descripcin
Elimina los espaciosa la derecha del texto Elimina los espacios a la izquierda que posea el texto Elimina los espacios en blanco a la izquierda y la derecha del texto y los espacios dobles del interior. Elimina del texto los caracteres indicados. Por ejemplo TRIM('h' FROM nombre) elimina las haches de la columna nombre que estn a la izquierda y a la derecha Obtiene los m siguientes caracteres del texto a partir de la posicin n (si m no se indica se cogen desde n hasta el final). Obtiene el tamao del texto Obtiene la posicin en la que se encuentra el texto buscado en el texto inicial. Se puede empezar a buscar a partir de una posicin inicial concreta e incluso indicar el nmero de aparicin del texto buscado. Ejemplo, si buscamos la letra a y ponemos 2 en nAparicin, devuelve la posicin de la segunda letra a del texto). Si no lo encuentra devuelve 0 Buscar el texto a buscar en un determinado texto y lo cambia por el indicado como texto de reemplazo Rellena el texto a la izquierda (LPAD) o a la derecha (RPAD) con el carcter indicado para ocupar la anchura indicada. Si el texto es ms grande que la anchura indicada, 32
Funcin
caracterDeRelleno)
Descripcin
el texto se recorta.
funciones numricas
redondeos Funcin
ROUND(n,decimales)
Descripcin
Redondea el nmero al siguiente nmero con el nmero de decimales indicado ms cercano. ROUND(8.239,2) devuelve 8.3 Los decimales del nmero para que slo aparezca el nmero de decimales indicado Obtiene el entero ms grande o igual que n Entero ms pequeo o igual que n
matemticas Funcin
MOD(n1,n2) POWER(valor,exponente) SQRT(n) SIGN(n) ABS(n) EXP(n) LN(n) LOG(n) SIN(n) COS(n) TAN(n) ACOS(n) ASIN(n) ATAN(n) SINH(n) COSH(n) TANH(n)
Descripcin
Devuelve el resto resultado de dividir n1 entre n2 Eleva el valor al exponente indicado Calcula la raz cuadrada de n Devuelve 1 si n es positivo, cero si vale cero y -1 si es negativo Calcula el valor absoluto de n Calcula en, es decir el exponente en base e del nmero n Logaritmo neperiano de n Logaritmo en base 10 de n Calcula el seno de n (n tiene que estar en radianes) Calcula el coseno de n (n tiene que estar en radianes) Calcula la tangente de n (n tiene que estar en radianes) Devuelve en radianes el arcocoseno de n Devuelve en radianes el arcoseno de n Devuelve en radianes el arcotangente de n Devuelve el seno hiperblico de n Devuelve el coseno hiperblico de n Devuelve la tangente hiperblica de n
otras Funcin
BITAND(n1,n2)
Descripcin
Realiza una operacin AND de bits sobre los valores n1 y n2 que tienen que ser enteros sin 33
Funcin
VSIZE(valor)
Descripcin
signo (el resultado tambin es un entero) Tamao en bytes que gasta Oracle en almacenar ese valor
Funcin
NVL(valor,sustituto) NVL2(valor,sustituto1, sustituto2) NULLIF(valor1,valor2)
Descripcin
Si el valor es NULL, devuelve el valor sustituto; de otro modo, devuelve valor Variante de la anterior, devuelve el valor sustituto1 si valor no es nulo. Si valor es nulo devuelve el sustituto2 Funcin que devuelve nulo si el valor1 y el valor2 sean iguales. En el caso de que no lo sean devuelve el valor1 Devuelve el valor1 si no es nulo; si lo es devuelve el valor2 si no es nulo. Si son nulos el 1 y el 2 devuelve el tres si este no es nulo, y as sucesivamente
COALESCE(valor1,valor2 [,valor3...])
funciones de fecha
Las fechas se utilizan muchsimo en todas las bases de datos. Oracle proporciona dos tipos de datos para manejar fechas, los tipos DATE y TIMESTAMP. En el primer caso se almacena una fecha concreta (que incluso puede contener la hora), en el segundo caso se almacena un instante de tiempo ms concreto que puede incluir incluso fracciones de segundo. Hay que tener en cuenta que a los valores de tipo fecha se les pueden sumar nmeros y se entendera que esta suma es de das. Si tiene decimales entonces se suman das, horas, minutos y segundos. La diferencia entre dos fechas tambin obtiene un nmero de das.
intervalos
Los intervalos son datos relacionados con las fechas en s, pero que no son fechas. Hay dos tipos de intervalos el INTERVAL DAY TO SECOND que sirve para representar das, horas, minutos y segundos; y el INTERVAL YEAR TO MONTH que representa aos y meses. Para los intervalos de ao a mes los valores se pueden indicar de estas formas: /* 123 aos y seis meses */ INTERVAL '123-6' YEAR(4) TO MONTH /* 123 aos */ INTERVAL '123' YEAR(4) TO MONTH /* 6 meses */ INTERVAL '6' MONTH(3) TO MONTH La precisin en el caso de indicar tanto aos como meses, se indica slo en el ao. 34
En intervalos de das a segundos los intervalos se pueden indicar como: /* 4 das 10 horas 12 minutos y 7 con 352 segundos */ INTERVAL '4 10:12:7,352' DAY TO SECOND(3) /* 4 das 10 horas 12 minutos */ INTERVAL '4 10:12' DAY TO MINUTE /* 4 das 10 horas */ INTERVAL '4 10' DAY TO HOUR /* 4 das*/ INTERVAL '4' DAY /*10 horas*/ INTERVAL '10' HOUR /*25 horas*/ INTERVAL '253' HOUR /*12 minutos*/ INTERVAL '12' MINUTE /*30 segundos */ INTERVAL '30' SECOND /*8 horas y 50 minutos */ INTERVAL ('8:50') HOUR TO MINUTE; /*7 minutos 6 segundos*/ INTERVAL ('7:06') MINUTE TO SECOND; /*8 horas 7 minutos 6 segundos*/ INTERVAL ('8:07:06') HOUR TO SECOND; Esos intervalos se pueden sumar a valores de tipo DATE o TIMESTAMP
Descripcin
Obtiene la fecha y hora actuales Obtiene la fecha y hora actuales en formato TIMESTAMP Devuelve la zona horaria actual Obtiene la fecha y hora actuales e incluye la zona horaria Obtiene la fecha y hora actuales en formato TIMESTAMP e incluye la zona horaria
Descripcin
Aade a la fecha el nmero de meses indicado por n MONTHS_BETWEEN(fecha1, Obtiene la diferencia en meses entre las dos fechas (puede ser decimal) fecha2) 35
Funcin
NEXT_DAY(fecha,da)
Descripcin
Indica cual es el da que corresponde a aadir a la fecha el da indicado. El da puede ser el texto 'Lunes', 'Martes', 'Mircoles',... (si la configuracin est en espaol) o el nmero de da de la semana (1=lunes, 2=martes,...) Obtiene el ltimo da del mes al que pertenece la fecha. Devuelve un valor DATE Extrae un valor de una fecha concreta. El valor puede ser day (da), month (mes), year (ao), etc. Devuelve la fecha ms moderna la lista Devuelve la fecha ms antigua la lista Redondea la fecha al valor de aplicar el formato a la fecha. El formato puede ser: 'YEAR' Hace que la fecha refleje el ao completo 'MONTH' Hace que la fecha refleje el mes completo ms cercanoa la fecha 'HH24' Redondea la hora a las 00:00 ms cercanas
LAST_DAY(fecha) EXTRACT(valor FROM fecha) GREATEST(fecha1, fecha2,..) LEAST(fecha1, fecha2,..) ROUND(fecha [,'formato']
TRUNC(fecha [formato])
funciones de conversin
Oracle es capaz de convertir datos automticamente a fin de que la expresin final tenga sentido. En ese sentido son fciles las conversiones de texto a nmero y viceversa. Ejemplo: SELECT 5+'3' FROM DUAL /*El resultado es 8 */ SELECT 5 || '3' FROM DUAL /* El resultado es 53 */ Tambin ocurre eso con la conversin de textos a fechas. De hecho es forma habitual de asignar fechas. Pero en diversas ocasiones querremos realizar conversiones explcitas.
TO_CHAR
Obtiene un texto a partir de un nmero o una fecha. En especial se utiliza con fechas (ya que de nmero a texto se suele utilizar de forma implcita.
fechas
En el caso de las fechas se indica el formato de conversin, que es una cadena que puede incluir estos smbolos (en una cadena de texto):
Smbolo
YY 36
Significado
Ao en formato de dos cifras
Smbolo
YYY YYYY SYYYY MM MON MONTH DY DAY DD Q WW D DDD AD A.D. BC B.C. J RN AM PM HH12 HH24 MI SS SSSS /., Ejemplos:
Significado
ltimas tres cifras del ao Ao en formato de cuatro cifras igual que el anterior, pero si la fecha es anterior al nacimiento de Cristo el ao aparece en negativo Mes en formato de dos cifras Las tres primeras letras del mes Nombre completo del mes Da de la semana en tres letras Da completo de la semana Da en formato de dos cifras Semestre Semana del ao Da de la semana (del 1 al 7) Da del ao Indicador de periodo Anno Domini (despus de Cristo) Indicador de periodo, antes de Cristo. Aparece en fechas anteriores al ao cero (en espaol se pone AC) Ao juliano Mtodo Romano de numeracin Indicador AM Indicador PM Hora de 1 a 12 Hora de 0 a 23 Minutos (0 a 59) Segundos (0 a 59) Segundos desde medianoche Posicin de los separadores
SELECT TO_CHAR(SYSDATE, 'DD/MONTH/YYYY, DAY HH:MI:SS') FROM DUAL /* Sale : 16/AGOSTO /2004, LUNES 08:35:15, por ejemplo
nmeros
Para convertir nmeros a textos se usa est funcin cuando se desean caractersticas especiales. En ese caso en el formato se pueden utilizar estos smbolos:
Smbolo
9
Significado
Posicin del nmero 37
Smbolo
0 S $ L C D G RN rn PR . ,
Significado
Posicin del nmero (muestra ceros) En esa posicin se coloca el signo del nmero (tanto el negativo como el positivo) Formato dlar Smbolo local de la moneda Smbolo internacional de moneda (segn la configuracin local de Oracle) Posicin del smbolo decimal (en espaol, la coma) Posicin del separador de grupo (en espaol el punto) Numeracin romana en maysculas Numeracin romana en minsculas Se muestran los negativos entre smbolos < y > Posicin del decimal Posicin del separador de miles
TO_NUMBER
Convierte textos en nmeros. Se indica el formato de la conversin (utilizando los mismos smbolos que los comentados anteriormente).
TO_DATE
Convierte textos en fechas. Como segundo parmetro se utilizan los cdigos de formato de fechas comentados anteriormente.
funciones condicionales
CASE
Es una instruccin incorporada a la versin 9 de Oracle que permite establecer condiciones de salida (al estilo if-then-else de muchos lenguajes). Sintaxis: CASE expresin WHEN valor1 THEN resultado1 [ WHEN valor2 THEN resultado2 .... ... ELSE resultadoElse ] END El funcionamiento es el siguiente:
1>
38
2> 3>
Se comprueba si esa expresin es igual al valor del primer WHEN, de ser as se devuelve el primer resultado (cualquier valor excepto nulo) Si la expresin no es igual al valor 1, entonces se comprueba si es igual que el segundo. De ser as se escribe el resultado 3. De no ser as se continua con el siguiente WHEN El resultado indicado en la zona ELSE slo se escribe si la expresin no vale ningn valor de los indicados.
4>
Ejemplo: SELECT CASE cotizacion WHEN 1 THEN salario*0.85 WHEN 2 THEN salario * 0.93 WHEN 3 THEN salario * 0.96 ELSE salario END FROM empleados;
funcin DECODE
Similar a la anterior pero en forma de funcin. Se evala una expresin y se colocan a continuacin pares valor, resultado de forma que si se la expresin equivale al valor, se obtiene el resultado indicado. Se puede indicar un ltimo parmetro con el resultado a efectuar en caso de no encontrar ninguno de los valores indicados. Sintaxis: DECODE(expresin, valor1, resultado1 [,valor2, resultado2,...] [,valorPordefecto]) Ejemplo: SELECT DECODE(cotizacion,1, salario*0.85, 2,salario * 0.93, 3,salario * 0.96, salario) FROM empleados; Este ejemplo es idntico al utilizado para la instruccin CASE
comandos internos SQL e iSQL*Plus tablas que se pueden relacionar mediante un campo. Ese campo es el que permite integrar los datos de las tablas. Por ejemplo si disponemos de una tabla de empleados cuya clave es el dni y otra tabla de tareas que se refiere a tareas realizadas por los empleados, es seguro (si el diseo est bien hecho) que en la tabla de tareas aparecer el dni del empleado para saber qu empleado realiz la tarea.
asociando tablas
La forma de realizar correctamente la consulta anterior (asociado las tareas con los empleados que la realizaron sera: SELECT cod_tarea, descripcion_tarea, dni_empleado, nombre_empleado FROM tareas,empleados WHERE tareas.dni_empleado = empleados.dni; Ntese que se utiliza la notacin tabla.columna para evitar la ambigedad, ya que el mismo nombre de campo se puede repetir en ambas tablas. Para evitar repetir continuamente el nombre de la tabla, se puede utilizar un alias de tabla: SELECT a.cod_tarea, a.descripcion_tarea, b.dni_empleado, b.nombre_empleado FROM tareas a,empleados b WHERE a.dni_empleado = b.dni; Al apartado WHERE se le pueden aadir condiciones encadenndolas con el operador AND. Ejemplo: SELECT a.cod_tarea, a.descripcion_tarea FROM tareas a,empleados b WHERE a.dni_empleado = b.dni AND b.nombre_empleado='Javier'; 40
Finalmente indicar que se pueden enlazar ms de dos tablas a travs de sus campos relacionados. Ejemplo: SELECT a.cod_tarea, a.descripcion_tarea, b.nombre_empleado, c.nombre_utensilio FROM tareas a,empleados b, utensilios_utilizados c WHERE a.dni_empleado = b.dni AND a.cod_tarea=c.cod_tarea;
categora D C B A
En el ejemplo anterior podramos averiguar la categora a la que pertenece cada empleado, pero estas tablas poseen una relacin que ya no es de igualdad. La forma sera: SELECT a.empleado, a.sueldo, b.categoria FROM empleados a, categorias b WHERE a.sueldo between b.sueldo_minimo and b.sueldo_maximo;
comandos internos SQL e iSQL*Plus Sintaxis: SELECT tabla1.columna1, tabla1.columna2,.... tabla2.columna1, tabla2.columna2,... FROM tabla1, tabla2 WHERE tabla1.columnaRelacionada(+)=tabla2.columnaRelacionada Eso obtiene los registros relacionados entre las tablas y adems los registros no relacionados de la tabla2. Se podra usar esta otra forma: SELECT tabla1.columna1, tabla1.columna2,.... tabla2.columna1, tabla2.columna2,... FROM tabla1, tabla2 WHERE tabla1.columnaRelacionada=tabla2.columnaRelacionada(+) En ese caso salen los relacionados y los de la primera tabla que no estn relacionados con ninguno de la primera.
CROSS JOIN
Utilizando la opcin CROSS JOIN se realiza un producto cruzado entre las tablas indicadas
NATURAL JOIN
Establece una relacin de igualdad entre las tablas a travs de los campos que tengan el mismo nombre en ambas tablas: SELECT * FROM piezas NATURAL JOIN existencias; 42
En el ejemplo anterior se obtienen los registros de piezas relacionados en existencias a travs de los campos que tengan el mismo nombre en ambas tablas
JOIN USING
Permite establecer relaciones indicando qu campo (o campos) comn a las dos tablas hay que utilizar: SELECT * FROM piezas JOIN existencias USING(tipo,modelo);
JOIN ON
Permite establecer relaciones cuya condicin se establece manualmente, lo que permite realizar asociaciones ms complejas o bien asociaciones cuyos campos en las tablas no tienen el mismo nombre: SELECT * FROM piezas JOIN existencias ON(piezas.tipo=existencias.tipo AND piezas.modelo=existencias.modelo);
relaciones externas
La ltima posibilidad es obtener relaciones laterales o externas (outer join). Para ello se utiliza la sintaxis: SELECT * FROM piezas LEFT OUTER JOIN existencias ON(piezas.tipo=existencias.tipo AND piezas.modelo=existencias.modelo); En este consulta adems de las relacionadas, aparecen las piezas no relacionadas en existencias. Si el LEFT lo cambiamos por un RIGHT, aparecern las existencias no presentes en piezas. La condicin FULL OUTER JOIN producira un resultado en el que aparecen los registros no relacionados de ambas tablas.
agrupaciones
Es muy comn utilizar consultas en las que se desee agrupar los datos a fin de realizar clculos en vertical, es decir calculados a partir de datos de distintos registros. Para ello se utiliza la clusula GROUP BY que permite indicar en base a qu registros se realiza la agrupacin. Con GROUP BY la instruccin SELECT queda de esta forma: SELECT listaDeExpresiones FROM listaDeTablas [JOIN tablasRelacionadasYCondicionesDeRelacin] [WHERE condiciones] [GROUP BY grupos] [HAVING condiciones de grupo] [ORDER BY columnas]; 43
comandos internos SQL e iSQL*Plus En el apartado GROUP BY, se indican las columnas por las que se agrupa. La funcin de este apartado es crear un nico registro por cada valor distinto en las columnas del grupo. Si por ejemplo agrupamos en base a las columnas tipo y modelo en una tabla de existencias, se crear un nico registro por cada tipo y modelo distintos: SELECT tipo,modelo FROM existencias GROUP BY tipo,modelo; Si la tabla de existencias sin agrupar es:
TI AR AR AR AR AR AR AR AR BI BI BI BI BI MODELO 6 6 6 9 9 9 15 20 10 10 38 38 38 N_ALMACEN 1 2 3 1 2 3 1 3 2 3 1 2 3 CANTIDAD 2500 5600 2430 250 4000 678 5667 43 340 23 1100 540
Es decir es un resumen de los datos anteriores. Los datos n_almacen y cantidad no estn disponibles directamente ya que son distintos en los registros del mismo grupo. Slo se pueden utilizar desde funciones (como se ver ahora). Es decir esta consulta es errnea: SELECT tipo,modelo, cantidad FROM existencias GROUP BY tipo,modelo; SELECT tipo,modelo, cantidad *
ERROR en lnea 1: ORA-00979: no es una expresin GROUP BY
44
Funcin
COUNT(*)
Significado
Cuenta los elementos de un grupo. Se utiliza el asterisco para no tener que indicar un nombre de columna concreto, el resultado es el mismo para cualquier columna Suma los valores de la expresin Calcula la media aritmtica sobre la expresin indicada Mnimo valor que toma la expresin indicada Mximo valor que toma la expresin indicada Calcula la desviacin estndar Calcula la varianza
Todos esos valores se calculan para cada elemento del grupo, as la expresin: SELECT tipo,modelo, cantidad, SUM(Cantidad) FROM existencias GROUP BY tipo,modelo; Obtiene este resultado:
TI AR AR AR AR BI BI MODELO 6 9 15 20 10 38 SUM(CANTIDAD) 10530 4928 5667 43 363 1740
condiciones HAVING
A veces se desea restringir el resultado de una expresin agrupada, por ejemplo con: SELECT tipo,modelo, cantidad, SUM(Cantidad) FROM existencias WHERE SUM(Cantidad)>500 GROUP BY tipo,modelo;
45
comandos internos SQL e iSQL*Plus Pero Oracle devolvera este error: WHERE SUM(Cantidad)>500 * ERROR en lnea 3: ORA-00934: funcin de grupo no permitida aqu La razn es que Oracle calcula primero el WHERE y luego los grupos; por lo que esa condicin no la puede realizar al no estar establecidos los grupos. Por ello se utiliza la clusula HAVING, que se efecta una vez realizados los grupos. Se usara de esta forma: SELECT tipo,modelo, cantidad, SUM(Cantidad) FROM existencias GROUP BY tipo,modelo HAVING SUM(Cantidad)>500; Eso no implica que no se pueda usar WHERE. Esta expresin s es vlida: SELECT tipo,modelo, cantidad, SUM(Cantidad) FROM existencias WHERE tipo!='AR' GROUP BY tipo,modelo HAVING SUM(Cantidad)>500; En definitiva, el orden de ejecucin de la consulta marca lo que se puede utilizar con WHERE y lo que se puede utilizar con HAVING: Pasos en la ejecucin de una instruccin de agrupacin por parte del gestor de bases de datos:
Seleccionar las filas deseadas utilizando WHERE. Esta clusula eliminar columnas en base a la condicin indicada Se establecen los grupos indicados en la clusula GROUP BY Se calculan los valores de las funciones de totales (COUNT, SUM, AVG,...) Se filtran los registros que cumplen la clusula HAVING El resultado se ordena en base al apartado ORDER BY.
subconsultas
Se trata de una tcnica que permite utilizar el resultado de una tabla SELECT en otra consulta SELECT. Permite solucionar problemas en los que el mismo dato aparece dos veces.
46
La sintaxis es: SELECT listaExpresiones FROM tabla WHERE expresin operador (SELECT listaExpresiones FROM tabla); Se puede colocar el SELECT dentro de las clusulas WHERE, HAVING o FROM. El operador puede ser >,<,>=,<=,!=, = o IN. Ejemplo: SELECT nombre_empleado, paga FROM empleados WHERE paga < (SELECT paga FROM empleados WHERE nombre_empleado='Martina') ; Lgicamente el resultado de la subconsulta debe incluir el campo que estamos analizando. Se pueden realizar esas subconsultas las veces que haga falta: SELECT nombre_empleado, paga FROM empleados WHERE paga < (SELECT paga FROM empleados WHERE nombre_empleado='Martina') AND paga > (SELECT paga FROM empleados WHERE nombre_empleado='Luis'); La ltima consulta obtiene los empleados cuyas pagas estn entre lo que gana Luis y lo que gana Martina. Una subconsulta que utilice los valores >,<,>=,... tiene que devolver un nico valor, de otro modo ocurre un error. Pero a veces se utilizan consultas del tipo: mostrar el sueldo y nombre de los empleados cuyo sueldo supera al de cualquier empleado del departamento de ventas. La subconsulta necesaria para ese resultado mostrara los sueldos del departamento de ventas. Pero no podremos utilizar un operador de comparacin directamente ya que compararamos un valor con muchos valores. La solucin a esto es utilizar instrucciones especiales entre el operador y la consulta. Esas instrucciones son:
Instruccin
ANY
Significado
Compara con cualquier registro de la consulta. La instruccin es vlida si hay un registro en la subconsulta que permite que la comparacin sea cierta Compara con todos los registros de la consulta. La instruccin resulta cierta si es cierta toda 47
ALL
Instruccin
IN
Significado
comparacin con los registros de la subconsulta No usa comparador, ya que sirve para comprobar si un valor se encuentra en el resultado de la subconsulta Comprueba si un valor no se encuentra en una subconsulta
NOT IN
Ejemplo: SELECT nombre, sueldo FROM empleados WHERE sueldo >= ALL (SELECT sueldo FROM empleados) Esa consulta obtiene el empleado que ms cobra. Otro ejemplo: SELECT nombre FROM empleados WHERE dni IN (SELECT dni FROM directivos) En ese caso se obtienen los nombres de los empleados cuyos dni estn en la tabla de directivos.
intersecciones
De la misma forma, la palabra INTERSECT permite unir dos consultas SELECT de modo que el resultado sern las filas que estn presentes en ambas consultas.
diferencia
Con MINUS tambin se combinan dos consultas SELECT de forma que aparecern los registros del primer SELECT que no estn presentes en el segundo.
48
Se podran hacer varias combinaciones anidadas (una unin cuyo resultado se intersectara con otro SELECT por ejemplo), en ese caso es conveniente utilizar parntesis para indicar qu combinacin se hace primero: (SELECT.... .... UNION SELECT.... ... ) MINUS SELECT.... /* Primero se hace la unin y luego la diferencia*/
49
variables de sustitucin
Se utilizan para poder dar parmetros a una consulta. Por ejemplo si a menudo se realiza un listado de clientes en el que queremos mostrar los datos de un cliente identificado por su DNI, entonces se puede utilizar una variable de sustitucin para el DNI, de modo que cada vez que se ejecute esa consulta se pedir el nuevo valor de la variable.
operador &
La primera forma de utilizar variables de sustitucin es mediante el comando &. Este smbolo utilizado en cualquier parte de la consulta, permite rellenar el contenido de una variable de sustitucin. Por ejemplo: SELECT * FROM Piezas WHERE modelo=&mod; Al ejecutar esa sentencia, desde el cliente SQL*Plus se nos pedir rellenar el valor de la variable mod. Esa variable no se puede volver a usar, si se usa se nos invitar a indicar el valor que la damos. La ventaja de esta tcnica est en que cada vez que ejecutemos podremos dar un valor a la variable, lo que nos permite reutilizar consultas una y otra vez para distintos valores, sin tener que rescribirla. En el caso de que la variable sea de texto, hay que colocar el smbolo & dentro de las comillas que delimitan el texto. Ejemplo: SELECT * FROM Piezas WHERE tipo='&tip'; Es decir se trata de una macro-sustitucin en la que el contenido de la variable se sustituye por su contenido antes de pasar la instruccin a Oracle, de ah que sea necesario colocar las comillas, de otro modo Oracle indicara que la instruccin es errnea.
define
Se pueden utilizar variables de sustitucin que se definan como variables de usuario mediante la operacin DEFINE. La sintaxis de este comando es: DEFINE variable=valor; La variable se sobreentiende que es de tipo texto. El valor es el contenido inicial de la variable. La variable as creada tiene vigencia durante toda la sesin de usuario. Se elimina 50
en el cierre de la sesin o si se usa el comando UNDEFINE indicando el nombre de la variable a eliminar. Para cambiar el valor de la variable se debe utilizar otra vez el comando DEFINE. La ventaja respecto al mtodo anterior est en que la misma variable de sustitucin se puede utilizar para varios SELECT. La desventaja est en que requiere tocar el cdigo para cambiar el valor de la variable. Ejemplo: DEFINE tip='TU'; SELECT * FROM piezas where tipo='&tip'; SELECT * FROM existencias where tipo='&tip'; En el ejemplo, los dos SELECT muestran piezas cuyo tipo sea TU. SQL*Plus no preguntar por el valor de la variable tip.
listar variables
El comand0 DEFINE sin nada ms permite mostrar una lista de todas las variables definidas en ese momento.
operador &&
Se trata de una mezcla entre las anteriores. Cuando en una consulta se utiliza una variable de sustitucin mediante dos smbolos ampersand, entonces al ejecutar la consulta se nos preguntar el valor. Pero luego ya no, la variable queda definida como si se hubiera declarado con DEFINE. El resto de veces que se utilice la variable, se usa con un solo &. El cambio de valor de la variable habr que realizarle con DEFINE.
comando SET
Este comando permite cambiar el valor de las variables de entorno del programa. Su uso es: SET nombreVariable valor las variables ms interesantes a utilizar son:
variable
ECHO TIMING
posibles valores
ON (activado) y OFF (desactivado) ON (activado) y OFF (desactivado)
explicacin
Repite el comando SQL antes de mostrar su resultado Permite mostrar estadsticas sobre el tiempo de ejecucin en cada consulta SQL que se ejecute (interesante para estadsticas) Hace que el encabezado con los alias de las columnas se active o no Activado, trunca un texto si sobrepasa la anchura mxima. Permite indicar la versin con la que se comprueba la compatibilidad de los 51
HEADING
ON (activado) y OFF (desactivado) WRAP ON (activado) y OFF (desactivado) COMPATIBILITY V7, V8, NATIVE
variable
posibles valores
explicacin
comandos. NATIVE indica que el propio servidor Oracle decide la compatibilidad Permite activar y desactivar la posibilidad de usar variables de sustitucin. Permite indicar el carcter utilizado para la sustitucin de variables Indica el nmero de filas que se muestran antes de repetir el encabezado de la consulta Indica la anchura mxima de la lnea de la consulta. Si una lnea de la consulta sobrepasa este valor, los datos pasan a la siguiente. Tambin influye sobre los tamaos y posiciones de los encabezados y pies de los informes Indica qu valor se muestra cuando hay nulos Permite especificar un formato que se aplicar a todos los nmeros. (Vase formato de columnas, ms adelante) Indica la anchura mxima utilizada para mostrar nmeros. Si un nmero sobrepasa esta anchura, es redondeado Hace que se muestren el nmero total de registros de la consulta cuando el resultado supera los n registros. Anchura mxima para los campos de tipo LONG
DEFINE
PAGESIZE LINESIZE
n n
NULL NUMFORMAT
valor formato
NUMWIDTH
valor
FEEDBACK
LONG
SHOW
El comando SHOW seguido de el nombre de uno de los parmetros de la tabla anterior, permite mostrar el estado actual del parmetro indicado. Si se usa SHOW ALL, entonces se muestran todos
Se pueden indicar incluso las tres cosas a la vez: TTITLE LEFT 'informe1' RIGHT 'estudio de clientes'; Se puede tambin usar la palabra COL seguida del nmero de columna en el que se desea el texto: TTITLE COL 50 'informe1'; Tambin se puede indicar la palabra TAB seguida de un nmero que representar tabulaciones, haciendo que SQL*Plus deje ese espacio en encabezado o pie.
COLUMN
Permite especificar un formato de columna. Si se usa sin modificador (slo COLUMNS o su abreviatura COL) se muestran las configuraciones de formato de columnas actualmente en uso. Si se aade el nombre de una columna, se indica el formato actual (si lo hay) para esa columna.
FORMAT
Permite indicar una mscara de formato para el texto. Se usan cdigos especiales para ello.
textos
A los textos se les puede colocar una anchura mxima de columna. Eso se hace con una A seguida del nmero que indica esa anchura. COLUMN tipo FORMAT 'A10'; SELECT tipo, modelo, precio_venta FROM piezas;
nmeros
Se usan cdigos de posicin:
cdigo
9 0
significado
Posicin para un nmero. Si el valor es 0 o vaco, entonces no se muestra nada Posicin para un nmero. Si el valor es 0 o vaco, entonces se muestra 0 53
cdigo
$ MI S PR D G . , L RN rn
significado
Posicin para el signo de dlar Muestra un signo menos tras el nmero, si el nmero es negativo (ejemplo: '999MI') Muestra el signo del nmero (+ -) en la posicin en la que se coloca el signo Muestra los nmeros negativos entre < y > Muestra el signo decimal en esa posicin Muestra el signo de grupo en esa posicin Muestra el punto (separador decimal) Muestra la coma (separador de miles) Muestra el smbolo de moneda nacional en esa posicin Muestra el nmero en romano (maysculas) Muestra el nmero en romano (minsculas)
fechas
Las fechas deben ser formateadas desde la propia instruccin SQL mediante la funcin TO_CHAR (vista en el tema anterior)
LIKE
Permite copia atributos de una columna a otra: COLUMN precio_venta FORMAT '9G990D00L'; COLUMN precio_compra LIKE precio_venta; Las dos columnas tendrn el mismo formato (separador de miles, decimales y moneda tras los dos decimales)
NULL
Indica un texto que sustituir a los valores nulos.
CLEAR
Elimina el formato de la columna Lgicamente se pueden combinar varias acciones a la vez
BREAK
Es uno de los comandos ms poderosos. Permite realizar agrupaciones en las consultas, consiguiendo verdaderos informes (en especial si se combina con COMPUTE). Permite dividir la vista en secciones en base al valor de un campo al que se le pueden incluso quitar los duplicados. El comando: BREAK ON tipo;
54
Hace que las columnas con alias tipo no muestren los duplicados, mostrando una vez cada valor duplicado. Para el buen funcionamiento de la orden, el resultado debe de estar ordenado por esa columna. Se pueden hacer varios grupos a la vez: BREAK ON tipo ON modelo; La orden CLEAR BREAK elimina todos los BREAK anteriormente colocados.
SKIP
A la instruccin anterior se le puede aadir la palabra SKIP seguida de un nmero. Ese nmero indica las lneas que se dejan tras el valor del grupo al imprimir. Si se indica SKIP PAGE, significa que se salta una pgina completa cada vez que cambie el valor del grupo.
ON REPORT
Permite (en unin con COMPUTE) realizar clculos de totales sobre el informe completo.
DUPLICATES y NODUPLICATES
Permiten mostrar o no los duplicados de cada seccin. La opcin inicial es NODUPLICATES.
COMPUTE
Permite en unin con BREAK realizar clculos para las secciones de una consulta. Todo COMPUTE est asociado a un apartado ON de una instruccin BREAL previa. Sintaxis: COM[PUTE] [funcin [LAB[EL] texto] OF columnaOAlias ON {columnaOAlias|REPORT} funcin. Es el nombre de la funcin de clculo que se usa (SUM, AVG, MIN, MAX, NUM (esta es como COUNT) , STD o VAR) LABEL. Permite indicar un texto previo al resultado del clculo, si no se utiliza se pone el nombre de la funcin utilizada. OF. Indica el nombre de columna o alias utilizado en la instruccin SELECT a partir de la que se realiza el clculo ON. Indica el nombre de columna o alias que define la seccin sobre la que se realizar el clculo. Este nombre debe haber sido indicado en un BREAK anterior. REPORT. Indica que el clculo se calcular para toda la consulta.
55
CLEAR BREAK; COLUMN TIPO FORMAT A20; BREAK ON tipo SKIP PAGE ON modelo ON REPORT; COMPUTE SUM LABEL 'Total' MAX LABEL 'Mximo' OF cantidad ON tipo; COMPUTE SUM LABEL 'Total' OF cantidad ON modelo; COMPUTE SUM LABEL 'Total absoluto' OF cantidad ON REPORT; SELECT tipo, modelo, n_almacen, cantidad FROM existencias WHERE tipo='AR' OR tipo='TU' ORDER BY tipo, modelo; Resultado:
TIPO AR MODELO 6 N_ALMACEN 1 2 3 CANTIDAD 2500 5600 2430 ---------10530 250 4000 678 ---------4928 5667 ---------5667 43 ---------43 ---------5667 21168 CANTIDAD 234 43 ---------277 876 ---------876 1023
********** Total 9
1 2 3
********** Total 15 ********** Total 20 ********** Total ******************** Mximo Total TIPO TU
N_ALMACEN 2 3
56
Copyright - Copyleft ' Jorge Snchez 2004 ********** Total 12 ********** Total 16 ********** Total ******************** Mximo Total TIPO Total absoluto ---------1023 234 ---------234 654 ---------654 ---------1023 3064 CANTIDAD ---------24232
MODELO
N_ALMACEN
57
DML
introduccin
Es una de las partes fundamentales del lenguaje SQL. El DML (Data Manipulation Language) lo forman las instrucciones capaces de modificar los datos de las tablas. Al conjunto de instrucciones DML que se ejecutan consecutivamente, se las llama transacciones y se pueden anular todas ellas o aceptar, ya que una instruccin DML no es realmente efectuada hasta que no se acepta (commit). En todas estas consultas, el nico dato devuelto por Oracle es el nmero de registros que se han modificado.
insercin de datos
La adicin de datos a una tabla se realiza mediante la instruccin INSERT. Su sintaxis fundamental es: INSERT INTO tabla [(listaDeCampos)] VALUES (valor1 [,valor2 ...]) La tabla representa la tabla a la que queremos aadir el registro y los valores que siguen a VALUES son los valores que damos a los distintos campos del registro. Si no se especifica la lista de campos, la lista de valores debe seguir el orden de las columnas segn fueron creados (es el orden de columnas segn las devuelve el comando DESCRIBE). La lista de campos a rellenar se indica si no queremos rellenar todos los campos. Los campos no rellenados explcitamente con la orden INSERT, se rellenan con su valor por defecto (DEFAULT) o bien con NULL si no se indic valor alguno. Si algn campo tiene restriccin de tipo NOT NULL, ocurrir un error si no rellenamos el campo con algn valor. Por ejemplo, supongamos que tenemos una tabla de clientes cuyos campos son: dni, nombre, apellido1, apellido2, localidad y direccin; supongamos que ese es el orden de creacin de los campos de esa tabla y que la localidad tiene como valor por defecto Palencia y la direccin no tiene valor por defecto. En ese caso estas dos instrucciones son equivalentes: INSERT INTO clientes VALUES('11111111','Pedro','Gutirrez', 'Crespo',DEFAULT,NULL); INSERT INTO clientes(dni,nombre,apellido1,apellido2) VALUES('11111111','Pedro','Gutirrez', 'Crespo') Son equivalentes puesto que en la segunda instruccin los campos no indicados se rellenan con su valor por defecto y la direccin no tiene valor por defecto. La palabra DEFAULT fuerza a utilizar ese valor por defecto. El uso de los distintos tipos de datos debe de cumplir los requisitos ya comentados en temas anteriores (vase tipos de datos, pgina 15). 59
actualizacin de registros
La modificacin de los datos de los registros lo implementa la instruccin UPDATE. Sintaxis: UPDATE tabla SET columna1=valor1 [,columna2=valor2...] [WHERE condicin] Se modifican las columnas indicadas en el apartado SET con los valores indicados. La clusula WHERE permite especificar qu registros sern modificados. Ejemplos: UPDATE clientes SET provincia='Ourense' WHERE provincia='Orense'; UPDATE productos SET precio=precio*1.16; El primer dato actualiza la provincia de los clientes de Orense para que aparezca como Ourense. El segundo UPDATE incrementa los precios en un 16%. La expresin para el valor puede ser todo lo compleja que se desee: UPDATE partidos SET fecha= NEXT_DAY(SYSDATE,'Martes') WHERE fecha=SYSDATE; 60
Incluso se pueden utilizar subconsultas: UPDATE empleados SET puesto_trabajo=(SELECT puesto_trabajo FROM empleados WHERE id_empleado=12) WHERE seccion=23; Esta consulta coloca a todos los empleados de la seccin 23 el mismo puesto de trabajo que el empleado nmero 12. Este tipo de actualizaciones slo son vlidas si el subselect devuelve un nico valor, que adems debe de ser compatible con la columna que se actualiza. Hay que tener en cuenta que las actualizaciones no pueden saltarse las reglas de integridad que posean las tablas.
borrado de registros
Se realiza mediante la instruccin DELETE: DELETE [FROM] tabla [WHERE condicin] Es ms sencilla que el resto, elimina los registros de la tabla que cumplan la condicin indicada. Ejemplos: DELETE FROM empleados WHERE seccion=23; DELETE FROM empleados WHERE id_empleado IN (SELECT id_empleado FROM errores_graves); Hay que tener en cuenta que el borrado de un registro no puede provocar fallos de integridad y que la opcin de integridad ON DELETE CASCADE (vase pgina 21, clave secundaria o fornea) hace que no slo se borren los registros indicados en el SELECT, sino todos los relacionados.
comando MERGE
Sin duda alguna el comando ms poderoso del lenguaje de manipulacin de Oracle es MERGE. Este comando sirve para actualizar los valores de los registros de una tabla a partir de valores de registros de otra tabla o consulta. Permite pues combinar los datos de dos tablas a fin de actualizar la primera Supongamos que poseemos una tabla en la que queremos realizar una lista de localidades con su respectiva provincia. Las localidades estn ya rellenadas, nos faltan las provincias. Resulta que tenemos otra tabla llamada clientes en la que tenemos datos de localidades y provincias, gracias a esta tabla podremos rellenar los datos que faltan en la otra. La situacin se muestra en la ilustracin siguiente. 61
Clientes
Valores UPDATE (se copiarn a la segunda tabla)
Registros MATCHED
Localidades
La sintaxis del comando MERGE es: MERGE INTO tabla alias USING (instruccin SELECT) alias ON (condicin de unin) WHEN MATCHED THEN UPDATE SET col1=valor1 [col2=valor2] WHEN NOT MATCHED THEN INSERT (listaDeColumnas) VALUES (listaDeValores) MERGE compara los registros de ambas tablas segn la condicin indicada en el apartado ON. Compara cada registro de la tabla con cada registro del SELECT. Los apartados de la sintaxis significan lo siguiente: tabla es el nombre de la tabla que queremos modificar USING. En esa clusula se indica una instruccin SELECT tan compleja como queramos que muestre una tabla que contenga los datos a partir de los cuales se modifica la tabla ON. permite indicar la condicin que permite relacionar los registros de la tabla con los registros de la consulta SELECT 62
WHEN MATCHED THEN. El UPDATE que sigue a esta parte se ejecuta cuando la condicin indicada en el apartado ON sea cierta para los dos registros actuales. WHEN NOT MATCHED THEN. El INSERT que sigue a esta parte se ejecuta para cada registro de la consulta SELECT que no pudo ser relacionado con ningn registro de la tabla. Para el ejemplo descrito antes la instruccin MERGE sera: MERGE INTO localidades l USING (SELECT * FROM clientes) c ON (l.localidad=clientes.localidad) WHEN MATCHED THEN UPDATE SET l.provincia=c.provincia WHEN NOT MATCHED THEN INSERT (localidad, provincia) VALUES (c.localidad, c.provincia) El resultado es la siguiente tabla de localidades: Localidad Villamuriel Cigales Palencia Aranda de Duero Provincia Palencia Valladolid Palencia Burgos
transacciones
Como se ha comentado anteriormente, una transaccin est formada por una serie de instrucciones DML. Una transaccin comienza con la primera instruccin DML que se ejecute y finaliza con alguna de estas circunstancias: Una operacin COMMIT o ROLLBACK Una instruccin DDL (como ALTER TABLE por ejemplo) Una instruccin DCL (como GRANT) El usuario abandona la sesin Cada del sistema Hay que tener en cuenta que cualquier instruccin DDL o DCL da lugar a un COMMIT implcito, es decir todas las instrucciones DML ejecutadas hasta ese instante pasan a ser definitivas.
63
COMMIT
La instruccin COMMIT hace que los cambios realizados por la transaccin sean definitivos, irrevocables. Slo se debe utilizar si estamos de acuerdo con los cambios, conviene asegurarse mucho antes de realizar el COMMIT ya que las instrucciones ejecutadas pueden afectar a miles de registros. Adems el cierre correcto de la sesin da lugar a un COMMIT, aunque siempre conviene ejecutar explcitamente esta instruccin a fin de asegurarnos de lo que hacemos.
ROLLBACK
Esta instruccin regresa a la instruccin anterior al inicio de la transaccin, normalmente el ltimo COMMIT, la ltima instruccin DDL o DCL o al inicio de sesin. Anula definitivamente los cambios, por lo que conviene tambin asegurarse de esta operacin. Un abandono de sesin incorrecto o un problema de comunicacin o de cada del sistema dan lugar a un ROLLBACK implcito.
SAVEPOINT
Esta instruccin permite establecer un punto de ruptura. El problema de la combinacin ROLLBACK/COMMIT es que un COMMIT acepta todo y un ROLLBACK anula todo. SAVEPOINT permite sealar un punto intermedio entre el inicio de la transaccin y la situacin actual. Su sintaxis es: ...instrucciones DML... SAVEPOINT nombre ....instrucciones DML... Para regresar a un punto de ruptura concreto se utiliza ROLLBACK TO SAVEPOINT seguido del nombre dado al punto de ruptura. Cuando se vuelve a un punto marcado, las instrucciones que siguieron a esa marca se anulan definitivamente.
64
creacin de vistas
Sintaxis: CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW vista [(alias[, alias2...]] AS consultaSELECT [WITH CHECK OPTION [CONSTRAINT restriccin]] [WITH READ ONLY [CONSTRAINT restriccin]] OR REPLACE. Si la vista ya exista, la cambia por la actual FORCE. Crea la vista aunque los datos de la consulta SELECT no existan vista. Nombre que se le da a la vista alias. Lista de alias que se establecen para las columnas devueltas por la consulta SELECT en la que se basa esta vista. El nmero de alias debe coincidir con el nmero de columnas devueltas por SELECT. WITH CHECK OPTION. Hace que slo las filas que se muestran en la vista puedan ser aadidas (INSERT) o modificadas (IPDATE). La restriccin que sigue a esta seccin es el nombre que se le da a esta restriccin de tipo CHECK OPTION. 65
objetos de la base de datos WITH READ ONLY. Hace que la vista sea de slo lectura. Permite grabar un nombre para esta restriccin. Lo bueno de las vistas es que tras su creacin se utilizan como si fueran una tabla. Ejemplo: CREATE VIEW resumen /* alias */ (id_localidad, localidad, poblacion, n_provincia, provincia, superficie, capital_provincia, id_comunidad, comunidad, capital_comunidad) AS ( SELECT l.id_localidad, l.nombre, l.poblacion, n_provincia, p.nombre, p.superficie, l2.nombre, id_comunidad, c.nombre, l3.nombre FROM localidades l JOIN provincias p USING (n_provincia) JOIN comunidades c USING (id_comunidad) JOIN localidades l2 ON (p.id_capital=l2.id_localidad) JOIN localidades l3 ON (c.id_capital=l3.id_localidad) )
SELECT DISTINCT (comunidad, capital_comunidad) FROM resumen; La creacin de la vista del ejemplo es compleja ya que hay relaciones complicadas, pero una vez creada la vista, se le pueden hacer consultas como si se tratara de una tabla normal. Incluso se puede utilizar el comando DESCRIBE sobre la vista para mostrar la estructura de los campos que forman la vista.
borrar vistas
Se utiliza el comando DROP VIEW: DROP VIEW nombreDeVista;
secuencias
Una secuencia sirve para generar automticamente nmeros distintos. Se utilizan para generar valores para campos que se utilizan como clave forzada (claves cuyo valor no interesa, slo sirven para identificar los registros de una tabla). Es una rutina interna de Oracle la que realiza la funcin de generar un nmero distinto cada vez. Las secuencias se almacenan independientemente de la tabla, por lo que la misma secuencia se puede utilizar para diversas tablas.
creacin de secuencias
Sintaxis: CREATE SEQUENCE secuencia [INCREMENT BY n] [START WITH n] [{MAXVALUE n|NOMAXVALUE}] [{MINVALUE n|NOMINVALUE}] [{CYCLE|NOCYCLE}] Donde: secuencia. Es el nombre que se le da al objeto de secuencia INCREMENT BY. Indica cunto se incrementa la secuencia cada vez que se usa. Por defecto se incrementa de uno en uno START WITH. Indica el valor inicial de la secuencia (por defecto 1) MAXVALUE. Mximo valor que puede tomar la secuencia. Si no se toma NOMAXVALUE que permite llegar hasta el 1027 MINVALUE. Mnimo valor que puede tomar la secuencia. Por defecto -1026 67
objetos de la base de datos CYCLE. Hace que la secuencia vuelva a empezar si se ha llegado al mximo valor. Ejemplo: CREATE SEQUENCE numeroPlanta INCREMENT 100 STARTS WITH 100 MAXVALUE 2000
uso de la secuencia
Los mtodos NEXTVAL y CURRVAL se utilizan para obtener el siguiente nmero y el valor actual de la secuencia respectivamente. Ejemplo de uso: SELECT numeroPlanta.NEXTVAL FROM DUAL; Eso muestra en pantalla el siguiente valor de la secuencia. Realmente NEXTVAL incrementa la secuencia y devuelve el valor actual. CURRVAL devuelve el valor de la secuencia, pero sin incrementar la misma. Ambas funciones pueden ser utilizadas en: Una consulta SELECT que no lleve DISTINCT, ni grupos, ni sea parte de una vista, ni sea subconsulta de otro SELECT, UPDATE o DELETE Una subconsulta SELECT en una instruccin INSERT La clusula VALUES de la instruccin INSERT La clusula SET de la instruccin UPDATE No se puede utilizar (y siempre hay tentaciones para ello) como valor para la clusula DEFAULT de un campo de tabla. Su uso ms habitual es como apoyo al comando INSERT: INSERT INTO plantas(num, uso) VALUES(numeroPlanta.NEXTVAL, 'Suites');
68
modificar secuencias
Se pueden modificar las secuencias, pero la modificacin slo puede afectar a los futuros valores de la secuencia, no a los ya utilizados. Sintaxis: ALTER SEQUENCE secuencia [INCREMENT BY n] [START WITH n] [{MAXVALUE n|NOMAXVALUE}] [{MINVALUE n|NOMINVALUE}] [{CYCLE|NOCYCLE}]
borrar secuencias
Lo hace el comando DROP SEQUENCE seguido del nombre de la secuencia a borrar.
ndices
Los ndices son esquemas que hacen que Oracle acelere las operaciones de consulta y ordenacin sobre los campos a los que el ndice hace referencia. Se almacenan aparte de la tabla a la que hace referencia, lo que permite crearles y borrarles en cualquier momento. Lo que realizan es una lista ordenada por la que Oracle puede acceder para facilitar la bsqueda de los datos. cada vez que se aade un nuevo registro, los ndices involucrados se actualizan a fin de que su informacin est al da. De ah que cuantos ms ndices haya, ms le cuesta a Oracle aadir registros, pero ms rpidas se realizan las instrucciones de consulta. La mayora de los ndices se crean de manera implcita, como consecuencia de las restricciones PRIMARY KEY (que obliga a crear un ndice nico sobre los campos clave) , UNIQUE (crea tambin un ndice nico) y FOREIGN KEY (crea un ndice con posibilidad de repetir valores, ndice con duplicados). Estos son ndices obligatorios, por los que les crea el propio Oracle.
creacin de ndices
Aparte de los ndices obligatorios comentados anteriormente, se pueden crear ndices de forma explcita. stos se crean para aquellos campos sobre los cuales se realizarn bsquedas e instrucciones de ordenacin frecuente. Sintaxis: CREATE INDEX nombre ON tabla (columna1 [,columna2...]) Ejemplo: CREATE INDEX nombre_completo ON clientes (apellido1, apellido2, nombre);
69
objetos de la base de datos El ejemplo crea un ndice para los campos apellido1, apellido2 y nombre. Esto no es lo mismo que crear un ndice para cada campo, este ndice es efectivo cuando se buscan u ordenan clientes usando los tres campos (apellido1, apellido2, nombre) a la vez. Se aconseja crear ndices en campos que: Contengan una gran cantidad de valores Contengan una gran cantidad de nulos Son parte habitual de clusulas WHERE, GROUP BY u ORDER BY Son parte de listados de consultas de grandes tablas sobre las que casi siempre se muestran como mucho un 4% de su contenido. No se aconseja en campos que: Pertenezcan a tablas pequeas No se usan a menudo en las consultas Pertenecen a tablas cuyas consultas muestran ms de un 6% del total de registros Pertenecen a tablas que se actualizan frecuentemente Se utilizan en expresiones Los ndices se pueden crear utilizando expresiones complejas: CREATE INDEX nombre_complejo ON clientes (UPPER(nombre)); Esos ndices tienen sentido si en las consultas se utilizan exactamente esas expresiones.
lista de ndices
Para ver la lista de ndices se utiliza la vista USER_INDEXES . Mientras que la vista USER_IND_COLUMNS Muestra la lista de columnas que son utilizadas por ndices.
borrar ndices
La instruccin DROP INDEX seguida del nombre del ndice permite eliminar el ndice en cuestin.
sinnimos
Un sinnimo es un nombre que se asigna a un objeto cualquiera. Normalmente es un nombre menos descriptivo que el original a fin de facilitar la escritura del nombre del objeto en diversas expresiones.
70
creacin
Sintaxis: CREATE [PUBLIC] SYNONYM nombre FOR objeto; objeto es el objeto al que se referir el sinnimo. La clusula PUBLIC hace que el sinnimo est disponible para cualquier usuario (slo se permite utilizar si disponemos de privilegios administrativos).
borrado
DROP SYNONYM nombre
lista de sinnimos
La vista USER_SYNONYMS permite observar la lista de sinnimos del usuario, la vista ALL_SYNONYMSE permite mostrar la lista completa de sinnimos.
71
consultas avanzadas
consultas con ROWNUM
La funcin ROWNUM devuelve el nmero de la fila de una consulta. Por ejemplo en: SELECT ROWNUM, edad, nombre FROM clientes Aparece el nmero de cada fila en la posicin de la tabla. Esa funcin actualiza sus valores usando subconsultas de modo que la consulta: SELECT ROWNUM AS ranking, edad, nombre FROM clientes FROM (SELECT edad, nombre FROM clientes ORDER BY edad DESC) Puesto que la consulta SELECT edad, nombre FROM clientes ORDER BY edad DESC, obtiene una lista de los clientes ordenada por edad, el SELECT superior obtendr esa lista pero mostrando el orden de las filas en esa consulta. Eso permite hacer consultas el tipo top-n, (los n ms....). Por ejemplo para sacar el top-10 de la edad de los clientes (los 10 clientes ms mayores): SELECT ROWNUM AS ranking, edad, nombre FROM clientes FROM (SELECT edad, nombre FROM clientes ORDER BY edad DESC) WHERE ROWNUMZ<=10
73
consultas avanzadas En el ejemplo se observa como un jefe puede tener otro jefe, generando una estructura jerrquica:
Sin embargo: SELECT nombre FROM empleados START WITH nombre='Andrs' CONNECT BY n_jefe= PRIOR n_empleado;
74
Devuelve:
NOMBRE Andrs Carmelo
El modificador LEVEL permite mostrar el nivel en el rbol jerrquico de cada elemento: SELECT LEVEL, nombre FROM empleados START WITH nombre='ngel' CONNECT BY n_jefe= PRIOR n_empleado; Resultado:
LEVEL 1 2 2 3 3 4 ngel Antonio Eva Carmen Andrs Carmelo NOMBRE
Para eliminar recorridos, se utilizan condiciones en WHERE o en el propio CONNECT. De modo que : SELECT LEVEL, nombre FROM empleados WHERE nombre!='Eva' START WITH nombre='ngel' CONNECT BY n_jefe= PRIOR n_empleado;
75
consultas avanzadas En ese ejemplo, Eva no sale en los resultados. En este otro: SELECT LEVEL, nombre FROM empleados START WITH nombre='ngel' CONNECT BY n_jefe= PRIOR n_empleado AND nombre!='Eva'; No sale ni Eva ni sus empleados (se corta la rama entera)..
subconsultas avanzadas
Ya se coment en el apartado subconsultas (pgina 46) como utilizar las subconsultas. Este tipo de consultas permiten comprobar si un dato se encuentra relacionado con datos que proceden de una segunda consulta. Aqu se comentan algunas mejoras a ese tipo de consultas implementadas por Oracle.
subconsultas correlacionadas
Las subconsultas correlacionadas hacen un proceso fila a fila, de modo que la subconsulta se ejecuta una vez por cada fila de la consulta principal. Esto es absolutamente diferente respecto a la ejecucin normal de una subconsulta, ya que normalmente la subconsulta se ejecuta primero, y con sus resultados se ejecuta la consulta principal. La sintaxis de este tipo de consultas es: SELECT listaDeColumnas FROM tabla alias WHERE expresion operador (SELECT listaDeExpresiones+ FROM tabla2 WHERE expr1 = alias.expr2)
76
Ejemplo: SELECT nombre, salario, cod_departamento FROM empleados emp WHERE salario >(SELECT AVG(salario) FROM empleados WHERE departamento = emp.departamento) Este ejemplo muestra los datos de los empleados cuyo sueldo supera la media de su departamento.
consultas EXISTS
Este operador devuelve verdadero si la consulta que le sigue devuelve algn valor. Si no, devuelve falso. Se utiliza sobre todo en consultas correlacionadas. Ejemplo: SELECT tipo,modelo, precio_venta FROM piezas p WHERE EXISTS ( SELECT tipo,modelo FROM existencias WHERE tipo=p.tipo AND modelo=p.modelo); Esta consulta devuelve las piezas que se encuentran en la tabla de existencias (es igual al ejemplo comentado en el apartado subconsultas sobre mltiples valores). La consulta contraria es : SELECT tipo,modelo, precio_venta FROM piezas p WHERE NOT EXISTS ( SELECT tipo,modelo FROM existencias WHERE tipo=p.tipo AND modelo=p.modelo); Normalmente las consultas EXISTS se pueden realizar de alguna otra forma con los operadores ya comentados.
77
consultas avanzadas Si aadimos: SELECT tipo, modelo, SUM(cantidad) FROM existencias GROUP BY ROLLUP (tipo,modelo); Entonces nos aade un registro para cada tipo en el que aparece la suma del total para ese tipo. Al final mostrar un registro con el total absoluto. Es decir el resultado de esa consulta es:
TI AR AR AR AR AR BI BI BI BI CL CL CL CL EM EM EM PU PU PU TO TO TO TO TO TO TU TU TU TU TU TU MODELO 6 9 15 20 10 38 57 12 15 18 21 42 5 9 6 9 10 12 16 6 9 10 12 16 SUM(CANTIDAD) 10530 4928 5667 43 21168 363 1740 1638 3741 7000 3068 6612 16680 257 534 791 12420 7682 20102 464 756 987 7740 356 10303 277 876 1023 234 654 3064 75849
78
Se pueden unir varias columnas entre parntesis para tratarlas como si fueran una unidad: SELECT tipo, modelo, n_almacen, SUM(cantidad) FROM existencias GROUP BY ROLLUP ((tipo,modelo), (n_almacen)); La diferencia respecto a la anterior es que el total mostado por ROLLUP se referir al tipo y al modelo.
CUBE
Es muy similar al anterior, slo que este calcula todos los subtotales relativos a la consulta. Ejemplo: SELECT tipo, modelo, SUM(cantidad) FROM existencias GROUP BY CUBE (tipo,modelo); Resulta:
TI MODELO 5 6 9 10 12 15 16 18 20 21 38 42 57 AR AR AR AR AR BI BI BI BI CL CL CL CL 6 9 15 20 10 38 57 12 15 18 SUM(CANTIDAD) 75849 12420 11271 14242 2373 14974 8735 1010 6612 43 257 1740 534 1638 21168 10530 4928 5667 43 3741 363 1740 1638 16680 7000 3068 6612
79
consultas avanzadas
TI EM EM EM PU PU PU TO TO TO TO TO TO TU TU TU TU TU TU MODELO 21 42 5 9 6 9 10 12 16 6 9 10 12 16 SUM(CANTIDAD) 791 257 534 20102 12420 7682 10303 464 756 987 7740 356 3064 277 876 1023 234
GROUPING
Se trata de una funcin que funciona con ROLLUP y CUBE y que recibe uno o ms campos e indica si la fila muestra un subtotal referido a los campos en cuestin. Si la fila es un subtotal de esos campos pone 1, sino lo marca con 0. Ejemplo: SELECT tipo, modelo, SUM(cantidad), GROUPING(tipo), GROUPING(modelo) FROM existencias GROUP BY CUBE (tipo,modelo); Sale:
TIPO MODELO 5 6 9 10 12 15 16 18 20 SUM(CANTIDAD) 75849 12420 11271 14242 2373 14974 8735 1010 6612 43 GROUPING(TIPO) 1 1 1 1 1 1 1 1 1 1 GROUPING(MODELO) 1 0 0 0 0 0 0 0 0 0
80
Copyright - Copyleft ' Jorge Snchez 2004 TIPO MODELO 21 38 42 57 6 9 15 20 10 38 57 12 15 18 21 42 5 9 6 9 10 12 16 6 9 10 12 16 SUM(CANTIDAD) 257 1740 534 1638 21168 10530 4928 5667 43 3741 363 1740 1638 16680 7000 3068 6612 791 257 534 20102 12420 7682 10303 464 756 987 7740 356 3064 277 876 1023 234 654 GROUPING(TIPO) 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GROUPING(MODELO) 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0
AR AR AR AR AR BI BI BI BI CL CL CL CL EM EM EM PU PU PU TO TO TO TO TO TO TU TU TU TU TU TU
GROUPING SETS
Se trata de una mejora de Oracle 9i que permite realizar varias agrupaciones para la misma consulta. Sintaxis: SELECT... ... 81
consultas avanzadas
GROUP BY GROUPING SETS (listaDeCampos1) [,(lista2)...] Las listas indican los campos por los que se realiza la agrupacin. Ejemplo: SELECT tipo, modelo, n_almacen, SUM(cantidad) FROM existencias GROUP BY GROUPING SETS ((tipo,modelo), (n_almacen)); De esa consulta se obtiene:
TI AR AR AR AR BI BI BI CL CL CL EM EM PU PU TO TO TO TO TO TU TU TU TU TU MODELO 6 9 15 20 10 38 57 12 15 18 21 42 5 9 6 9 10 12 16 6 9 10 12 16 1 2 3 N_ALMACEN SUM(CANTIDAD) 10530 4928 5667 43 363 1740 1638 7000 3068 6612 257 534 12420 7682 464 756 987 7740 356 277 876 1023 234 654 30256 40112 5481
82
83