Sei sulla pagina 1di 177

1 - Instalacin de Oracle.

Para este curso utilizaremos la versin Oracle 10g XE (Express Edition para Windows) Para descargar el mismo debemos ingresar al sitio de Oracle: 1. Oracle 10g XE 2. Para permitir descargarlo del sitio seleccionamos con el mouse el control Radio "Accept License Agreement". 3. Luego seleccionamos la versin "Oracle Database 10g Express Edition (Universal)" (OracleXEUniv.exe (216,933,372 bytes)) 4. El sitio de Oracle requiere que nos registremos. Debemos seleccionar "sign up now" y luego "Create your Oracle account now", es decir crear una cuenta Oracle. Luego de habernos registrado podemos descargar el motor de base de datos Oracle. 5. El paso siguiente es instalar el gestor de base de datos propiamente dicho. Ejecutamos el archivo que acabamos de descargar: OracleXEUniv.exe Debemos ir presionando el botn "siguiente" en el asistente de instalacin, salvo cuando nos pide ingresar la contrasea de la base de datos, es importante no olvidar dicha clave. Luego de algunos minutos ya tenemos instalado el gestor de bases de datos Oracle en nuestro equipo. La segunda aplicacin que instalaremos ser el "Oracle SQL Developer". Es un entorno visual que nos permite comunicar con nuestro gestor de base de datos Oracle. Desde este entorno aprenderemos a administrar una base de datos Oracle. 1. Debemos ingresar a la siguiente pgina para descargar el Oracle SQL Developer 2. Aceptamos la licencia y seleccionamos "Oracle SQL Developer for Windows (JDK1.5.0_06 is bundled in this zip) 3. Luego de descargar el archivo procedemos a descomprimir el archivo zip en una carpeta (este programa no requiere instalacin) 4. En la carpeta donde descomprimimos debemos ejecutar el archivo sqldeveloper.exe

2 - Crear tablas (create table - describe - all_tables - drop table)


Existen varios objetos de base de datos: tablas, constraints (restricciones), vistas, secuencias, ndices, agrupamientos (clusters), disparadores (triggers), instantaneas (snapshots), procedimientos, funciones, paquetes, sinnimos, usuarios, perfiles, privilegios, roles, etc. Los primeros objetos que veremos son tablas. Una base de datos almacena su informacin en tablas, que es la unidad bsica de almacenamiento. Una tabla es una estructura de datos que organiza los datos en columnas y filas; cada columna es un campo (o atributo) y cada fila, un registro. La interseccin de una columna con una fila, contiene un dato especfico, un solo valor. Cada registro contiene un dato por cada columna de la tabla. Cada campo (columna) debe tener un nombre. El nombre del campo hace referencia a la informacin que almacenar. Cada campo (columna) tambin debe definir el tipo de dato que almacenar. Las tablas forman parte de una base de datos.

Nosotros trabajaremos con la base de datos ya creada. Para ver las tablas existentes tipeamos: select *from all_tables; Aparece una tabla que nos muestra en cada fila, los datos de una tabla especfica; en la columna "TABLE_NAME" aparece el nombre de cada tabla existente. Al crear una tabla debemos resolver qu campos (columnas) tendr y que tipo de datos almacenarn cada uno de ellos, es decir, su estructura. La sintaxis bsica y general para crear una tabla es la siguiente: create table NOMBRETABLA( NOMBRECAMPO1 TIPODEDATO, ... NOMBRECAMPON TIPODEDATO ); La tabla debe ser definida con un nombre que la identifique y con el cual accederemos a ella. Creamos una tabla llamada "usuarios" y entre parntesis definimos los campos y sus tipos: create table usuarios( nombre varchar2(30), clave varchar2(10) ); Cada campo con su tipo debe separarse con comas de los siguientes, excepto el ltimo. Cuando se crea una tabla debemos indicar su nombre y definir al menos un campo con su tipo de dato. En esta tabla "usuarios" definimos 2 campos: - nombre: que contendr una cadena de caracteres de 30 caracteres de longitud, que almacenar el nombre de usuario y - clave: otra cadena de caracteres de 10 de longitud, que guardar la clave de cada usuario. Cada usuario ocupar un registro de esta tabla, con su respectivo nombre y clave. Para nombres de tablas, se puede utilizar cualquier caracter permitido para nombres de directorios, el primero debe ser un caracter alfabtico y no puede contener espacios. La longitud mxima es de 30 caracteres. Si intentamos crear una tabla con un nombre ya existente (existe otra tabla con ese nombre), mostrar un mensaje indicando que a tal nombre ya lo est utilizando otro objeto y la sentencia no se ejecutar. Para ver la estructura de una tabla usamos el comando "describe" junto al nombre de la tabla: describe usuarios; Aparece la siguiente informacin:

Name Null Type ------------------------------NOMBRE VARCHAR2(30) CLAVE VARCHAR2(10) Esta es la estructura de la tabla "usuarios"; nos muestra cada campo, su tipo y longitud y otros valores que no analizaremos por el momento. Para eliminar una tabla usamos "drop table" junto al nombre de la tabla a eliminar: drop table NOMBRETABLA; En el siguiente ejemplo eliminamos la tabla "usuarios": drop table usuarios; Si intentamos eliminar una tabla que no existe, aparece un mensaje de error indicando tal situacin y la sentencia no se ejecuta.

Ejercicios Crear tablas

2 - Crear tablas (create table - describe - all_tables - drop table)


Primer problema: Necesita almacenar los datos de amigos en una tabla. Los datos que guardar sern: apellido, nombre, domicilio y telfono. 1- Elimine la tabla "agenda" Si no existe, un mensaje indicar tal situacin. 2- Intente crear una tabla llamada "*agenda" create table *agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); aparece un mensaje de error indicando que usamos un caracter invlido ("*") para el nombre de la tabla. 3- Cree una tabla llamada "agenda", debe tener los siguientes campos: apellido, varchar2(30); nombre, varchar2(20); domicilio, varchar2 (30) y telefono, varchar2(11) Un mensaje indica que la tabla ha sido creada exitosamente. 4- Intente crearla nuevamente. Aparece mensaje de error indicando que el nombre ya lo tiene otro objeto.

5- Visualice las tablas existentes (all_tables) La tabla "agenda" aparece en la lista. 6- Visualice la estructura de la tabla "agenda" (describe) Aparece la siguiente tabla: Name Null Type ----------------------APELLIDO VARCHAR2(30) NOMBRE VARCHAR2(20) DOMICILIO VARCHAR2(30) TELEFONO VARCHAR2(11)

Solucin:
drop table agenda; create table *agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); select *from all_tables; describe agenda;

Segundo ejercicio
Segundo problema: Necesita almacenar informacin referente a los libros de su biblioteca personal. Los datos que guardar sern: ttulo del libro, nombre del autor y nombre de la editorial.

1- Elimine la tabla "libros" Si no existe, un mensaje indica tal situacin. 2- Verifique que la tabla "libros" no existe (all_tables) No aparece en la lista. 3- Cree una tabla llamada "libros". Debe definirse con los siguientes campos: titulo, varchar2(20); autor, varchar2(30) y editorial, varchar2(15) 4- Intente crearla nuevamente: Aparece mensaje de error indicando que existe un objeto con el nombre "libros". 5- Visualice las tablas existentes 6- Visualice la estructura de la tabla "libros": Aparece "libros" en la lista. 7- Elimine la tabla 8- Intente eliminar la tabla Un mensaje indica que no existe.

Solucin
drop table libros; select *from all_tables; create table libros( titulo varchar2(20), autor varchar2(30), editorial varchar2(15) ); create table libros( titulo varchar2(20), autor varchar2(30), editorial varchar2(15) ); select *from all_tables; describe libros; drop table libros; drop table libros;

3 - Ingresar registros (insert into- select)


Un registro es una fila de la tabla que contiene los datos propiamente dichos. Cada registro tiene un dato por cada columna (campo). Nuestra tabla "usuarios" consta de 2 campos, "nombre" y "clave". Al ingresar los datos de cada registro debe tenerse en cuenta la cantidad y el orden de los campos. La sintaxis bsica y general es la siguiente: insert into NOMBRETABLA (NOMBRECAMPO1, ..., NOMBRECAMPOn) values (VALORCAMPO1, ..., VALORCAMPOn); Usamos "insert into", luego el nombre de la tabla, detallamos los nombres de los campos entre parntesis y separados por comas y luego de la clusula "values" colocamos los valores para cada campo, tambin entre parntesis y separados por comas. En el siguiente ejemplo se agrega un registro a la tabla "usuarios", en el campo "nombre" se almacenar "Mariano" y en el campo "clave" se guardar "payaso": insert into usuarios (nombre, clave) values ('Mariano','payaso'); Luego de cada insercin aparece un mensaje indicando la cantidad de registros ingresados. Note que los datos ingresados, como corresponden a cadenas de caracteres se colocan entre comillas simples. Para ver los registros de una tabla usamos "select": select *from usuarios; El comando "select" recupera los registros de una tabla. Con el asterisco indicamos que muestre todos los campos de la tabla "usuarios". Aparece la tabla, sus campos y registros ingresados; si no tiene registros, apareceran solamente los campos y la tabla vaca). Es importante ingresar los valores en el mismo orden en que se nombran los campos: En el siguiente ejemplo se lista primero el campo "clave" y luego el campo "nombre" por eso, los valores tambin se colocan en ese orden: insert into usuarios (clave, nombre) values ('River','Juan'); Si ingresamos los datos en un orden distinto al orden en que se nombraron los campos, no aparece un mensaje de error y los datos se guardan de modo incorrecto.

En el siguiente ejemplo se colocan los valores en distinto orden en que se nombran los campos, el valor de la clave (la cadena "Boca") se guardar en el campo "nombre" y el valor del nombre (la cadena "Luis") en el campo "clave": insert into usuarios (nombre,clave) values ('Boca','Luis');

Ejercicio

3 - Ingresar registros (insert into- select)


Primer problema: Trabaje con la tabla "agenda" que almacena informacin de sus amigos. 1- Elimine la tabla "agenda" 2- Cree una tabla llamada "agenda". Debe tener los siguientes campos: apellido (cadena de 30), nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11) 3- Visualice las tablas existentes para verificar la creacin de "agenda" (all_tables) 4- Visualice la estructura de la tabla "agenda" (describe) 5- Ingrese los siguientes registros: insert into agenda (apellido, nombre, domicilio, telefono) values ('Moreno','Alberto','Colon 123','4234567'); insert into agenda (apellido,nombre, domicilio, telefono) values ('Torres','Juan','Avellaneda 135','4458787'); 6- Seleccione todos los registros de la tabla. 7- Elimine la tabla "agenda" 8- Intente eliminar la tabla nuevamente (aparece un mensaje de error)

Resultado
drop table agenda; create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); select *from all_tables;

describe agenda; insert into agenda (apellido, nombre, domicilio, telefono) values ('Moreno','Alberto','Colon 123','4234567'); insert into agenda (apellido,nombre, domicilio, telefono) values ('Torres','Juan','Avellaneda 135','4458787'); select *from agenda; drop table agenda; drop table agenda;

Ejercicio 2
Segundo problema: Trabaje con la tabla "libros" que almacena los datos de los libros de su propia biblioteca. 1- Elimine la tabla "libros" 2- Cree una tabla llamada "libros". Debe definirse con los siguientes campos: titulo (cadena de 20), autor (cadena de 30) y editorial (cadena de 15) 3- Visualice las tablas existentes. 4- Visualice la estructura de la tabla "libros" Muestra los campos y los tipos de datos de la tabla "libros". 5- Ingrese los siguientes registros: insert into libros (titulo,autor,editorial) values ('El aleph','Borges','Planeta'); insert into libros (titulo,autor,editorial) values ('Martin Fierro','Jose Hernandez','Emece'); insert into libros (titulo,autor,editorial) values ('Aprenda PHP','Mario Molina','Emece'); 6- Muestre todos los registros (select) de "libros"

Resultado
drop table libros; create table libros( titulo varchar2(30), autor varchar2(30), editorial varchar2(15)

); select *from all_tables; describe libros; insert into libros (titulo,autor,editorial) values ('El aleph','Borges','Planeta'); insert into libros (titulo,autor,editorial) values ('Martin Fierro','Jose Hernandez','Emece'); insert into libros (titulo,autor,editorial) values ('Aprenda PHP','Mario Molina','Emece');

select *from libros;

4 - Tipos de datos
Ya explicamos que al crear una tabla debemos resolver qu campos (columnas) tendr y que tipo de datos almacenar cada uno de ellos, es decir, su estructura. El tipo de dato especifica el tipo de informacin que puede guardar un campo: caracteres, nmeros, etc. Estos son algunos tipos de datos bsicos de Oracle (posteriormente veremos otros y con ms detalle): - varchar2: se emplea para almacenar cadenas de caracteres. Una cadena es una secuencia de caracteres. Se coloca entre comillas simples; ejemplo: 'Hola', 'Juan Perez', 'Colon 123'. Este tipo de dato definen una cadena de longitud variable en la cual determinamos el mximo de caracteres entre parntesis. Puede guardar hasta xxx caracteres. Por ejemplo, para almacenar cadenas de hasta 30 caracteres, definimos un campo de tipo varchar2 (30), es decir, entre parntesis, junto al nombre del campo colocamos la longitud. Si intentamos almacenar una cadena de caracteres de mayor longitud que la definida, la cadena no se carga, aparece un mensaje indicando tal situacin y la sentencia no se ejecuta. Por ejemplo, si definimos un campo de tipo varchar(10) e intentamos almacenar en l la cadena 'Buenas tardes', aparece un mensaje indicando que el valor es demasiado grande para la columna. - number(p,s): se usa para guardar valores numricos con decimales, de 1.0 x10-120 a 9.9...(38 posiciones). Definimos campos de este tipo cuando queremos almacenar valores numricos con los cuales luego realizaremos operaciones matemticas, por ejemplo, cantidades, precios, etc. Puede contener nmeros enteros o decimales, positivos o negativos. El parmetro "p" indica la precisin, es decir, el nmero de dgitos en total (contando los decimales) que contendr el nmero como mximo. El parmetro "s" especifica la escala, es decir, el mximo de dgitos decimales. Por ejemplo, un campo definido "number(5,2)" puede contener cualquier nmero entre 0.00 y 999.99 (positivo o negativo). Para especificar nmero enteros, podemos omitir el parmetro "s" o colocar el valor 0 como parmetro "s". Se utiliza como separador el punto (.). Si intentamos almacenar un valor mayor fuera del rango permitido al definirlo, tal valor no se carga, aparece un mensaje indicando tal situacin y la sentencia no se ejecuta.

Por ejemplo, si definimos un campo de tipo number(4,2) e intentamos guardar el valor 123.45, aparece un mensaje indicando que el valor es demasiado grande para la columna. Si ingresamos un valor con ms decimales que los definidos, el valor se carga pero con la cantidad de decimales permitidos, los dgitos sobrantes se omiten. Antes de crear una tabla debemos pensar en sus campos y optar por el tipo de dato adecuado para cada uno de ellos. Por ejemplo, si en un campo almacenaremos nmeros telefnicos o un nmeros de documento, usamos "varchar2", no "number" porque si bien son dgitos, con ellos no realizamos operaciones matemticas. Si en un campo guardaremos apellidos, y suponemos que ningn apellido superar los 20 caracteres, definimos el campo "varchar2(20)". Si en un campo almacenaremos precios con dos decimales que no superarn los 999.99 pesos definimos un campo de tipo "number(5,2)", es decir, 5 dgitos en total, con 2 decimales. Si en un campo almacenaremos valores enteros de no ms de 3 dgitos, definimos un campo de tipo "number(3,0)".

Ejercicio

4 - Tipos de datos
Primer problema: Un videoclub que alquila pelculas en video almacena la informacin de sus pelculas en una tabla llamada "peliculas"; para cada pelcula necesita los siguientes datos: -nombre, cadena de caracteres de 20 de longitud, -actor, cadena de caracteres de 20 de longitud, -duracin, valor numrico entero que no supera los 3 dgitos. -cantidad de copias: valor entero de un slo dgito (no tienen ms de 9 copias de cada pelcula). 1- Elimine la tabla "peliculas" si ya existe. 2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo. Note que los campos "duracion" y "cantidad", que almacenarn valores sin decimales, fueron definidos de maneras diferentes, en el primero especificamos el valor 0 como cantidad de decimales, en el segundo no especificamos cantidad de decimales, es decir, por defecto, asume el valor 0. 3- Vea la estructura de la tabla. 4- Ingrese los siguientes registros: insert into peliculas (nombre, actor, duracion, cantidad) values ('Mision imposible','Tom Cruise',128,3); insert into peliculas (nombre, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',130,2); insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','Julia Roberts',118,3); insert into peliculas (nombre, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',110,2); 5- Muestre todos los registros (4 registros)

6- Intente ingresar una pelcula con valor de cantidad fuera del rango permitido: insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','Richard Gere',1200,10); Mensaje de error. 7- Ingrese un valor con decimales en un nuevo registro, en el campo "duracion": insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','Richard Gere',120.20,4); 8- Muestre todos los registros para ver cmo se almacen el ltimo registro ingresado. 9- Intente ingresar un nombre de pelcula que supere los 20 caracteres.

Solucin
drop table peliculas; create table peliculas( nombre varchar2(20), actor varchar2(20), duracion number(3,0), cantidad number(1) ); describe peliculas; insert into peliculas (nombre, actor, duracion, cantidad) values ('Mision imposible','Tom Cruise',128,3); insert into peliculas (nombre, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',130,2); insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','Julia Roberts',118,3); insert into peliculas (nombre, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',110,2); select *from peliculas; insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','Richard Gere',1200,10); insert into peliculas (nombre, actor, duracion, cantidad) values ('Mujer bonita','Richard Gere',120.20,4); select *from peliculas: insert into peliculas (nombre, actor, duracion, cantidad) values ('Alicia en el pais de las maravillas','Animados',90,3);

Ejercicio 2

Segundo problema: Una empresa almacena los datos de sus empleados en una tabla "empleados" que guarda los siguientes datos: nombre, documento, sexo, domicilio, sueldobasico. 1- Elimine la tabla si existe. 2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table empleados( nombre varchar2(20), documento varchar2(8), sexo varchar2(1), domicilio varchar2(30), sueldobasico number(6,2) ); 3- Verifique que la tabla existe consultando "all_tables" 4- Vea la estructura de la tabla (5 campos) 5- Ingrese algunos registros: insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Juan Perez','22333444','m','Sarmiento 123',500); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Ana Acosta','24555666','f','Colon 134',650); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Bartolome Barrios','27888999','m','Urquiza 479',800); 6- Seleccione todos los registros (3 registros) 7- Intente ingresar un registro con el valor "masculino" en el campo "sexo" Un mensaje indica que el campo est definido para almacenar 1 solo caracter como mximo y est intentando ingresar 9 caracteres. 8- Intente ingresar un valor fuera de rango, en un nuevo registro, para el campo "sueldobasico" Mensaje de error. 9- Elimine la tabla

Solucin
drop table empleados; create table empleados( nombre varchar2(20), documento varchar2(8), sexo varchar2(1), domicilio varchar2(30), sueldobasico number(6,2)

); select *from all_tables; describe empleados; insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Juan Perez','22333444','m','Sarmiento 123',500); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Ana Acosta','24555666','f','Colon 134',650); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Bartolome Barrios','27888999','m','Urquiza 479',800); select *from empleados; insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Carlos Caseres','33556688','masculino','Colon 235',900); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Carlos Caseres','33556688','m','Colon 235',10000.5);

drop table empleados;

5 - Recuperar algunos campos (select)


Hemos aprendido cmo ver todos los registros de una tabla, empleando la instruccin "select". La sintaxis bsica y general es la siguiente: select *from NOMBRETABLA; El asterisco (*) indica que se seleccionan todos los campos de la tabla. Podemos especificar el nombre de los campos que queremos ver, separndolos por comas: select titulo,autor from libros; La lista de campos luego del "select" selecciona los datos correspondientes a los campos nombrados. En el ejemplo anterior seleccionamos los campos "titulo" y "autor" de la tabla "libros", mostrando todos los registros. Ejercicio Primer problema: Un videoclub que alquila pelculas en video almacena la informacin de sus pelculas en alquiler en una tabla llamada "peliculas". 1- Elimine la tabla si existe. 2- Cree la tabla:

create table peliculas( titulo varchar2(20), actor varchar2(20), duracion number(3), cantidad number(1) ); 3- Vea la estructura de la tabla (4 campos) 4- Ingrese los siguientes registros: insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible','Tom Cruise',180,3); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',190,2); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mujer bonita','Julia Roberts',118,3); insert into peliculas (titulo, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',110,2); 5- Realice un "select" mostrando solamente el ttulo y actor de todas las pelculas 6- Muestre el ttulo y duracin de todas las peliculas. 7- Muestre el ttulo y la cantidad de copias. drop table peliculas; create table peliculas( titulo varchar2(20), actor varchar2(20), duracion number(3), cantidad number(1) ); describe peliculas; insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible','Tom Cruise',180,3); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',190,2); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mujer bonita','Julia Roberts',118,3); insert into peliculas (titulo, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',110,2); select titulo,actor from peliculas; select titulo,duracion from peliculas; select titulo,cantidad from peliculas;

Ejercicio 2 Segundo problema: Una empresa almacena los datos de sus empleados en una tabla llamada "empleados". 1- Elimine la tabla si ya existe. 2- Cree la tabla: create table empleados( nombre varchar2(20), documento varchar2(8), sexo varchar2(1), domicilio varchar2(30), sueldobasico number(6,2) ); 3- Vea la estructura de la tabla (5 campos) 4- Ingrese algunos registros: insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Juan Juarez','22333444','m','Sarmiento 123',500); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Ana Acosta','27888999','f','Colon 134',700); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Carlos Caseres','31222333','m','Urquiza 479',850); 5- Muestre todos los datos de los empleados. 6- Muestre el nombre, documento y domicilio de los empleados. 7- Realice un "select" mostrando el documento, sexo y sueldo bsico de todos los empleados. Solucin drop table empleados; create table empleados( nombre varchar2(20), documento varchar2(8), sexo varchar2(1), domicilio varchar2(30), sueldobasico number(6,2) ); describe empleados; insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Juan Juarez','22333444','m','Sarmiento 123',500); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico)

values ('Ana Acosta','27888999','f','Colon 134',700); insert into empleados (nombre, documento, sexo, domicilio, sueldobasico) values ('Carlos Caseres','31222333','m','Urquiza 479',850); select *from empleados; select nombre,documento,domicilio from empleados; select documento,sexo,sueldobasico

from empleados;

6 - Recuperar algunos registros (where)


Hemos aprendido a seleccionar algunos campos de una tabla. Tambin es posible recuperar algunos registros. Existe una clusula, "where" con la cual podemos especificar condiciones para una consulta "select". Es decir, podemos recuperar algunos registros, slo los que cumplan con ciertas condiciones indicadas con la clusula "where". Por ejemplo, queremos ver el usuario cuyo nombre es "Marcelo", para ello utilizamos "where" y luego de ella, la condicin: select nombre, clave from usuarios where nombre='Marcelo'; La sintaxis bsica y general es la siguiente: select NOMBRECAMPO1, ..., NOMBRECAMPOn from NOMBRETABLA where CONDICION; Para las condiciones se utilizan operadores relacionales (tema que trataremos ms adelante en detalle). El signo igual(=) es un operador relacional. Para la siguiente seleccin de registros especificamos una condicin que solicita los usuarios cuya clave es igual a "River": select nombre,clave from usuarios where clave='River'; Si ningn registro cumple la condicin establecida con el "where", no aparecer ningn registro. Entonces, con "where" establecemos condiciones para recuperar algunos registros. Para recuperar algunos campos de algunos registros combinamos en la consulta la lista de campos y la clusula "where": select nombre from usuarios

where clave='River'; En la consulta anterior solicitamos el nombre de todos los usuarios cuya clave sea igual a "River". Ejercicios Primer problema: Trabaje con la tabla "agenda" en la que registra los datos de sus amigos. 1- Elimine "agenda" 2- Cree la tabla, con los siguientes campos: apellido (cadena de 30), nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11): create table agenda( apellido varchar2(30), nombre varchar2(30), domicilio varchar2(30), telefono varchar2(11) ); 3- Visualice la estructura de la tabla "agenda" (4 campos) 4- Ingrese los siguientes registros ("insert into"): insert into agenda(apellido,nombre,domicilio,telefono) values ('Acosta', 'Ana', 'Colon 123', '4234567'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Bustamante', 'Betina', 'Avellaneda 135', '4458787'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Lopez', 'Hector', 'Salta 545', '4887788'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Lopez', 'Luis', 'Urquiza 333', '4545454'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Lopez', 'Marisa', 'Urquiza 333', '4545454'); 5- Seleccione todos los registros de la tabla (5 registros) 6- Seleccione el registro cuyo nombre sea "Marisa" (1 registro) 7- Seleccione los nombres y domicilios de quienes tengan apellido igual a "Lopez" (3 registros) 8- Seleccione los nombres y domicilios de quienes tengan apellido igual a "lopez" (en minsculas) No aparece ningn registro, ya que la cadena "Lopez" noe s igual a la cadena "lopez". 9- Muestre el nombre de quienes tengan el telfono "4545454" (2 registros)

Solucion drop table agenda; create table agenda( apellido varchar2(30), nombre varchar2(30), domicilio varchar2(30), telefono varchar2(11) ); describe agenda; insert into agenda(apellido,nombre,domicilio,telefono) values ('Acosta', 'Ana', 'Colon 123', '4234567'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Bustamante', 'Betina', 'Avellaneda 135', '4458787'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Lopez', 'Hector', 'Salta 545', '4887788'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Lopez', 'Luis', 'Urquiza 333', '4545454'); insert into agenda(apellido,nombre,domicilio,telefono) values ('Lopez', 'Marisa', 'Urquiza 333', '4545454'); select *from agenda; select *from agenda where nombre='Marisa'; select nombre,domicilio from agenda where apellido='Lopez'; select nombre,domicilio from agenda where apellido='lopez'; select nombre from agenda

where telefono='4545454'; Ejercicio 2


Segundo problema: Un comercio que vende artculos de computacin registra los datos de sus artculos en una tabla llamada "articulos". 1- Elimine la tabla si existe. 2- Cree la tabla "articulos" con la siguiente estructura: create table articulos( codigo number(5), nombre varchar2(20),

descripcion varchar2(30), precio number(7,2) ); 3- Vea la estructura de la tabla: describe articulos; 4- Ingrese algunos registros: insert into articulos (codigo, nombre, descripcion, precio) values (1,'impresora','Epson Stylus C45',400.80); insert into articulos (codigo, nombre, descripcion, precio) values (2,'impresora','Epson Stylus C85',500); insert into articulos (codigo, nombre, descripcion, precio) values (3,'monitor','Samsung 14',800); insert into articulos (codigo, nombre, descripcion, precio) values (4,'teclado','ingles Biswal',100); insert into articulos (codigo, nombre, descripcion, precio) values (5,'teclado','espaol Biswal',90); 5- Seleccione todos los datos de los registros cuyo nombre sea "impresora" (2 registros) 6- Muestre slo el cdigo, descripcin y precio de los teclados (2 registros) Solucin: drop table articulos; create table articulos( codigo number(5), nombre varchar2(20), descripcion varchar2(30), precio number(7,2) ); describe articulos; insert into articulos (codigo, nombre, descripcion, precio) values (1,'impresora','Epson Stylus C45',400.80); insert into articulos (codigo, nombre, descripcion, precio) values (2,'impresora','Epson Stylus C85',500); insert into articulos (codigo, nombre, descripcion, precio) values (3,'monitor','Samsung 14',800); insert into articulos (codigo, nombre, descripcion, precio) values (4,'teclado','ingles Biswal',100); insert into articulos (codigo, nombre, descripcion, precio) values (5,'teclado','espaol Biswal',90); select *from articulos where nombre='impresora';

select codigo,descripcion,precio from articulos

where nombre='teclado';

7 - Operadores relacionales
Los operadores son smbolos que permiten realizar operaciones matemticas, concatenar cadenas, hacer comparaciones. Oracle reconoce de 4 tipos de operadores:

1) 2) 3) 4)

relacionales (o de comparacin) aritmticos de concatenacin lgicos

Por ahora veremos solamente los primeros. Los operadores relacionales (o de comparacin) nos permiten comparar dos expresiones, que pueden ser variables, valores de campos, etc. Hemos aprendido a especificar condiciones de igualdad para seleccionar registros de una tabla; por ejemplo: select *from libros where autor='Borges'; Utilizamos el operador relacional de igualdad. Los operadores relacionales vinculan un campo con un valor para que Oracle compare cada registro (el campo especificado) con el valor dado. Los operadores relacionales son los siguientes: = <> > < >= <= igual distinto mayor menor mayor o igual menor o igual

Podemos seleccionar los registros cuyo autor sea diferente de "Borges", para ello usamos la condicin: select * from libros where autor<>'Borges'; Podemos comparar valores numricos. Por ejemplo, queremos mostrar los ttulos y precios de los libros cuyo precio sea mayor a 20 pesos: select titulo, precio

from libros where precio>20; Queremos seleccionar los libros cuyo precio sea menor o igual a 30: select *from libros where precio<=30; Los operadores relacionales comparan valores del mismo tipo. Se emplean para comprobar si un campo cumple con una condicin. No son los nicos, existen otros que veremos mas adelante. Ejercicio 1: Primer problema: Un comercio que vende artculos de computacin registra los datos de sus artculos en una tabla con ese nombre. 1- Elimine "articulos" 2- Cree la tabla, con la siguiente estructura: create table articulos( codigo number(5), nombre varchar2(20), descripcion varchar2(30), precio number(6,2), cantidad number(3) ); 3- Vea la estructura de la tabla. 4- Ingrese algunos registros: insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (1,'impresora','Epson Stylus C45',400.80,20); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (2,'impresora','Epson Stylus C85',500,30); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (3,'monitor','Samsung 14',800,10); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (4,'teclado','ingles Biswal',100,50); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (5,'teclado','espaol Biswal',90,50); 5- Seleccione los datos de las impresoras (2 registros) 6- Seleccione los artculos cuyo precio sea mayor o igual a 400 (3 registros) 7- Seleccione el cdigo y nombre de los artculos cuya cantidad sea menor a 30 (2 registros)

8- Selecciones el nombre y descripcin de los artculos que NO cuesten $100 (4 registros) Solucin: drop table articulos; create table articulos( codigo number(5), nombre varchar2(20), descripcion varchar2(30), precio number(6,2), cantidad number(3) ); describe articulos; insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (1,'impresora','Epson Stylus C45',400.80,20); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (2,'impresora','Epson Stylus C85',500,30); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (3,'monitor','Samsung 14',800,10); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (4,'teclado','ingles Biswal',100,50); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (5,'teclado','espaol Biswal',90,50); select *from articulos where nombre='impresora'; select *from articulos where precio>=400; select codigo,nombre from articulos where cantidad<30; select nombre, descripcion from articulos

where precio<>100;

Ejercicio 2: Segundo problema:

Un video club que alquila pelculas en video almacena la informacin de sus pelculas en alquiler en una tabla denominada "peliculas". 1- Elimine la tabla. drop table peliculas; 2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table peliculas( titulo varchar2(20), actor varchar2(20), duracion number(3), cantidad number(1) ); 3- Ingrese los siguientes registros: insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible','Tom Cruise',120,3); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',180,4); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mujer bonita','Julia R.',90,1); insert into peliculas (titulo, actor, duracion, cantidad) values ('Elsa y Fred','China Zorrilla',80,2); 4- Seleccione las pelculas cuya duracin no supere los 90 minutos (2 registros) 5- Seleccione el ttulo de todas las pelculas en las que el actor NO sea "Tom Cruise" (2 registros) 6- Muestre todos los campos, excepto "duracion", de todas las pelculas de las que haya ms de 2 copias (2 registros) Solucin: drop table peliculas; create table peliculas( titulo varchar2(20), actor varchar2(20), duracion number(3), cantidad number(1) ); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible','Tom Cruise',120,3); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mision imposible 2','Tom Cruise',180,4); insert into peliculas (titulo, actor, duracion, cantidad) values ('Mujer bonita','Julia R.',90,1); insert into peliculas (titulo, actor, duracion, cantidad)

values ('Elsa y Fred','China Zorrilla',80,2); select *from peliculas where duracion<=90; select *from peliculas where actor<>'Tom Cruise'; select titulo,actor,cantidad from peliculas

where cantidad >2;

8 - Borrar registros (delete)


Para eliminar los registros de una tabla usamos el comando "delete". Sintaxis bsica: delete from NOMBRETABLA; Se coloca el comando delete seguido de la palabra clave "from" y el nombre de la tabla de la cual queremos eliminar los registros. En el siguiente ejemplo se eliminan los registros de la tabla "usuarios": delete from usuarios; Luego, un mensaje indica la cantidad de registros que se han eliminado. Si no queremos eliminar todos los registros, sino solamente algunos, debemos indicar cul o cules; para ello utilizamos el comando "delete" junto con la clausula "where" con la cual establecemos la condicin que deben cumplir los registros a borrar. Por ejemplo, queremos eliminar aquel registro cuyo nombre de usuario es "Marcelo": delete from usuarios where nombre='Marcelo'; Si solicitamos el borrado de un registro que no existe, es decir, ningn registro cumple con la condicin especificada, aparecer un mensaje indicando que ningn registro fue eliminado, pues no encontr registros con ese dato. Tenga en cuenta que si no colocamos una condicin, se eliminan todos los registros de la tabla especificada. Ejercicio 1: Primer problema: Trabaje con la tabla "agenda" que registra la informacin referente a sus amigos.

1- Elimine la tabla. 2- Cree la tabla con los siguientes campos: apellido (cadena de 30), nombre (cadena de 20), domicilio (cadena de 30) y telefono (cadena de 11): create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); 3- Ingrese los siguientes registros (insert into): insert into agenda(apellido,nombre,domicilio,telefono) ('Alvarez','Alberto','Colon 123','4234567'); insert into agenda(apellido,nombre,domicilio,telefono) ('Juarez','Juan','Avellaneda 135','4458787'); insert into agenda(apellido,nombre,domicilio,telefono) ('Lopez','Maria','Urquiza 333','4545454'); insert into agenda(apellido,nombre,domicilio,telefono) ('Lopez','Jose','Urquiza 333','4545454'); insert into agenda(apellido,nombre,domicilio,telefono) ('Salas','Susana','Gral. Paz 1234','4123456'); 4- Elimine el registro cuyo nombre sea "Juan" (1 registro) 5- Elimine los registros cuyo nmero telefnico sea igual a "4545454" (2 registros) 6- Elimine todos los registros (2 registros) Solucin: drop table agenda; create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); insert into agenda(apellido,nombre,domicilio,telefono) ('Alvarez','Alberto','Colon 123','4234567'); insert into agenda(apellido,nombre,domicilio,telefono) ('Juarez','Juan','Avellaneda 135','4458787'); insert into agenda(apellido,nombre,domicilio,telefono) ('Lopez','Maria','Urquiza 333','4545454'); insert into agenda(apellido,nombre,domicilio,telefono) ('Lopez','Jose','Urquiza 333','4545454'); insert into agenda(apellido,nombre,domicilio,telefono) ('Salas','Susana','Gral. Paz 1234','4123456'); values values values values values values values values values values

delete from agenda where nombre='Juan'; delete from agenda where telefono='4545454';

delete from agenda; Ejercicio 2


Segundo problema: Un comercio que vende artculos de computacin registra los datos de sus artculos en una tabla con ese nombre. 1- Elimine "articulos" 2- Cree la tabla, con la siguiente estructura: create table articulos( codigo number(4,0), nombre varchar2(20), descripcion varchar2(30), precio number(7,2), cantidad number(3) ); 3- Vea la estructura de la tabla. 4- Ingrese algunos registros: insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (1,'impresora','Epson Stylus C45',400.80,20); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (2,'impresora','Epson Stylus C85',500,30); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (3,'monitor','Samsung 14',800,10); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (4,'teclado','ingles Biswal',100,50); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (5,'teclado','espaol Biswal',90,50); 5- Elimine los artculos cuyo precio sea mayor o igual a 500 (2 registros) 7- Elimine todas las impresoras (1 registro) 8- Elimine todos los artculos cuyo cdigo sea diferente a 4 (1 registro)

Solucion

drop table articulos; create table articulos( codigo number(4,0), nombre varchar2(20), descripcion varchar2(30), precio number(7,2), cantidad number(3) ); describe libros; insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (1,'impresora','Epson Stylus C45',400.80,20); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (2,'impresora','Epson Stylus C85',500,30); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (3,'monitor','Samsung 14',800,10); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (4,'teclado','ingles Biswal',100,50); insert into articulos (codigo, nombre, descripcion, precio,cantidad) values (5,'teclado','espaol Biswal',90,50); delete from articulos where precio>=500; delete from articulos where nombre='impresora'; delete from articulos where codigo<>4;

9 - Actualizar registros (update)


Decimos que actualizamos un registro cuando modificamos alguno de sus valores. Para modificar uno o varios datos de uno o varios registros utilizamos "update" (actualizar). Sintaxis bsica: update NOMBRETABLA set CAMPO=NUEVOVALOR; Utilizamos "update" junto al nombre de la tabla y "set" junto con el campo a modificar y su nuevo valor. El cambio afectar a todos los registros. Por ejemplo, en nuestra tabla "usuarios", queremos cambiar los valores de todas las claves, por "RealMadrid":

update usuarios set clave='RealMadrid'; Podemos modificar algunos registros, para ello debemos establecer condiciones de seleccin con "where". Por ejemplo, queremos cambiar el valor correspondiente a la clave de nuestro usuario llamado "Federicolopez", queremos como nueva clave "Boca", necesitamos una condicin "where" que afecte solamente a este registro: update usuarios set clave='Boca' where nombre='Federicolopez'; Si Oracle no encuentra registros que cumplan con la condicin del "where", un mensaje indica que ningn registro fue modificado. Las condiciones no son obligatorias, pero si omitimos la clusula "where", la actualizacin afectar a todos los registros. Tambin podemos actualizar varios campos en una sola instruccin: update usuarios set nombre='Marceloduarte', clave='Marce' where nombre='Marcelo'; Para ello colocamos "update", el nombre de la tabla, "set" junto al nombre del campo y el nuevo valor y separado por coma, el otro nombre del campo con su nuevo valor.

Ejercicio 1:
Primer problema: Trabaje con la tabla "agenda" que almacena los datos de sus amigos. 1- Elimine la tabla y crela con la siguiente estructura: drop table agenda; create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); 3- Ingrese los siguientes registros: insert into agenda (apellido,nombre,domicilio,telefono) values ('Acosta','Alberto','Colon 123','4234567'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Juarez','Juan','Avellaneda 135','4458787'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Lopez','Maria','Urquiza 333','4545454'); insert into agenda (apellido,nombre,domicilio,telefono)

values ('Lopez','Jose','Urquiza 333','4545454'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Suarez','Susana','Gral. Paz 1234','4123456'); 4- Modifique el registro cuyo nombre sea "Juan" por "Juan Jose" (1 registro actualizado) 5- Actualice los registros cuyo nmero telefnico sea igual a "4545454" por "4445566" (2 registros) 6- Actualice los registros que tengan en el campo "nombre" el valor "Juan" por "Juan Jose" (ningn registro afectado porque ninguno cumple con la condicin del "where")

Solucin 1:
drop table agenda; create table agenda( apellido varchar2(30), nombre varchar2(20), domicilio varchar2(30), telefono varchar2(11) ); insert into agenda (apellido,nombre,domicilio,telefono) values ('Acosta','Alberto','Colon 123','4234567'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Juarez','Juan','Avellaneda 135','4458787'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Lopez','Maria','Urquiza 333','4545454'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Lopez','Jose','Urquiza 333','4545454'); insert into agenda (apellido,nombre,domicilio,telefono) values ('Suarez','Susana','Gral. Paz 1234','4123456'); update agenda set nombre='Juan Jose' where nombre='Juan'; update agenda set telefono='4445566' where telefono='4545454'; update agenda set nombre='Juan Jose' where nombre='Juan';

Ejercicio 2:
Segundo problema: Trabaje con la tabla "libros" de una librera. 1- Elimine la tabla y crela con los siguientes campos: titulo (cadena de 30 caracteres de longitud), autor (cadena de 20), editorial (cadena de 15) y precio (entero no mayor a 999.99): drop table libros;

create table libros ( titulo varchar2(30), autor varchar2(20), editorial varchar2(15), precio number(5,2) ); 3- Ingrese los siguientes registros: insert into libros (titulo, autor, editorial, precio) values ('El aleph','Borges','Emece',25.00); insert into libros (titulo, autor, editorial, precio) values ('Martin Fierro','Jose Hernandez','Planeta',35.50); insert into libros (titulo, autor, editorial, precio) values ('Aprenda PHP','Mario Molina','Emece',45.50); insert into libros (titulo, autor, editorial, precio) values ('Cervantes y el quijote','Borges','Emece',25); insert into libros (titulo, autor, editorial, precio) values ('Matematica estas ahi','Paenza','Siglo XXI',15); 4- Muestre todos los registros (5 registros) 5- Modifique los registros cuyo autor sea igual a "Paenza", por "Adrian Paenza" (1 registro) 6- Nuevamente, modifique los registros cuyo autor sea igual a "Paenza", por "Adrian Paenza" (ningn registro afectado porque ninguno cumple la condicin) 7- Actualice el precio del libro de "Mario Molina" a 27 pesos (1 registro) 8- Actualice el valor del campo "editorial" por "Emece S.A.", para todos los registros cuya editorial sea igual a "Emece" (3 registros) Solucin: drop table libros; create table libros ( titulo varchar2(30), autor varchar2(20), editorial varchar2(15), precio number(5,2) ); insert into libros (titulo, autor, editorial, precio) values ('El aleph','Borges','Emece',25.00); insert into libros (titulo, autor, editorial, precio) values ('Martin Fierro','Jose Hernandez','Planeta',35.50); insert into libros (titulo, autor, editorial, precio) values ('Aprenda PHP','Mario Molina','Emece',45.50); insert into libros (titulo, autor, editorial, precio) values ('Cervantes y el quijote','Borges','Emece',25);

insert into libros (titulo, autor, editorial, precio) values ('Matematica estas ahi','Paenza','Siglo XXI',15); select *from libros; update libros set autor='Adrian Paenza' where autor='Paenza'; update libros set autor='Adrian Paenza' where autor='Paenza'; update libros set precio=27 where autor='Mario Molina'; update libros set editorial='Emece S.A.'

where editorial='Emece';

10 - Comentarios
Para aclarar algunas instrucciones, en ocasiones, necesitamos agregar comentarios. Es posible ingresar comentarios en la lnea de comandos, es decir, un texto que no se ejecuta; para ello se emplean dos guiones (--): select *from libros;--mostramos los registros de libros en la lnea anterior, todo lo que est luego de los guiones (hacia la derecha) no se ejecuta. Para agregar varias lneas de comentarios, se coloca una barra seguida de un asterisco (/*) al comienzo del bloque de comentario y al finalizarlo, un asterisco seguido de una barra (*/) select titulo, autor /*mostramos ttulos y nombres de los autores*/ from libros; todo lo que est entre los smbolos "/*" y "*/" no se ejecuta.

11 - Valores nulos (null)


"null' significa "dato desconocido" o "valor inexistente". A veces, puede desconocerse o no existir el dato correspondiente a algn campo de un registro. En estos casos decimos que el campo puede contener valores nulos. Por ejemplo, en nuestra tabla de libros, podemos tener valores nulos en el campo "precio" porque es posible que para algunos libros no le hayamos establecido el precio para la venta. En contraposicin, tenemos campos que no pueden estar vacos jams.

Veamos un ejemplo. Tenemos nuestra tabla "libros". El campo "titulo" no debera estar vaco nunca, igualmente el campo "autor". Para ello, al crear la tabla, debemos especificar que tales campos no admitan valores nulos: create table libros( titulo varchar2(30) not null, autor varchar2(20) not null, editorial varchar2(15) null, precio number(5,2) ); Para especificar que un campo NO admita valores nulos, debemos colocar "not null" luego de la definicin del campo. En el ejemplo anterior, los campos "editorial" y "precio" si admiten valores nulos. Cuando colocamos "null" estamos diciendo que admite valores nulos (caso del campo "editorial"); por defecto, es decir, si no lo aclaramos, los campos permiten valores nulos (caso del campo "precio"). Cualquier campo, de cualquier tipo de dato permite ser definido para aceptar o no valores nulos. Un valor "null" NO es lo mismo que un valor 0 (cero) o una cadena de espacios en blanco (" "). Si ingresamos los datos de un libro, para el cual an no hemos definido el precio podemos colocar "null" para mostrar que no tiene precio: insert into libros (titulo,autor,editorial,precio) values('El aleph','Borges','Emece',null); Note que el valor "null" no es una cadena de caracteres, NO se coloca entre comillas. Entonces, si un campo acepta valores nulos, podemos ingresar "null" cuando no conocemos el valor. Tambin podemos colocar "null" en el campo "editorial" si desconocemos el nombre de la editorial a la cual pertenece el libro que vamos a ingresar: insert into libros (titulo,autor,editorial,precio) values('Alicia en el pais','Lewis Carroll',null,25); Una cadena vaca es interpretada por Oracle como valor nulo; por lo tanto, si ingresamos una cadena vaca, se almacena el valor "null". Si intentamos ingresar el valor "null" (o una cadena vaca) en campos que no admiten valores nulos (como "titulo" o "autor"), Oracle no lo permite, muestra un mensaje y la insercin no se realiza; por ejemplo: insert into libros (titulo,autor,editorial,precio) values(null,'Borges','Siglo XXI',25); Cuando vemos la estructura de una tabla con "describe", en la columna "Null", aparece "NOT NULL" si el campo no admite valores nulos y no aparece en caso que si los permita.

Para recuperar los registros que contengan el valor "null" en algn campo, no podemos utilizar los operadores relacionales vistos anteriormente: = (igual) y <> (distinto); debemos utilizar los operadores "is null" (es igual a null) y "is not null" (no es null). Los valores nulos no se muestran, aparece el campo vaco. Entonces, para que un campo no permita valores nulos debemos especificarlo luego de definir el campo, agregando "not null". Por defecto, los campos permiten valores nulos, pero podemos especificarlo igualmente agregando "null". Ejercicio 1: Primer problema: Una farmacia guarda informacin referente a sus medicamentos en una tabla llamada "medicamentos". 1- Elimine la tabla y crela con la siguiente estructura: drop table medicamentos; create table medicamentos( codigo number(5) not null, nombre varchar2(20) not null, laboratorio varchar2(20), precio number(5,2), cantidad number(3,0) not null ); 3- Visualice la estructura de la tabla "medicamentos" note que los campos "codigo", "nombre" y "cantidad", en la columna "Null" muestra "NOT NULL". 4- Ingrese algunos registros con valores "null" para los campos que lo admitan: insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(1,'Sertal gotas',null,null,100); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(2,'Sertal compuesto',null,8.90,150); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(3,'Buscapina','Roche',null,200); 5- Vea todos los registros. 6- Ingrese un registro con valor "0" para el precio y cadena vaca para el laboratorio. 7- Intente ingresar un registro con cadena vaca para el nombre (mensaje de error) 8- Intente ingresar un registro con valor nulo para un campo que no lo admite (aparece un mensaje de error) 9- Ingrese un registro con una cadena de 1 espacio para el laboratorio. 10- Recupere los registros cuyo laboratorio contenga 1 espacio (1 registro)

11- Recupere los registros cuyo laboratorio sea distinto de ' '(cadena de 1 espacio) (1 registro) Solucin: drop table medicamentos; create table medicamentos( codigo number(5) not null, nombre varchar2(20) not null, laboratorio varchar2(20), precio number(5,2), cantidad number(3,0) not null ); describe medicamentos; insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(1,'Sertal gotas',null,null,100); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(2,'Sertal compuesto',null,8.90,150); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(3,'Buscapina','Roche',null,200); select *from medicamentos; insert into medicamentos (codigo,nombre, laboratorio,precio,cantidad) values(4,'Bayaspirina','',0,150); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(0,'','Bayer',15.60,200); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(null,'Amoxidal jarabe','Bayer',25,120); insert into medicamentos (codigo,nombre, laboratorio,precio,cantidad) values(5,'Geniol',' ',0.5,200); select *from medicamentos where laboratorio=' '; select *from medicamentos where laboratorio<>' ';

Ejercicio 2: Segundo problema: Trabaje con la tabla que almacena los datos sobre pelculas, llamada "peliculas". 1- Elimine la tabla:

2- Crela con la siguiente estructura: create table peliculas( codigo number(4) not null, titulo varchar2(40) not null, actor varchar2(20), duracion number(3) ); 3- Visualice la estructura de la tabla. note que el campo "codigo" y "titulo", en la columna "Null" muestran "NOT NULL". 4- Ingrese los siguientes registros: insert into peliculas (codigo,titulo,actor,duracion) values(1,'Mision imposible','Tom Cruise',120); insert into peliculas (codigo,titulo,actor,duracion) values(2,'Harry Potter y la piedra filosofal',null,180); insert into peliculas (codigo,titulo,actor,duracion) values(3,'Harry Potter y la camara secreta','Daniel R.',null); insert into peliculas (codigo,titulo,actor,duracion) values(0,'Mision imposible 2','',150); insert into peliculas (codigo,titulo,actor,duracion) values(4,'Titanic','L. Di Caprio',220); insert into peliculas (codigo,titulo,actor,duracion) values(5,'Mujer bonita','R. Gere-J. Roberts',0); 5- Recupere todos los registros para ver cmo Oracle los almacen. 6- Intente ingresar un registro con valor nulo para campos que no lo admiten (aparece un mensaje de error) 7- Muestre todos los registros. 8- Actualice la pelcula en cuyo campo "duracion" hay 0 por "null" (1 registro) 9- Recupere todos los registros. Solucin: drop table peliculas; create table peliculas( codigo number(4) not null, titulo varchar2(40) not null, actor varchar2(20), duracion number(3) ); describe peliculas; insert into peliculas (codigo,titulo,actor,duracion)

values(1,'Mision imposible','Tom Cruise',120); insert into peliculas (codigo,titulo,actor,duracion) values(2,'Harry Potter y la piedra filosofal',null,180); insert into peliculas (codigo,titulo,actor,duracion) values(3,'Harry Potter y la camara secreta','Daniel R.',null); insert into peliculas (codigo,titulo,actor,duracion) values(0,'Mision imposible 2','',150); insert into peliculas (codigo,titulo,actor,duracion) values(4,'Titanic','L. Di Caprio',220); insert into peliculas (codigo,titulo,actor,duracion) values(5,'Mujer bonita','R. Gere-J. Roberts',0); select *from peliculas; insert into peliculas (codigo,titulo,actor,duracion) values(null,'Mujer bonita','R. Gere-J. Roberts',190); select *from peliculas; update peliculas set duracion=null where duracion=0; select *from peliculas;

12 - Operadores relacionales (is null)


Para recuperar los registros que contengan el valor "null" en algn campo, no podemos utilizar los operadores relacionales vistos anteriormente: = (igual) y <> (distinto); debemos utilizar los operadores "is null" (es igual a null) y "is not null" (no es null). Con la siguiente sentencia recuperamos los libros que contienen valor nulo en el campo "editorial": select *from libros where editorial is null; Recuerde que los valores nulos no se muestran, aparece el campo vaco. Las siguientes sentencias tendrn una salida diferente: select *from libros where editorial is null; select *from libros where editorial=' '; Con la primera sentencia veremos los libros cuya editorial almacena el valor "null" (desconocido); con la segunda, los libros cuya editorial guarda una cadena de 3 espacios en blanco. Para obtener los registros que no contienen "null", se puede emplear "is not null", esto mostrar los registros con valores conocidos. Para ver los libros que NO tienen valor "null" en el campo "precio" tipeamos:

select *from libros where precio is not null; Ejerccio 1: Primer problema: Una farmacia guarda informacin referente a sus medicamentos en una tabla llamada "medicamentos". 1- Elimine la tabla y crela con la siguiente estructura: drop table medicamentos; create table medicamentos( codigo number(5) not null, nombre varchar2(20) not null, laboratorio varchar2(20), precio number(5,2), cantidad number(3,0) not null ); 3- Visualice la estructura de la tabla "medicamentos" note que los campos "codigo", "nombre" y "cantidad", en la columna "Null" muestra "NOT NULL". 4- Ingrese algunos registros con valores "null" para los campos que lo admitan: insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(1,'Sertal gotas',null,null,100); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(2,'Sertal compuesto',null,8.90,150); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(3,'Buscapina','Roche',null,200); 5- Vea todos los registros. 6- Ingrese un registro con valor "0" para el precio y cadena vaca para el laboratorio. 7- Intente ingresar un registro con cadena vaca para el nombre (mensaje de error) 8- Intente ingresar un registro con valor nulo para un campo que no lo admite (aparece un mensaje de error) 9- Recupere los registros que contengan valor "null" en el campo "laboratorio" (3 registros) 10- Recupere los registros que contengan valor "null" en el campo "precio", luego los que tengan el valor 0 en el mismo campo. Note que el resultado es distinto (2 y 1 registros respectivamente) 11- Recupere los registros cuyo laboratorio no contenga valor nulo (1 registro) 12- Recupere los registros cuyo precio sea distinto de 0, luego los que sean distintos de "null" (1 y 2 resgistros respectivamente) Note que la salida de la primera sentencia no muestra los registros con valor 0 y tampoco los que

tienen valor nulo; el resultado de la segunda sentencia muestra los registros con valor para el campo precio (incluso el valor 0). 13- Ingrese un registro con una cadena de 1 espacio para el laboratorio. 14- Recupere los registros cuyo laboratorio sea "null" y luego los que contengan 1 espacio (3 y 1 registros respectivamente) Note que la salida de la primera sentencia no muestra los registros con valores para el campo "laboratorio" (un caracter espacio es un valor); el resultado de la segunda sentencia muestra los registros con el valor " " para el campo precio. 15- Recupere los registros cuyo laboratorio sea distinto de ' '(cadena de 1 espacio), luego los que sean distintos de "null" (1 y 2 registros respectivamente) Note que la salida de la primera sentencia no muestra los registros con valor ' ' y tampoco los que tienen valor nulo; el resultado de la segunda sentencia muestra los registros con valor para el campo laboratorio (incluso el valor ' ') Solucion: drop table medicamentos; create table medicamentos( codigo number(5) not null, nombre varchar2(20) not null, laboratorio varchar2(20), precio number(5,2), cantidad number(3,0) not null ); describe medicamentos; insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(1,'Sertal gotas',null,null,100); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(2,'Sertal compuesto',null,8.90,150); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(3,'Buscapina','Roche',null,200); select *from medicamentos; insert into medicamentos (codigo,nombre, laboratorio,precio,cantidad) values(4,'Bayaspirina','',0,150); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(0,'','Bayer',15.60,200); insert into medicamentos (codigo,nombre,laboratorio,precio,cantidad) values(null,'Amoxidal jarabe','Bayer',25,120); select *from medicamentos where laboratorio is null; select *from medicamentos where precio is null;

select *from medicamentos where precio=0; select *from medicamentos where laboratorio is not null; select *from medicamentos where precio<>0; select *from medicamentos where precio is not null; insert into medicamentos (codigo,nombre, laboratorio,precio,cantidad) values(5,'Geniol',' ',0.5,200); select *from medicamentos where laboratorio is null; select *from medicamentos where laboratorio=' '; select *from medicamentos where laboratorio<>' '; select *from medicamentos where laboratorio is not null; Ejercicio 2: Segundo problema: Trabaje con la tabla que almacena los datos sobre pelculas, llamada "peliculas". 1- Elimine la tabla: drop table peliculas; 2- Crela con la siguiente estructura: create table peliculas( codigo number(4) not null, titulo varchar2(40) not null, actor varchar2(20), duracion number(3) ); 3- Visualice la estructura de la tabla. note que el campo "codigo" y "titulo", en la columna "Null" muestran "NOT NULL". 4- Ingrese los siguientes registros: insert into peliculas (codigo,titulo,actor,duracion) values(1,'Mision imposible','Tom Cruise',120); insert into peliculas (codigo,titulo,actor,duracion) values(2,'Harry Potter y la piedra filosofal',null,180); insert into peliculas (codigo,titulo,actor,duracion) values(3,'Harry Potter y la camara secreta','Daniel R.',null); insert into peliculas (codigo,titulo,actor,duracion) values(0,'Mision imposible 2','',150); insert into peliculas (codigo,titulo,actor,duracion) values(4,'Titanic','L. Di Caprio',220); insert into peliculas (codigo,titulo,actor,duracion) values(5,'Mujer bonita','R. Gere-J. Roberts',0);

5- Recupere todos los registros para ver cmo Oracle los almacen. 6- Intente ingresar un registro con valor nulo para campos que no lo admiten (aparece un mensaje de error) 7- Muestre los registros con valor nulo en el campo "actor" (2 registros) 8- Actualice los registros que tengan valor de duracin desconocido (nulo) por "120" (1 registro actualizado) 9- Coloque 'Desconocido' en el campo "actor" en los registros que tengan valor nulo en dicho campo (2 registros) 10- Muestre todos los registros 11- Muestre todos los registros con valor nulo en el campo "actor" (ninguno) 12- Actualice la pelcula en cuyo campo "duracion" hay 0 por "null" (1 registro) 13- Recupere todos los registros. 14- Borre todos los registros en los cuales haya un valor nulo en "duracion" (1 registro) 15- Verifique que se elimin recuperando todos los registros. drop table peliculas; create table peliculas( codigo number(4) not null, titulo varchar2(40) not null, actor varchar2(20), duracion number(3) ); describe peliculas; insert into peliculas (codigo,titulo,actor,duracion) values(1,'Mision imposible','Tom Cruise',120); insert into peliculas (codigo,titulo,actor,duracion) values(2,'Harry Potter y la piedra filosofal',null,180); insert into peliculas (codigo,titulo,actor,duracion) values(3,'Harry Potter y la camara secreta','Daniel R.',null); insert into peliculas (codigo,titulo,actor,duracion) values(0,'Mision imposible 2','',150); insert into peliculas (codigo,titulo,actor,duracion) values(4,'Titanic','L. Di Caprio',220); insert into peliculas (codigo,titulo,actor,duracion) values(5,'Mujer bonita','R. Gere-J. Roberts',0); select *from peliculas; insert into peliculas (codigo,titulo,actor,duracion)

values(null,'Mujer bonita','R. Gere-J. Roberts',190); select *from peliculas where actor is null; update peliculas set duracion=120 where duracion is null; update peliculas set actor='Desconocido' where actor is null; select *from peliculas; select *from peliculas where actor is null; update peliculas set duracion=null where duracion=0; select *from peliculas; delete from peliculas where duracion is null; select *from peliculas;

13 - Clave primaria (primary key)


Una clave primaria es un campo (o varios) que identifica un solo registro (fila) en una tabla. Para un valor del campo clave existe solamente un registro. Veamos un ejemplo, si tenemos una tabla con datos de personas, el nmero de documento puede establecerse como clave primaria, es un valor que no se repite; puede haber personas con igual apellido y nombre, incluso el mismo domicilio (padre e hijo por ejemplo), pero su documento ser siempre distinto. Si tenemos la tabla "usuarios", el nombre de cada usuario puede establecerse como clave primaria, es un valor que no se repite; puede haber usuarios con igual clave, pero su nombre de usuario ser siempre diferente. Podemos establecer que un campo sea clave primaria al momento de crear la tabla o luego que ha sido creada. Vamos a aprender a establecerla al crear la tabla. No existe una nica manera de hacerlo, por ahora veremos la sintaxis ms sencilla. Tenemos nuestra tabla "usuarios" definida con 2 campos ("nombre" y "clave"). La sintaxis bsica y general es la siguiente: create table NOMBRETABLA( CAMPO TIPO, ..., CAMPO TIPO, PRIMARY KEY (CAMPO) );

Lo que hacemos agregar, luego de la definicin de cada campo, "primary key" y entre parntesis, el nombre del campo que ser clave primaria. En el siguiente ejemplo definimos una clave primaria, para nuestra tabla "usuarios" para asegurarnos que cada usuario tendr un nombre diferente y nico: create table usuarios( nombre varchar2(20), clave varchar2(10), primary key(nombre) ); Una tabla slo puede tener una clave primaria. Cualquier campo (de cualquier tipo) puede ser clave primaria, debe cumplir como requisito, que sus valores no se repitan ni sean nulos. Por ello, al definir un campo como clave primaria, automticamente Oracle lo convierte a "not null". Luego de haber establecido un campo como clave primaria, al ingresar los registros, Oracle controla que los valores para el campo establecido como clave primaria no estn repetidos en la tabla; si estuviesen repetidos, muestra un mensaje y la insercin no se realiza. Es decir, si en nuestra tabla "usuarios" ya existe un usuario con nombre "juanperez" e intentamos ingresar un nuevo usuario con nombre "juanperez", aparece un mensaje y la instruccin "insert" no se ejecuta. Igualmente, si realizamos una actualizacin, Oracle controla que los valores para el campo establecido como clave primaria no estn repetidos en la tabla, si lo estuviese, aparece un mensaje indicando que se viola la clave primaria y la actualizacin no se realiza. Podemos ver el campo establecido como clave primaria de una tabla realizando la siguiente consulta: select uc.table_name, column_name from user_cons_columns ucc join user_constraints uc on ucc.constraint_name=uc.constraint_name where uc.constraint_type='P' and uc.table_name='USUARIOS'; No explicaremos la consulta anterior por el momento, slo la ejecutaremos; si la consulta retorna una tabla vaca, significa que la tabla especificada no tiene clave primaria. El nombre de la tabla DEBE ir en maysculas, sino Oracle no la encontrar.

Ejercicio 1: Primer problema: Trabaje con la tabla "libros" de una librera. 1- Elimine la tabla: drop table libros; 2- Crela con los siguientes campos, estableciendo como clave primaria el campo "codigo":

create table libros( codigo number(4) not null, titulo varchar2(40) not null, autor varchar2(20), editorial varchar2(15), primary key (codigo) ); 3- Ingrese los siguientes registros: insert into libros (codigo,titulo,autor,editorial) values (1,'El aleph','Borges','Emece'); insert into libros (codigo,titulo,autor,editorial) values (2,'Martin Fierro','Jose Hernandez','Planeta'); insert into libros (codigo,titulo,autor,editorial) values (3,'Aprenda PHP','Mario Molina','Nuevo Siglo'); 4- Ingrese un registro con cdigo repetido (aparece un mensaje de error) 5- Intente ingresar el valor "null" en el campo "codigo" 6- Intente actualizar el cdigo del libro "Martin Fierro" a "1" (mensaje de error) 7- Actualice el cdigo del libro "Martin Fierro" a "10" 8- Vea qu campo de la tabla "LIBROS" fue establecido como clave primaria 9- Vea qu campo de la tabla "libros" (en minsculas) fue establecido como clave primaria La tabla aparece vaca porque Oracle no encuentra la tabla "libros", ya que almacena los nombres de las tablas con maysculas.

Solucin: drop table libros; create table libros( codigo number(4) not null, titulo varchar2(40) not null, autor varchar2(20), editorial varchar2(15), primary key (codigo) );

insert into libros (codigo,titulo,autor,editorial) values (1,'El aleph','Borges','Emece'); insert into libros (codigo,titulo,autor,editorial) values (2,'Martin Fierro','Jose Hernandez','Planeta'); insert into libros (codigo,titulo,autor,editorial) values (3,'Aprenda PHP','Mario Molina','Nuevo Siglo'); insert into libros (codigo,titulo,autor,editorial) values (2,'Alicia en el pais de las maravillas','Lewis Carroll','Planeta'); insert into libros (codigo,titulo,autor,editorial) values (null,'Alicia en el pais de las maravillas','Lewis Carroll','Planeta'); update libros set codigo=1 where titulo='Martin Fierro'; update libros set codigo=10 where titulo='Martin Fierro'; select uc.table_name, column_name from user_cons_columns ucc join user_constraints uc on ucc.constraint_name=uc.constraint_name where uc.constraint_type='P' and uc.table_name='LIBROS'; select uc.table_name, column_name from user_cons_columns ucc join user_constraints uc on ucc.constraint_name=uc.constraint_name where uc.constraint_type='P' and uc.table_name='libros'; Ejercicio 2: Segundo problema: Un instituto de enseanza almacena los datos de sus estudiantes en una tabla llamada "alumnos". 1- Elimine la tabla "alumnos": drop table alumnos; 2- Cree la tabla con la siguiente estructura intentando establecer 2 campos como clave primaria, el campo "documento" y "legajo": create table alumnos( legajo varchar2(4) not null, documento varchar2(8), nombre varchar2(30), domicilio varchar2(30), primary key(codigo), primary key(documento) );

Un mensaje indica la tabla solamente puede tener UNA clave primaria. 3- Cree la tabla estableciendo como clave primaria el campo "documento": create table alumnos( legajo varchar2(4) not null, documento varchar2(8), nombre varchar2(30), domicilio varchar2(30), primary key(documento) ); 4- Verifique que el campo "documento" no admite valores nulos 5- Ingrese los siguientes registros: insert into alumnos (legajo,documento,nombre,domicilio) values('A233','22345345','Perez Mariana','Colon 234'); insert into alumnos (legajo,documento,nombre,domicilio) values('A567','23545345','Morales Marcos','Avellaneda 348'); 6- Intente ingresar un alumno con nmero de documento existente (no lo permite) 7- Intente ingresar un alumno con documento nulo (no lo permite) 8- Vea el campo clave primaria de "ALUMNOS". Solucin 2: drop table alumnos; create table alumnos( legajo varchar2(4) not null, documento varchar2(8), nombre varchar2(30), domicilio varchar2(30), primary key(codigo), primary key(documento) ); create table alumnos( legajo varchar2(4) not null, documento varchar2(8), nombre varchar2(30), domicilio varchar2(30), primary key(documento) ); describe alumnos; insert into alumnos (legajo,documento,nombre,domicilio) values('A233','22345345','Perez Mariana','Colon 234');

insert into alumnos (legajo,documento,nombre,domicilio) values('A567','23545345','Morales Marcos','Avellaneda 348'); insert into alumnos (legajo,documento,nombre,domicilio) values('A642','23545345','Gonzalez Analia','Caseros 444'); insert into alumnos (legajo,documento,nombre,domicilio) values('A685',null,'Miranda Carmen','Uspallata 999'); select uc.table_name, column_name from user_cons_columns ucc join user_constraints uc on ucc.constraint_name=uc.constraint_name where uc.constraint_type='P' and uc.table_name='ALUMNOS';

14 - Vaciar la tabla (truncate table)


Aprendimos que para borrar todos los registro de una tabla se usa "delete" sin condicin "where". Tambin podemos eliminar todos los registros de una tabla con "truncate table". Sintaxis: truncate table NOMBRETABLA; Por ejemplo, queremos vaciar la tabla "libros", usamos: truncate table libros; La sentencia "truncate table" vaca la tabla (elimina todos los registros) y conserva la estructura de la tabla. La diferencia con "drop table" es que esta sentencia elimina la tabla, no solamente los registros, "truncate table" la vaca de registros. La diferencia con "delete" es la siguiente, al emplear "delete", Oracle guarda una copia de los registros borrados y son recuperables, con "truncate table" no es posible la recuperacin porque se libera todo el espacio en disco ocupado por la tabla; por lo tanto, "truncate table" es ms rpido que "delete" (se nota cuando la cantidad de registros es muy grande).

15 - Tipos de datos alfanumricos


Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto es, definir los campos y sus tipos ms precisos, segn el caso. Para almacenar valores alfanumricos (texto) usamos cadenas de caracteres. Las cadenas se colocan entre comillas simples. Podemos almacenar letras, smbolos y dgitos con los que no se realizan operaciones matemticas, por ejemplo, cdigos de identificacin, nmeros de documentos, nmeros telefnicos. Tenemos los siguientes tipos:

1) char(x): define una cadena de caracteres de longitud fija determinada por el argumento "x". Si se omite el argumento, por defecto coloca 1. "char" viene de character, que significa caracter en ingls. Su rango es de 1 a 2000 caracteres. Que sea una cadena de longitud fija significa que, si definimos un campo como "char(10)" y almacenamos el valor "hola" (4 caracteres), Oracle rellenar las 6 posiciones restantes con espacios, es decir, ocupar las 10 posiciones; por lo tanto, si la longitud es invariable, es conveniente utilizar el tipo char; caso contrario, el tipo varchar2. Si almacenamos "hola" en un campo definido "char(10)" Oracle almacenar "hola ". 2) varchar2(x): almacena cadenas de caracteres de longitud variable determinada por el argumento "x" (obligatorio). Que sea una cadena de longitud variable significa que, si definimos un campo como "varchar2(10)" y almacenamos el valor "hola" (4 caracteres), Oracle solamente ocupa las 4 posiciones (4 bytes y no 10 como en el caso de "char"); por lo tanto, si la longitud es variable, es conveniente utilizar este tipo de dato y no "char", as ocupamos menos espacio de almacenamiento en disco. Su rango es de 1 a 4000 caracteres. 3) nchar(x): es similar a "char" excepto que permite almacenar caracteres ASCII, EBCDIC y Unicode; su rango va de 1 a 1000 caracteres porque se emplean 2 bytes por cada caracter. 4) nvarchar2(x): es similar a "varchar2", excepto que permite almacenar caracteres Unicode; su rango va de 1 a 2000 caracteres porque se emplean 2 bytes por cada caracter. 5 y 6) varchar(x) y char2(x): disponibles en Oracle8. 7) long: guarda caracteres de longitud variable; puede contener hasta 2000000000 caracteres (2 Gb). No admite argumento para especificar su longitud. En Oracle8 y siguientes versiones conviene emplear "clob" y "nlob" para almacenar grandes cantidades de datos alfanumricos. En general se usarn los 2 primeros. Si intentamos almacenar en un campo alfanumrico una cadena de caracteres de mayor longitud que la definida, aparece un mensaje indicando que el valor es demasiado grande y la sentencia no se ejecuta. Por ejemplo, si definimos un campo de tipo varchar2(10) y le asignamos la cadena 'Aprenda PHP' (11 caracteres), aparece un mensaje y la sentencia no se ejecuta. Si ingresamos un valor numrico (omitiendo las comillas), lo convierte a cadena y lo ingresa como tal. Por ejemplo, si en un campo definido como varchar2(5) ingresamos el valor 12345, lo toma como si hubisemos tipeado '12345', igualmente, si ingresamos el valor 23.56, lo convierte a '23.56'. Si el valor numrico, al ser convertido a cadena supera la longitud definida, aparece un mensaje de error y la sentencia no se ejecuta. Es importante elegir el tipo de dato adecuado segn el caso. Para almacenar cadenas que varan en su longitud, es decir, no todos los registros tendrn la misma longitud en un campo determinado, se emplea "varchar2" en lugar de "char". Por ejemplo, en campos que guardamos nombres y apellidos, no todos los nombres y apellidos tienen la misma longitud.

Para almacenar cadenas que no varan en su longitud, es decir, todos los registros tendrn la misma longitud en un campo determinado, se emplea "char". Por ejemplo, definimos un campo "codigo" que constar de 5 caracteres, todos los registros tendrn un cdigo de 5 caracteres, ni ms ni menos. Para almacenar valores superiores a 4000 caracteres se debe emplear "long". Ejercicio 1: Primer problema: Una concesionaria de autos vende autos usados y almacena los datos de los autos en una tabla llamada "autos". 1- Elimine la tabla "autos" 2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo, estableciendo el campo "patente" como clave primaria: create table autos( patente char(6), marca varchar2(20), modelo char(4), precio number(8,2), primary key (patente) ); Hemos definido el campo "patente" de tipo "char" y no "varchar2" porque la cadena de caracteres siempre tendr la misma longitud (6 caracteres). Lo mismo sucede con el campo "modelo", en el cual almacenaremos el ao, necesitamos 4 caracteres fijos. 3- Ingrese los siguientes registros: insert into autos (patente,marca,modelo,precio) values('ABC123','Fiat 128','1970',15000); insert into autos (patente,marca,modelo,precio) values('BCD456','Renault 11','1990',40000); insert into autos (patente,marca,modelo,precio) values('CDE789','Peugeot 505','1990',80000); insert into autos (patente,marca,modelo,precio) values('DEF012','Renault Megane','1998',95000); 4- Ingrese un registro omitiendo las comillas en el valor de "modelo" Oracle convierte el valor a cadena. 5- Vea cmo se almacen. 6- Seleccione todos los autos modelo "1990" 7- Intente ingresar un registro con un valor de patente de 7 caracteres

8- Intente ingresar un registro con valor de patente repetida. drop table autos; create table autos( patente char(6), marca varchar2(20), modelo char(4), precio number(8,2), primary key (patente) ); insert into autos (patente,marca,modelo,precio) values('ABC123','Fiat 128','1970',15000); insert into autos (patente,marca,modelo,precio) values('BCD456','Renault 11','1990',40000); insert into autos (patente,marca,modelo,precio) values('CDE789','Peugeot 505','1990',80000); insert into autos (patente,marca,modelo,precio) values('DEF012','Renault Megane','1998',95000); insert into autos (patente,marca,modelo,precio) values('HIJ678','Renault Clio',1990,70000); select *from autos; select *from autos where modelo='1990'; insert into autos (patente,marca,modelo,precio) values('FGH3457','Fiat 128','1975',20000); insert into autos (patente,marca,modelo,precio)

values('HIJ678','Fiat 128','1975',20000);
Segundo problema: Una empresa almacena los datos de sus clientes en una tabla llamada "clientes". 1- Elimine la tabla "clientes" 2- Crela eligiendo el tipo de dato ms adecuado para cada campo: create table clientes( documento char(8) not null, apellido varchar2(20), nombre varchar2(20), domicilio varchar2(30), telefono varchar2 (11) );

3- Analice la definicin de los campos. Se utiliza char(8) para el documento porque siempre constar de 8 caracteres. Para el nmero telefnico se usar "varchar2" y no un tipo numrico porque si bien es un nmero, con l no se realizarn operaciones matemticas. 4- Ingrese algunos registros: insert into clientes (documento,apellido,nombre,domicilio,telefono) values('22333444','Perez','Juan','Sarmiento 980','4223344'); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('23444555','Perez','Ana','Colon 234',null); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('30444555','Garcia','Luciana','Caseros 634',null); 5- Intente ingresar un registro con ms caracteres que los permitidos para el campo "telefono" 6- Intente ingresar un registro con ms caracteres que los permitidos para el campo "documento" 7- Intente ingresar un registro omitiendo las comillas en el campo "apellido" 8- Seleccione todos los clientes de apellido "Perez" (2 registros) Solucin: drop table clientes; create table clientes( documento char(8) not null, apellido varchar2(20), nombre varchar2(20), domicilio varchar2(30), telefono varchar2 (11) ); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('22333444','Perez','Juan','Sarmiento 980','4223344'); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('23444555','Perez','Ana','Colon 234',null); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('30444555','Garcia','Luciana','Caseros 634',null); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('24555666','Juarez','Ana','Urquiza 444','035145566778'); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('256667778','Garcia','Luis','Avellaneda 1454','4558877'); insert into clientes (documento,apellido,nombre,domicilio,telefono) values('25666777',Garcia,'Luis','Avellaneda 1454','4558877'); select *from clientes

where apellido='Perez';

16 - Tipos de datos numricos


Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto es, definir los campos y sus tipos ms precisos, segn el caso. Los valores numricos no se ingresan entre comillas. Se utiliza el punto como separador de decimales. Para almacenar valores NUMERICOS Oracle dispone de dos tipos de datos: 1) number(t,d): para almacenar valores enteros o decimales, positivos o negativos. Su rango va de 1.0 x 10-130 hasta 9.999...(38 nueves). Definimos campos de este tipo cuando queremos almacenar valores numricos con los cuales luego realizaremos operaciones matemticas, por ejemplo, cantidades, precios, etc. El parmetro "t" indica el nmero total de dgitos (contando los decimales) que contendr el nmero como mximo (es la precisin). Su rango va de 1 a 38. El parmetro "d" indica el mximo de dgitos decimales (escala). La escala puede ir de -84 a 127. Para definir nmero enteros, se puede omitir el parmetro "d" o colocar un 0. Un campo definido "number(5,2)" puede contener cualquier nmero entre -999.99 y 999.99. Para especificar nmero enteros, podemos omitir el parmetro "d" o colocar el valor 0. Si intentamos almacenar un valor mayor fuera del rango permitido al definirlo, tal valor no se carga, aparece un mensaje indicando tal situacin y la sentencia no se ejecuta. Por ejemplo, si definimos un campo de tipo "number(4,2)" e intentamos guardar el valor 123.45, aparece un mensaje indicando que el valor es demasiado grande para la columna. Si ingresamos un valor con ms decimales que los definidos, el valor se carga pero con la cantidad de decimales permitidos, los dgitos sobrantes se omiten. 2) float (x): almacena un nmero en punto decimal. El parmetro indica la precisin binaria mxima; con un rango de 1 a 126. Si se omite, por defecto es 126. Para ambos tipos numricos: - si ingresamos un valor con ms decimales que los permitidos, redondea al ms cercano; por ejemplo, si definimos "float(4,2)" e ingresamos el valor "12.686", guardar "12.69", redondeando hacia arriba; si ingresamos el valor "12.682", guardar "12.67", redondeando hacia abajo. - si intentamos ingresar un valor fuera de rango, no lo acepta. - si ingresamos una cadena, Oracle intenta convertirla a valor numrico, si dicha cadena consta solamente de dgitos, la conversin se realiza, luego verifica si est dentro del rango, si es as, la ingresa, sino, muestra un mensaje de error y no ejecuta la sentencia. Si la cadena contiene caracteres que Oracle no puede convertir a valor numrico, muestra un mensaje de error y la sentencia no se ejecuta. Por ejemplo, definimos un campo de tipo "numberl(5,2)", si ingresamos la cadena '12.22', la convierte al valor numrico 12.22 y la ingresa; si intentamos ingresar la cadena '1234.56', la convierte al valor numrico 1234.56, pero como el mximo valor permitido es 999.99, muestra un mensaje indicando que est fuera de rango. Si intentamos ingresar el valor '12y.25', Oracle no puede realizar la conversin y muestra un mensaje de error.

Ejercicio 1: Primer problema: Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla llamada "cuentas". La tabla contiene estos datos: Nmero de Cuenta Documento Nombre Saldo ______________________________________________________________ 1234 25666777 Pedro Perez 500000.60 2234 27888999 Juan Lopez -250000 3344 27888999 Juan Lopez 4000.50 3346 32111222 Susana Molina 1000 1- Elimine la tabla "cuentas": drop table cuentas; 2- Cree la tabla eligiendo el tipo de dato adecuado para almacenar los datos descriptos arriba: - Nmero de cuenta: entero hasta 9999, no nulo, no puede haber valores repetidos, clave primaria; - Documento del propietario de la cuenta: cadena de caracteres de 8 de longitud (siempre 8), no nulo; - Nombre del propietario de la cuenta: cadena de caracteres de 30 de longitud, - Saldo de la cuenta: valores que no superan 999999.99 create table cuentas( numero number(4) not null, documento char(8), nombre varchar2(30), saldo number(8,2), primary key (numero) ); 3- Ingrese los siguientes registros: insert into cuentas(numero,documento,nombre,saldo) values('1234','25666777','Pedro Perez',500000.60); insert into cuentas(numero,documento,nombre,saldo) values('2234','27888999','Juan Lopez',-250000); insert into cuentas(numero,documento,nombre,saldo) values('3344','27888999','Juan Lopez',4000.50); insert into cuentas(numero,documento,nombre,saldo) values('3346','32111222','Susana Molina',1000); Note que hay dos cuentas, con distinto nmero de cuenta, de la misma persona. 4- Seleccione todos los registros cuyo saldo sea mayor a "4000" (2 registros)

5- Muestre el nmero de cuenta y saldo de todas las cuentas cuyo propietario sea "Juan Lopez" (2 registros) 6- Muestre las cuentas con saldo negativo (1 registro) 7- Muestre todas las cuentas cuyo nmero es igual o mayor a "3000" (2 registros) Solucin: drop table cuentas; create table cuentas( numero number(4) not null, documento char(8), nombre varchar2(30), saldo number(8,2), primary key (numero) ); insert into cuentas(numero,documento,nombre,saldo) values('1234','25666777','Pedro Perez',500000.60); insert into cuentas(numero,documento,nombre,saldo) values('2234','27888999','Juan Lopez',-250000); insert into cuentas(numero,documento,nombre,saldo) values('3344','27888999','Juan Lopez',4000.50); insert into cuentas(numero,documento,nombre,saldo) values('3346','32111222','Susana Molina',1000); select *from cuentas where saldo<4000; select numero,saldo from cuentas where nombre='Juan Lopez'; select *from cuentas where saldo<0; select *from cuentas

where numero>=3000; Ejercicio 2:


Segundo problema: Una empresa almacena los datos de sus empleados en una tabla "empleados" que guarda los siguientes datos: nombre, documento, sexo, domicilio, sueldobasico. 1- Elimine la tabla: drop table empleados;

2- Cree la tabla eligiendo el tipo de dato adecuado para cada campo: create table empleados( nombre varchar2(30), documento char(8), sexo char(1), domicilio varchar2(30), sueldobasico numberl(7,2),--mximo estimado 99999.99 cantidadhijos number(2)--no superar los 99 ); 3- Ingrese algunos registros: insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Juan Perez','22333444','m','Sarmiento 123',500,2); insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Ana Acosta','24555666','f','Colon 134',850,0); insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Bartolome Barrios','27888999','m','Urquiza 479',10000.80,4); 4- Ingrese un valor de "sueldobasico" con ms decimales que los definidos (redondea los decimales al valor ms cercano 800.89) 5- Intente ingresar un sueldo que supere los 7 dgitos (no lo permite) 6- Muestre todos los empleados cuyo sueldo no supere los 900 pesos 7- Seleccione los nombres de los empleados que tengan hijos (3 registros) Solucin: drop table empleados; create table empleados( nombre varchar2(30), documento char(8), sexo char(1), domicilio varchar2(30), sueldobasico numberl(7,2),--mximo estimado 99999.99 cantidadhijos number(2)--no superar los 99 ); insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Juan Perez','22333444','m','Sarmiento 123',500,2); insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Ana Acosta','24555666','f','Colon 134',850,0); insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Bartolome Barrios','27888999','m','Urquiza 479',10000.80,4); insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Susana Molina','29000555','f','Salta 876',800.888,3);

insert into empleados (nombre,documento,sexo,domicilio,sueldobasico,cantidadhijos) values ('Marta Juarez','32444555','f','Sucre 1086',5000000,2); select *from empleados where sueldobasico<=900; select *from empleados

where cantidadhijos>0;

17 - Ingresar algunos campos


Hemos aprendido a ingresar registros listando todos los campos y colocando valores para todos y cada uno de ellos luego de "values". Si ingresamos valores para todos los campos, podemos omitir la lista de nombres de los campos. Por ejemplo, si tenemos creada la tabla "libros" con los campos "titulo", "autor" y "editorial", podemos ingresar un registro de la siguiente manera: insert into libros values ('Uno','Richard Bach','Planeta'); Tambin es posible ingresar valores para algunos campos. Ingresamos valores solamente para los campos "titulo" y "autor": insert into libros (titulo, autor) values ('El aleph','Borges'); Oracle almacenar el valor "null" en el campo "editorial", para el cual no hemos explicitado un valor. Al ingresar registros debemos tener en cuenta: - la lista de campos debe coincidir en cantidad y tipo de valores con la lista de valores luego de "values". Si se listan ms (o menos) campos que los valores ingresados, aparece un mensaje de error y la sentencia no se ejecuta. - si ingresamos valores para todos los campos podemos obviar la lista de campos. - podemos omitir valores para los campos que permitan valores nulos (se guardar "null"); si omitimos el valor para un campo "not null", la sentencia no se ejecuta. Ejercicio 1: Primer problema: Un banco tiene registrados las cuentas corrientes de sus clientes en una tabla llamada "cuentas". 1- Elimine la tabla "cuentas": drop table cuentas;

2- Cree la tabla : create table cuentas( numero number(10) not null, documento char(8) not null, nombre varchar2(30), saldo number(9,2) ); 3- Ingrese un registro con valores para todos sus campos, omitiendo la lista de campos. 4- Ingrese un registro omitiendo algn campo que admita valores nulos. 5- Verifique que en tal campo se almacen "null" 6- Intente ingresar un registro listando 3 campos y colocando 4 valores. Un mensaje indica que hay demasiados valores. 7- Intente ingresar un registro listando 3 campos y colocando 2 valores. Un mensaje indica que no hay suficientes valores. 8- Intente ingresar un registro sin valor para un campo definido "not null". 9- Vea los registros ingresados.

Solucion: drop table cuentas; create table cuentas( numero number(10) not null, documento char(8) not null, nombre varchar2(30), saldo number(9,2) ); insert into cuentas values (12345,'30111111','Juan Perez',2500.50); insert into cuentas (numero,documento,saldo) values (23456,'28999777',-5500); select *from cuentas;

insert into cuentas (numero,documento,nombre) values (44444,'28999777','Luis Lopez',34000); insert into cuentas (numero,documento,nombre) values (44444,'28999777'); insert into cuentas (numero,nombre,saldo) values (555,'Luis Lopez',34000); select *from cuentas;

18 - Valores por defecto (default)


Hemos visto que si al insertar registros no se especifica un valor para un campo que admite valores nulos, se ingresa automticamente "null". A este valor se le denomina valor por defecto o predeterminado. Un valor por defecto se inserta cuando no est presente al ingresar un registro. Para campos de cualquier tipo no declarados "not null", es decir, que admiten valores nulos, el valor por defecto es "null". Para campos declarados "not null", no existe valor por defecto, a menos que se declare explcitamente con la clusula "default". Podemos establecer valores por defecto para los campos cuando creamos la tabla. Para ello utilizamos "default" al definir el campo. Por ejemplo, queremos que el valor por defecto del campo "autor" de la tabla "libros" sea "Desconocido" y el valor por defecto del campo "cantidad" sea "0": create table libros( titulo varchar2(40) not null, autor varchar2(30) default 'Desconocido' not null, editorial varchar2(20), precio number(5,2), cantidad number(3) default 0 ); Si al ingresar un nuevo registro omitimos los valores para el campo "autor" y "cantidad", Oracle insertar los valores por defecto; en "autor" colocar "Desconocido" y en cantidad "0". Entonces, si al definir el campo explicitamos un valor mediante la clusula "default", se ser el valor por defecto. La clusula "default" debe ir antes de "not null" (si existiese), sino aparece un mensaje de error. Para ver si los campos de la tabla "libros" tiene definidos valores por defecto y cules son, podemos realizar la siguiente consulta: select column_name,nullable,data_default from user_tab_columns where TABLE_NAME = 'libros';

Muestra una fila por cada campo, en la columna "data_default" aparece el valor por defecto (si lo tiene), en la columna "nullable" aparece "N" si el campo no est definido "not null" y "Y" si admite valores "null". Tambin se puede utilizar "default" para dar el valor por defecto a los campos en sentencias "insert", por ejemplo: insert into libros (titulo,autor,editorial,precio,cantidad) values ('El gato con botas',default,default,default,100); Entonces, la clusula "default" permite especificar el valor por defecto de un campo. Si no se explicita, el valor por defecto es "null", siempre que el campo no haya sido declarado "not null". Los campos para los cuales no se ingresan valores en un "insert" tomarn los valores por defecto: - si permite valores nulos y no tiene clusula "default", almacenar "null"; - si tiene clusula "default" (admita o no valores nulos), el valor definido como predeterminado; - si est declarado explcitamente "not null" y no tiene valor "default", no hay valor por defecto, as que causar un error y el "insert" no se ejecutar. Un campo slo puede tener un valor por defecto. Una tabla puede tener todos sus campos con valores por defecto. Que un campo tenga valor por defecto no significa que no admita valores nulos, puede o no admitirlos. Un campo definido como clave primaria acepta un valor "default", pero no tiene sentido ya que el valor por defecto solamente podr ingresarse una vez; si intenta ingresarse cuando otro registro ya lo tiene almacenado, aparecer un mensaje de error indicando que se intenta duplicar la clave.

Ejercicio 1: Primer problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos. 1- Elimine la tabla "visitantes" 2- Cree la tabla con la siguiente estructura: create table visitantes( nombre varchar2(30), edad number(2),

sexo char(1) default 'f', domicilio varchar2(30), ciudad varchar2(20) default 'Cordoba', telefono varchar(11), mail varchar(30) default 'no tiene', montocompra number (6,2) ); 4- Analice la informacin que retorna la siguiente consulta: select column_name,nullable,data_default from user_tab_columns where TABLE_NAME = 'VISITANTES'; Todos los campos admiten valores nulos; hay 3 campos con valores predeterminados. 5- Ingrese algunos registros sin especificar valores para algunos campos para ver cmo opera la clusula "default": insert into visitantes (domicilio,ciudad,telefono,mail,montocompra) values ('Colon 123','Cordoba','4334455','juanlopez@hotmail.com',59.80); insert into visitantes (nombre,edad,sexo,telefono,mail,montocompra) values ('Marcos Torres',29,'m','4112233','marcostorres@hotmail.com',60); insert into visitantes (nombre,edad,sexo,domicilio,ciudad) values ('Susana Molina',43,'f','Bulnes 345','Carlos Paz'); 6- Recupere todos los registros. Los campos de aquellos registros para los cuales no se ingres valor almacenaron el valor por defecto ("null" o el especificado con "default"). 7- Use la palabra "default" para ingresar valores en un "insert" 8- Recupere el registro anteriormente ingresado.

Solucion: drop table visitantes; create table visitantes( nombre varchar2(30), edad number(2), sexo char(1) default 'f', domicilio varchar2(30), ciudad varchar2(20) default 'Cordoba', telefono varchar(11), mail varchar(30) default 'no tiene', montocompra number (6,2) ); select column_name,nullable,data_default

from user_tab_columns where TABLE_NAME = 'VISITANTES'; insert into visitantes (domicilio,ciudad,telefono,mail,montocompra) values ('Colon 123','Cordoba','4334455','juanlopez@hotmail.com',59.80); insert into visitantes (nombre,edad,sexo,telefono,mail,montocompra) values ('Marcos Torres',29,'m','4112233','marcostorres@hotmail.com',60); insert into visitantes (nombre,edad,sexo,domicilio,ciudad) values ('Susana Molina',43,'f','Bulnes 345','Carlos Paz'); select *from visitantes; insert into visitantes values ('Marcela Morales',default,default,'Avellaneda 292',default,'4255232',default,default);

select *from visitantes where nombre='Marcela Morales';

19 - Operadores aritmticos y de concatenacin (columnas calculadas)


Aprendimos que los operadores son smbolos que permiten realizar distintos tipos de operaciones. Dijimos que Oracle tiene 4 tipos de operadores: 1) relacionales o de comparacin (los vimos), 2) aritmticos, 3) de concatenacin y 4) lgicos (lo veremos ms adelante). Los operadores aritmticos permiten realizar clculos con valores numricos. Son: multiplicacin (*), divisin (/), suma (+) y resta (-). Es posible obtener salidas en las cuales una columna sea el resultado de un clculo y no un campo de una tabla. Si queremos ver los ttulos, precio y cantidad de cada libro escribimos la siguiente sentencia: select titulo,precio,cantidad from libros; Si queremos saber el monto total en dinero de un ttulo podemos multiplicar el precio por la cantidad por cada ttulo, pero tambin podemos hacer que Oracle realice el clculo y lo incluya en una columna extra en la salida: select titulo, precio,cantidad, precio*cantidad from libros; Si queremos saber el precio de cada libro con un 10% de descuento podemos incluir en la sentencia los siguientes clculos: select titulo,precio, precio-(precio*0.1) from libros;

Tambin podemos actualizar los datos empleando operadores aritmticos: update libros set precio=precio-(precio*0.1); Para concatenar cadenas de caracteres existe el operador de concatenacin ||. Para concatenar el ttulo y el autor de cada libro usamos el operador de concatenacin ("||"): select titulo||'-'||autor from libros; Note que concatenamos adems un guin para separar los campos. Oracle puede convertir automticamente valores numricos a cadenas para una concatenacin; por ejemplo, en el siguiente ejemplo mostramos el ttulo y precio de cada libro concatenado con el operador "||": select titulo||' $'||precio from libros; Ejercicio 1: Primer problema: Un comercio que vende artculos de computacin registra los datos de sus artculos en una tabla con ese nombre. 1- Elimine la tabla: drop table articulos; 2- Cree la tabla: create table articulos( codigo number(4), nombre varchar2(20), descripcion varchar2(30), precio number(8,2), cantidad number(3) default 0, primary key (codigo) ); 3- Ingrese algunos registros: insert into articulos values (101,'impresora','Epson Stylus C45',400.80,20); insert into articulos values (203,'impresora','Epson Stylus C85',500,30); insert into articulos values (205,'monitor','Samsung 14',800,10); insert into articulos values (300,'teclado','ingles Biswal',100,50);

4- El comercio quiere aumentar los precios de todos sus artculos en un 15%. Actualice todos los precios empleando operadores aritmticos. 5- Vea el resultado. 6- Muestre todos los artculos, concatenando el nombre y la descripcin de cada uno de ellos separados por coma. 7- Reste a la cantidad de todas las impresoras, el valor 5, empleando el operador aritmtico menos ("-") 8- Recupere todos los datos de las impresoras para verificar que la actualizacin se realiz. 9- Muestre todos los artculos concatenado los campos para que aparezcan de la siguiente manera "Cod. 101: impresora Epson Stylus C45 $460,92 (15)" Solucin: drop table articulos; create table articulos( codigo number(4), nombre varchar2(20), descripcion varchar2(30), precio number(8,2), cantidad number(3) default 0, primary key (codigo) ); insert into articulos values (101,'impresora','Epson Stylus C45',400.80,20); insert into articulos values (203,'impresora','Epson Stylus C85',500,30); insert into articulos values (205,'monitor','Samsung 14',800,10); insert into articulos values (300,'teclado','ingles Biswal',100,50); update articulos set precio=precio+(precio*0.15); select *from articulos; select nombre||','||descripcion from articulos; update articulos set cantidad=cantidad-5 where nombre='impresora'; select *from articulos where nombre='impresora'; select 'Cod. '||codigo||': '||nombre||' '||descripcion||' $'||precio||' ('||cantidad||')'; from articulos;

20 - Alias (encabezados de columnas)


Una manera de hacer ms comprensible el resultado de una consulta consiste en cambiar los encabezados de las columnas. Por ejemplo, tenemos la tabla "libros" con un campo "cantidad" (entre otros) en el cual se almacena la cantidad de libros en stock; queremos que al mostrar la informacin de dicha tabla aparezca como encabezado del campo "cantidad" el texto "stock", para ello colocamos un alias de la siguiente manera: select titulo, cantidad as stock, precio from libros; Para reemplazar el nombre de un campo del encabezado por otro, se coloca la palabra clave "as" seguido del texto del encabezado. Si el alias consta de una sola cadena las comillas no son necesarias, pero si contiene ms de una palabra, es necesario colocarla entre comillas dobles: select titulo, cantidad as "stock disponible", precio from libros; Tambin se puede crear un alias para columnas calculadas. Por ejemplo: select titulo,precio, precio*0.1 as descuento, precio-(precio*0.1) as "preciofinal" from libros; La palabra clave "as" es opcional, pero es conveniente usarla. Entonces, un "alias" se usa como nombre de un campo o de una expresin. En estos casos, son opcionales, sirven para hacer ms comprensible el resultado. Ejercicio 1: Primer problema: Un comercio que vende artculos de computacin registra los datos de sus artculos en una tabla con ese nombre. 1- Elimine la tabla: drop table articulos; 2- Cree la tabla: create table articulos( codigo number(4), nombre varchar2(20),

descripcion varchar2(30), precio number(8,2), cantidad number(3) default 0, primary key (codigo) ); 3- Ingrese algunos registros: insert into articulos values (101,'impresora','Epson Stylus C45',400.80,20); insert into articulos values (203,'impresora','Epson Stylus C85',500,30); insert into articulos values (205,'monitor','Samsung 14',800,10); insert into articulos values (300,'teclado','ingles Biswal',100,50); 4- El comercio hace un descuento del 15% en ventas mayoristas. Necesitamos recuperar el cdigo, nombre, decripcin de todos los artculos con una columna extra que muestre el precio de cada artculo para la venta mayorista con el siguiente encabezado "precio mayorista" 5- Muestre los precios de todos los artculos, concatenando el nombre y la descripcin con el encabezado "artculo" (sin emplear "as" ni comillas) 6- Muestre todos los campos de los artculos y un campo extra, con el encabezado "monto total" en la que calcule el monto total en dinero de cada artculo (precio por cantidad) 7- Muestre la descripcin de todas las impresoras junto al precio con un 20% de recargo con un encabezado que lo especifique. Solucin: drop table articulos; create table articulos( codigo number(4), nombre varchar2(20), descripcion varchar2(30), precio number(8,2), cantidad number(3) default 0, primary key (codigo) ); insert into articulos values (101,'impresora','Epson Stylus C45',400.80,20); insert into articulos values (203,'impresora','Epson Stylus C85',500,30); insert into articulos values (205,'monitor','Samsung 14',800,10); insert into articulos values (300,'teclado','ingles Biswal',100,50);

select codigo, nombre, descripcion, precio-(precio*.15) as "precio mayorista" from articulos; select nombre||' '||descripcion artculo, precio from articulos; select codigo,nombre,descripcion, precio, cantidad, precio*cantidad "Monto Total" from articulos; select descripcion, precio+(precio*.2) as recargado from articulos;

21 - Funciones string
Las funciones de manejo de caracteres alfanumricos aceptan argumentos de tipo caracter y retornan caracteres o valores numricos. Las siguientes son algunas de las funciones que ofrece Oracle para trabajar con cadenas de caracteres: - chr(x): retorna un caracter equivalente al cdigo enviado como argumento "x". Ejemplo: select chr(65) from dual;-- retorna 'A'. select chr(100) from dual;-- retorna 'd'. - concat(cadena1,cadena2): concatena dos cadenas de caracteres; es equivalente al operador ||. Ejemplo: select concat('Buenas',' tardes') from dual;--retorna 'Buenas tardes'. - initcap(cadena): retorna la cadena enviada como argumento con la primera letra (letra capital) de cada palabra en mayscula. Ejemplo: select initcap('buenas tardes alumno') from dual;--retorna 'Buenas Tardes Alumno'. - lower(cadena): retorna la cadena enviada como argumento en minsculas. "lower" significa reducir en ingls. Ejemplo: select lower('Buenas tardes ALUMNO') from dual;--retorna "buenas tardes alumno". - upper(cadena): retorna la cadena con todos los caracteres en maysculas. Ejemplo: select upper('www.oracle.com') from dual;-- 'WWW.ORACLE.COM' - lpad(cadena,longitud,cadenarelleno): retorna la cantidad de caracteres especificados por el argumento "longitud", de la cadena enviada como primer argumento (comenzando desde el primer caracter); si "longitud" es mayor que el tamao de la cadena enviada, rellena los espacios

restantes con la cadena enviada como tercer argumento (en caso de omitir el tercer argumento rellena con espacios); el relleno comienza desde la izquierda. Ejemplos: select lpad('alumno',10,'xyz') from dual;-- retorna 'xyzxalumno' select lpad('alumno',4,'xyz') from dual;-- retorna 'alum' - rpad(cadena,longitud,cadenarelleno): retorna la cantidad de caracteres especificados por el argumento "longitud", de la cadena enviada como primer argumento (comenzando desde el primer caracter); si "longitud" es mayor que el tamao de la cadena enviada, rellena los espacios restantes con la cadena enviada como tercer argumento (en caso de omitir el tercer argumento rellena con espacios); el relleno comienza desde la derecha (ltimo caracter). Ejemplos: select rpad('alumno',10,'xyz') from dual;-- retorna 'alumnoxyzx' select rpad('alumno',4,'xyz') from dual;-- retorna 'alum' - ltrim(cadena1,cadena2): borra todas las ocurrencias de "cadena2" en "cadena1", si se encuentran al comienzo; si se omite el segundo argumento, se eliminan los espacios. Ejemplo: select ltrim('la casa de la cuadra','la') from dual;-- ' casa de la cuadra' select ltrim(' es la casa de la cuadra','la') from dual;-- no elimina ningn caracter select ltrim(' la casa') from dual;-- 'la casa' - rtrim(cadena1,cadena2): borra todas las ocurrencias de "cadena2" en "cadena1", si se encuentran por la derecha (al final de la cadena); si se omite el segundo argumento, se borran los espacios. Ejemplo: select rtrim('la casa lila','la') from dual;-- 'la casa li' select rtrim('la casa lila ','la') from dual;-- no borra ningn caracter select rtrim('la casa lila ') from dual; --'la casa lila' - trim(cadena): retorna la cadena con los espacios de la izquierda y derecha eliminados. "Trim" significa recortar. Ejemplo: select trim(' oracle ') from dual;--'oracle'

- replace(cadena,subcade1,subcade2): retorna la cadena con todas las ocurrencias de la subcadena de reemplazo (subcade2) por la subcadena a reemplazar (subcae1). Ejemplo: select replace('xxx.oracle.com','x','w') from dual; retorna "www.oracle.com'. - substr(cadena,inicio,longitud): devuelve una parte de la cadena especificada como primer argumento, empezando desde la posicin especificada por el segundo argumento y de tantos caracteres de longitud como indica el tercer argumento. Ejemplo: select substr('www.oracle.com',1,10) from dual;-- 'www.oracle' select substr('www.oracle.com',5,6) from dual;-- 'oracle' - length(cadena): retorna la longitud de la cadena enviada como argumento. "lenght" significa longitud en ingls. Ejemplo:

select length('www.oracle.com') from dual;-- devuelve 14. - instr (cadena,subcadena): devuelve la posicin de comienzo (de la primera ocurrencia) de la subcadena especificada en la cadena enviada como primer argumento. Si no la encuentra retorna 0. Ejemplos: select instr('Jorge Luis Borges','or') from dual;-- 2 select instr('Jorge Luis Borges','ar') from dual;-- 0, no se encuentra - translate(): reemplaza cada ocurrencia de una serie de caracteres con otra serie de acracteres. La diferencia con "replace" es que aquella trabaja con cadenas de caracteres y reemplaza una cadena completa por otra, en cambio "translate" trabaja con caracteres simples y reemplaza varios. En el siguiente ejemplo se especifica que se reemplacen todos los caracteres "O" por el caracter "0", todos los caracteres "S" por el caracter "5" y todos los caracteres "G" por "6": select translate('JORGE LUIS BORGES','OSG','056') from dual;--'J0R6E LUI5 B0R6E5' Se pueden emplear estas funciones enviando como argumento el nombre de un campo de tipo caracter.

22 - Funciones matemticas.
Las funciones matemticas realizan operaciones con expresiones numricas y retornan un resultado, operan con tipos de datos numricos. Las funciones numricas aceptan parmetros de entrada de tipo numrico y retornan valores numricos. Oracle tiene algunas funciones para trabajar con nmeros. Aqu presentamos algunas. - abs(x): retorna el valor absoluto del argumento "x". Ejemplo: select abs(-20) from dual;--retorna 20. La tabla dual es una tabla virtual que existe en todas las Bases de datos Oracle. - ceil(x): redondea a entero, hacia arriba, el argumento "x". Ejemplo: select ceil(12.34) from dual;--retorna 13. - floor(x): redondea a entero, hacia abajo, el argumento "x". Ejemplo: select floor(12.34) from dual; --12 - mod(x,y): devuelve el resto de la divisin x/y. Ejemplos: select mod(10,3) from dual;--retorna 1. select mod(10,2) from dual;--retorna 0. - power(x,y): retorna el valor de "x" elevado a la "y" potencia. Ejemplo:

select power(2,3) from dual;--retorna 8. - round(n,d): retorna "n" redondeado a "d" decimales; si se omite el segundo argumento, redondea todos los decimales. Si el segundo argumento es positivo, el nmero de decimales es redondeado segn "d"; si es negativo, el nmero es redondeado desde la parte entera segn el valor de "d". Ejemplos: select round(123.456,2) from dual;-- retorna "123.46", es decir, redondea desde el segundo decimal. select round(123.456,1) from dual;-- 123.5, es decir, redondea desde el primer decimal. select round(123.456,-1) from dual;-- 120, redondea desde el primer valor entero (hacia la izquierda). select round(123.456,-2) from dual;-- 100, redondea desde el segundo valor entero (hacia la izquierda). select round(123.456) from dual;-- 123. - sign(x): si el argumento es un valor positivo, retorna 1, si es negativo, devuelve -1 y 0 si es 0. Ejemplo: select sign(-120) from dual;--retorna -1 select sign(120) from dual;--retorna 1 - trunc(n,d): trunca un nmero a la cantidad de decimales especificada por el segundo argumento. Si se omite el segundo argumento, se truncan todos los decimales. Si "d" es negativo, el nmero es truncado desde la parte entera. Ejemplo: select select select select trunc(1234.5678,2) from dual;--retorna 1234.56 trunc(1234.5678,-2) from dual;--retorna 1200 trunc(1234.5678,-1) from dual;--retorna 1230 trunc(1234.5678) from dual;--retorna 1234

- sqrt(x): devuelve la raiz cuadrada del valor enviado como argumento. Ejemplo: select sqrt(9) from dual;--retorna 3 Oracle dispone de funciones trigonomtricas que retornan radianes, calculan seno, coseno, inversas, etc.: acos, asin, atan, atan2, cos, cosh, exp, ln, log, sin, sinh, tan, tanh. No las veremos en detalle. Se pueden emplear las funciones matemticas enviando como argumento el nombre de un campo de tipo numrico.

23 - Funciones de fechas y horas


Oracle dispone de varias funciones que operan con tipos de datos "date". Estas son algunas: - add_months(f,n): agrega a una fecha, un nmero de meses. Si el segundo argumento es positivo, se le suma a la fecha enviada tal cantidad de meses; si es negativo, se le resta a la fecha enviada tal cantidad de meses. Ejemplo: select add_months('10/06/2007',5) from dual; --retorna "10/11/07"

select add_months('10/06/2007',-5) from dual; --retorna "10/01/07" select add_months('30/01/2007',1) from dual;-- retorna "25/02/07" ya que es el ltimo da de ese mes. - last_day(f): retorna el ultimo da de mes de la fecha enviada como argumento. Ejemplo: select last_day('10/02/2007') from dual;-- "28/02/07" select last_day('10/08/2007') from dual;-- "31/08/07" - months_between(f1,f2): retorna el numero de meses entre las fechas enviadas como argumento. Ejemplo: select months_between('19/05/2003','21/06/05') from dual;-- retorna - next_day(fecha,dia): retorna una fecha correspondiente al primer da especificado en "dia" luego de la fecha especificada. En el siguiente ejemplo se busca el lunes siguiente a la fecha especificada: select next_day('10/08/2007','LUNES') from dual; - current_date: retorna la fecha actual. Ejemplo: select current_date from dual; - current_timestamp: retorna la fecha actual select current_timestamp from dual; Retorna: 10/08/07 09:59:44,109000000 AMERICA/BUENOS_AIRES - sysdate: retorna la fecha y hora actuales en el servidor de Oracle. -systimestamp: retorna fecha y hora actuales. select systimestamp from dual; Retorna 10/08/07 10:33:48,984000000 -03:00 - to_date: convierte una cadena a tipo de dato "date". Ejemplo: select to_date ('05-SEP-2007 10:00 AM','DD-MON-YYYY HH:MI AM') from dual; Retorna 05/09/07 - to_char: convierte una fecha a cadena de caracteres. Ejemplo: select to_char('10/10/2007')from dual; - extract(parte,fecha): retorna la parte (especificada por el primer argumento) de una fecha. Puede extraer el ao (year), mes (month), da (day), hora (hour), minuto (minute), segundo (second), etc. Ejemplo:

select extract(month from sysdate) from dual; retorna el nmero mes de la fecha actual. En Oracle: Los operadores aritmticos "+" (ms) y "-" (menos) pueden emplearse con fechas. Por ejemplos: select sysdate-3: Retorna 3 das antes de la fecha actual. select to_date('15/12/2007')-5 from dual; Retorna 10/12/07 Se pueden emplear estas funciones enviando como argumento el nombre de un campo de tipo date.

24 - Ordenar registros (order by)


Podemos ordenar el resultado de un "select" para que los registros se muestren ordenados por algn campo, para ello usamos la clusula "order by". La sintaxis bsica es la siguiente: select *from NOMBRETABLA order by CAMPO; Por ejemplo, recuperamos los registros de la tabla "libros" ordenados por el ttulo: select *from libros order by titulo; Aparecen los registros ordenados alfabticamente por el campo especificado. Tambin podemos colocar el nmero de orden del campo por el que queremos que se ordene en lugar de su nombre, es decir, referenciar a los campos por su posicin en la lista de seleccin. Por ejemplo, queremos el resultado del "select" ordenado por "precio": select titulo,autor,precio from libros order by 3; Si colocamos un nmero mayor a la cantidad de campos de la lista de seleccin, aparece un mensaje de error y la sentencia no se ejecuta. Por defecto, si no aclaramos en la sentencia, los ordena de manera ascendente (de menor a mayor). Podemos ordenarlos de mayor a menor, para ello agregamos la palabra clave "desc": select *libros order by editorial desc;

Tambin podemos ordenar por varios campos, por ejemplo, por "titulo" y "editorial": select *from libros order by titulo,editorial; Incluso, podemos ordenar en distintos sentidos, por ejemplo, por "titulo" en sentido ascendente y "editorial" en sentido descendente: select *from libros order by titulo asc, editorial desc; Debe aclararse al lado de cada campo, pues estas palabras claves afectan al campo inmediatamente anterior. Es posible ordenar por un campo que no se lista en la seleccin incluso por columnas calculados. Se puede emplear "order by" con campos de tipo caracter, numrico y date. Ejercicio 1: Primer problema: En una pgina web se guardan los siguientes datos de las visitas: nombre, mail, pais y fecha. 1- Elimine la tabla "visitas" y crela con la siguiente estructura: drop table visitas; create table visitas ( nombre varchar2(30) default 'Anonimo', mail varchar2(50), pais varchar2(20), fecha date ); 3- Ingrese algunos registros: insert into visitas values ('Ana Maria Lopez','AnaMaria@hotmail.com','Argentina','10/10/2006 10:10'); insert into visitas values ('Gustavo Gonzalez','GustavoGGonzalez@hotmail.com','Chile','10/10/2006 21:30'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','11/10/2006 15:45'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/10/2006 08:15'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/09/2006 20:45'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','12/09/2006 16:20'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','15/09/2006 16:25'); 4- Ordene los registros por fecha, en orden descendente.

5- Muestre el nombre del usuario, pais y el mes, ordenado por pais (ascendente) y el mes (descendente) 6- Muestre los mail, pas, ordenado por pas, de todos los que visitaron la pgina en octubre (4 registros) Solucion 1: drop table visitas; create table visitas ( nombre varchar2(30) default 'Anonimo', mail varchar2(50), pais varchar2(20), fecha date ); insert into visitas values ('Ana Maria Lopez','AnaMaria@hotmail.com','Argentina','10/10/2006 10:10'); insert into visitas values ('Gustavo Gonzalez','GustavoGGonzalez@hotmail.com','Chile','10/10/2006 21:30'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','11/10/2006 15:45'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/10/2006 08:15'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/09/2006 20:45'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','12/09/2006 16:20'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','15/09/2006 16:25'); select *from visitas order by fecha desc; select nombre,pais,extract(month from fecha) from visitas order by 1,3 desc; select mail, pais from visitas where extract(month from fecha)=10 order by 2;

25 - Operadores lgicos (and - or - not)


Hasta el momento, hemos aprendido a establecer una condicin con "where" utilizando operadores relacionales. Podemos establecer ms de una condicin con la clusula "where", para ello aprenderemos los operadores lgicos. Son los siguientes:

and, significa "y", or, significa "y/o", not, significa "no", invierte el resultado (), parntesis

Los operadores lgicos se usan para combinar condiciones. Si queremos recuperar todos los libros cuyo autor sea igual a "Borges" y cuyo precio no supere los 20 pesos, necesitamos 2 condiciones: select *from libros where (autor='Borges') and (precio<=20); Los registros recuperados en una sentencia que une dos condiciones con el operador "and", cumplen con las 2 condiciones. Queremos ver los libros cuyo autor sea "Borges" y/o cuya editorial sea "Planeta": select *from libros where autor='Borges' or editorial='Planeta'; En la sentencia anterior usamos el operador "or"; indicamos que recupere los libros en los cuales el valor del campo "autor" sea "Borges" y/o el valor del campo "editorial" sea "Planeta", es decir, seleccionar los registros que cumplan con la primera condicin, con la segunda condicin y con ambas condiciones. Los registros recuperados con una sentencia que une dos condiciones con el operador "or", cumplen una de las condiciones o ambas. Queremos recuperar los libros que NO cumplan la condicin dada, por ejemplo, aquellos cuya editorial NO sea "Planeta": select *from libros where not editorial='Planeta'; El operador "not" invierte el resultado de la condicin a la cual antecede. Los registros recuperados en una sentencia en la cual aparece el operador "not", no cumplen con la condicin a la cual afecta el "NOT". Los parntesis se usan para encerrar condiciones, para que se evalen como una sola expresin. Cuando explicitamos varias condiciones con diferentes operadores lgicos (combinamos "and", "or") permite establecer el orden de prioridad de la evaluacin; adems permite diferenciar las expresiones ms claramente. Por ejemplo, las siguientes expresiones devuelven un resultado diferente: select *from libros where (autor='Borges') or (editorial='Paidos' and precio<20);

select *from libros where (autor='Borges' or editorial='Paidos') and (precio<20); Si bien los parntesis no son obligatorios en todos los casos, se recomienda utilizarlos para evitar confusiones. El orden de prioridad de los operadores lgicos es el siguiente: "not" se aplica antes que "and" y "and" antes que "or", si no se especifica un orden de evaluacin mediante el uso de parntesis. El orden en el que se evalan los operadores con igual nivel de precedencia es indefinido, por ello se recomienda usar los parntesis. Entonces, para establecer ms de una condicin en un "where" es necesario emplear operadores lgicos. "and" significa "y", indica que se cumplan ambas condiciones; "or" significa "y/o", indica que se cumpla una u otra condicin (o ambas); "not" significa "no.", indica que no se cumpla la condicin especificada. Ejercicio 1: Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Elimine la tabla y crela con la siguiente estructura: drop table medicamentos; create table medicamentos( codigo number(5), nombre varchar2(20), laboratorio varchar2(20), precio number(5,2), cantidad number(3), primary key(codigo) ); 3- Ingrese algunos registros: insert insert insert insert insert insert into into into into into into medicamentos medicamentos medicamentos medicamentos medicamentos medicamentos values(100,'Sertal','Roche',5.2,100); values(102,'Buscapina','Roche',4.10,200); values(205,'Amoxidal 500','Bayer',15.60,100); values(230,'Paracetamol 500','Bago',1.90,200); values(345,'Bayaspirina','Bayer',2.10,150); values(347,'Amoxidal jarabe','Bayer',5.10,250);

4- Recupere los cdigos y nombres de los medicamentos cuyo laboratorio sea "Roche' y cuyo precio sea menor a 5 (1 registro cumple con ambas condiciones) 5- Recupere los medicamentos cuyo laboratorio sea "Roche" o cuyo precio sea menor a 5 (4 registros)

6- Muestre todos los medicamentos cuyo laboratorio NO sea "Bayer" y cuya cantidad sea=100. Luego muestre todos los medicamentos cuyo laboratorio sea "Bayer" y cuya cantidad NO sea=100 7- Recupere los nombres de los medicamentos cuyo precio est entre 2 y 5 inclusive (2 registros) 8- Elimine todos los registros cuyo laboratorio sea igual a "Bayer" y su precio sea mayor a 10 (1 registro eliminado) 9- Cambie la cantidad por 200, de todos los medicamentos de "Roche" cuyo precio sea mayor a 5 (1 registro afectado) 10- Muestre todos los registros para verificar el cambio. 11- Borre los medicamentos cuyo laboratorio sea "Bayer" o cuyo precio sea menor a 3 (3 registros borrados) Solucin: drop table medicamentos; create table medicamentos( codigo number(5), nombre varchar2(20), laboratorio varchar2(20), precio number(5,2), cantidad number(3), primary key(codigo) ); insert insert insert insert insert insert into into into into into into medicamentos medicamentos medicamentos medicamentos medicamentos medicamentos values(100,'Sertal','Roche',5.2,100); values(102,'Buscapina','Roche',4.10,200); values(205,'Amoxidal 500','Bayer',15.60,100); values(230,'Paracetamol 500','Bago',1.90,200); values(345,'Bayaspirina','Bayer',2.10,150); values(347,'Amoxidal jarabe','Bayer',5.10,250);

select codigo,nombre from medicamentos where laboratorio='Roche' and precio<5; select * from medicamentos where laboratorio='Roche' or precio<5; select * from medicamentos where laboratorio='Bayer' and not cantidad=100; select * from medicamentos where not laboratorio='Bayer' and cantidad=100;

select nombre from medicamentos where precio>=2 and precio <=5; delete from medicamentos where laboratorio='Bayer' and precio>10; update medicamentos set cantidad=200 where laboratorio='Roche' and precio>5; select *from medicamentos; delete from medicamentos where laboratorio='Bayer' or

precio<3; Ejercicio 2:
Segundo problema: Trabajamos con la tabla "peliculas" de un video club que alquila pelculas en video. 1- Elimine la tabla y crela con la siguiente estructura: drop table peliculas; create table peliculas( codigo number(4), titulo varchar2(40) not null, actor varchar2(20), duracion number(3), primary key (codigo) ); 3- Ingrese algunos registros: insert into peliculas values(1020,'Mision imposible','Tom Cruise',120); insert into peliculas values(1021,'Harry Potter y la piedra filosofal','Daniel R.',180); insert into peliculas values(1022,'Harry Potter y la camara secreta','Daniel R.',190); insert into peliculas values(1200,'Mision imposible 2','Tom Cruise',120); insert into peliculas values(1234,'Mujer bonita','Richard Gere',120); insert into peliculas values(900,'Tootsie','D. Hoffman',90); insert into peliculas

values(1300,'Un oso rojo','Julio Chavez',100); insert into peliculas values(1301,'Elsa y Fred','China Zorrilla',110); 4- Recupere los registros cuyo actor sea "Tom Cruise" o "Richard Gere" (3 registros) 5- Recupere los registros cuyo actor sea "Tom Cruise" y duracin menor a 100 (ninguno cumple ambas condiciones) 6- Recupere los nombres de las pelculas cuya duracin se encuentre entre 100 y 120 minutos(5 registros) 7- Cambie la duracin a 200, de las pelculas cuyo actor sea "Daniel R." y cuya duracin sea 180 (1 registro afectado) 8- Recupere todos los registros para verificar la actualizacin anterior 9- Borre todas las pelculas donde el actor NO sea "Tom Cruise" y cuya duracin sea mayor o igual a 100 (2 registros eliminados) Solucin: drop table peliculas; create table peliculas( codigo number(4), titulo varchar2(40) not null, actor varchar2(20), duracion number(3), primary key (codigo) ); insert into peliculas values(1020,'Mision imposible','Tom Cruise',120); insert into peliculas values(1021,'Harry Potter y la piedra filosofal','Daniel R.',180); insert into peliculas values(1022,'Harry Potter y la camara secreta','Daniel R.',190); insert into peliculas values(1200,'Mision imposible 2','Tom Cruise',120); insert into peliculas values(1234,'Mujer bonita','Richard Gere',120); insert into peliculas values(900,'Tootsie','D. Hoffman',90); insert into peliculas values(1300,'Un oso rojo','Julio Chavez',100); insert into peliculas values(1301,'Elsa y Fred','China Zorrilla',110); select *from peliculas where actor='Tom Cruise' or actor='Richard Gere';

select *from peliculas where actor='Tom Cruise' and duracion<100; select titulo from peliculas where duracion>=100 and duracion<=120; update peliculas set duracion=200 where actor='Daniel R.' and duracion=180; select *from peliculas; delete from peliculas where not actor='Tom Cruise' and duracion<=100;

26 - Otros operadores relacionales (between)


Hemos visto los operadores relacionales: = (igual), <> (distinto), > (mayor), < (menor), >= (mayor o igual), <= (menor o igual), is null/is not null (si un valor es NULL o no). Otro operador relacional es "between", trabajan con intervalos de valores. Hasta ahora, para recuperar de la tabla "libros" los libros con precio mayor o igual a 20 y menor o igual a 40, usamos 2 condiciones unidas por el operador lgico "and": select *from libros where precio>=20 and precio<=40; Podemos usar "between" y as simplificar la consulta: select *from libros where precio between 20 and 40; Averiguamos si el valor de un campo dado (precio) est entre los valores mnimo y mximo especificados (20 y 40 respectivamente). "between" significa "entre". Trabaja con intervalo de valores. Este operador no tiene en cuenta los valores "null". Si agregamos el operador "not" antes de "between" el resultado se invierte, es decir, se recuperan los registros que estn fuera del intervalo especificado. Por ejemplo, recuperamos los libros cuyo precio NO se encuentre entre 20 y 30, es decir, los menores a 20 y mayores a 30: select *from libros

where precio not between 20 and 30; Podemos especificar un intervalo de valores de tipo fecha con "between": select *from libros where edicion between '01/05/2000' and '01/05/2007'; Entonces, empleamos el operador "between" para reducir las condiciones "where". Ejercicio: Primer problema: En una pgina web se guardan los siguientes datos de las visitas: nmero de visita, nombre, mail, pais, fechayhora de la visita. 1- Elimine la tabla "visitas" y crela con la siguiente estructura: drop table visitas; create table visitas ( nombre varchar2(30) default 'Anonimo', mail varchar2(50), pais varchar2(20), fecha date ); 2- Ingrese algunos registros: insert into visitas values ('Ana Maria Lopez','AnaMaria@hotmail.com','Argentina','10/10/2006'); insert into visitas values ('Gustavo Gonzalez','GustavoGGonzalez@gotmail.com','Chile','10/10/2006'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','11/10/2006'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/10/2006'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/09/2006'); insert into visitas values ('Juancito','JuanJosePerez@gmail.com','Argentina','12/09/2006'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','15/09/2006'); insert into visitas values ('Federico1','federicogarcia@xaxamail.com','Argentina',null); 3- Seleccione los usuarios que visitaron la pgina entre el '12/09/2006' y '11/10/2006' (6 registros) Note que incluye los de fecha mayor o igual al valor mnimo y menores o iguales al valor mximo, y que los valores nulos no se incluyen. Solucion:

drop table visitas; create table visitas ( nombre varchar2(30) default 'Anonimo', mail varchar2(50), pais varchar2(20), fecha date ); insert into visitas values ('Ana Maria Lopez','AnaMaria@hotmail.com','Argentina','10/10/2006'); insert into visitas values ('Gustavo Gonzalez','GustavoGGonzalez@gotmail.com','Chile','10/10/2006'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','11/10/2006'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/10/2006'); insert into visitas values ('Fabiola Martinez','MartinezFabiola@hotmail.com','Mexico','12/09/2006'); insert into visitas values ('Juancito','JuanJosePerez@gmail.com','Argentina','12/09/2006'); insert into visitas values ('Juancito','JuanJosePerez@hotmail.com','Argentina','15/09/2006'); insert into visitas values ('Federico1','federicogarcia@xaxamail.com','Argentina',null); select *from visitas where fecha between '12/09/2006' and '11/10/2006';

Segundo problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Elimine la tabla y crela con la siguiente estructura: drop table medicamentos; create table medicamentos( codigo number(6) not null, nombre varchar2(20), laboratorio varchar2(20), precio number(6,2), cantidad number(4), fechavencimiento date not null, primary key(codigo) ); 2- Ingrese algunos registros: insert into medicamentos values(102,'Sertal','Roche',5.2,10,'01/02/2010');

insert into medicamentos values(120,'Buscapina','Roche',4.10,200,'01/12/2007'); insert into medicamentos values(230,'Amoxidal 500','Bayer',15.60,100,'28/12/2007'); insert into medicamentos values(250,'Paracetamol 500','Bago',1.90,20,'01/02/2008'); insert into medicamentos values(350,'Bayaspirina','Bayer',2.10,150,'01/12/2009'); insert into medicamentos values(456,'Amoxidal jarabe','Bayer',5.10,250,'01/10/2010'); 3- Recupere los nombres y precios de los medicamentos cuyo precio est entre 5 y 15 (2 registros) 4- Seleccione los registros cuya cantidad se encuentre entre 100 y 200 (3 registros) 5- Recupere los remedios cuyo vencimiento se encuentre entre la fecha actual y '01/01/2008' inclusive (2 registros) 6- Elimine los remedios cuyo vencimiento se encuentre entre el ao 2007 y 2008 inclusive (3 registros) Solucin: drop table medicamentos; create table medicamentos( codigo number(6) not null, nombre varchar2(20), laboratorio varchar2(20), precio number(6,2), cantidad number(4), fechavencimiento date not null, primary key(codigo) ); insert into medicamentos values(102,'Sertal','Roche',5.2,10,'01/02/2010'); insert into medicamentos values(120,'Buscapina','Roche',4.10,200,'01/12/2007'); insert into medicamentos values(230,'Amoxidal 500','Bayer',15.60,100,'28/12/2007'); insert into medicamentos values(250,'Paracetamol 500','Bago',1.90,20,'01/02/2008'); insert into medicamentos values(350,'Bayaspirina','Bayer',2.10,150,'01/12/2009'); insert into medicamentos values(456,'Amoxidal jarabe','Bayer',5.10,250,'01/10/2010'); select nombre,precio from medicamentos where precio between 5 and 15; select *from medicamentos

where cantidad between 100 and 200; select *from medicamentos where fechavencimiento between sysdate and '01/01/2008'; delete from medicamentos where extract(year from fechavencimiento) between '2007' and '2008';

27 - Otros operadores relacionales (in)


Se utiliza "in" para averiguar si el valor de un campo est incluido en una lista de valores especificada. En la siguiente sentencia usamos "in" para averiguar si el valor del campo autor est incluido en la lista de valores especificada (en este caso, 2 cadenas). Hasta ahora, para recuperar los libros cuyo autor sea 'Paenza' o 'Borges' usbamos 2 condiciones: select *from libros where autor='Borges' or autor='Paenza'; Podemos usar "in" y simplificar la consulta: select *from libros where autor in('Borges','Paenza'); Para recuperar los libros cuyo autor no sea 'Paenza' ni 'Borges' usbamos: select *from libros where autor<>'Borges' and autor<>'Paenza'; Tambin podemos usar "in" anteponiendo "not": select *from libros where autor not in ('Borges','Paenza'); Empleando "in" averiguamos si el valor del campo est incluido en la lista de valores especificada; con "not" antecediendo la condicin, invertimos el resultado, es decir, recuperamos los valores que no se encuentran (no coinciden) con la lista de valores. Los valores "null" no se consideran. Ejercicio: Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Elimine la tabla y crela con la siguiente estructura: drop table medicamentos;

create table medicamentos( codigo number(5), nombre varchar2(20), laboratorio varchar2(20), precio number(6,2), cantidad number(3) not null, fechavencimiento date not null, primary key(codigo) ); 3- Ingrese algunos registros: insert into medicamentos values(100,'Sertal','Roche',5.2,1,'01/02/2005'); insert into medicamentos values(230,'Buscapina',null,4.10,3,'01/03/2006'); insert into medicamentos values(280,'Amoxidal 500','Bayer',15.60,100,'01/05/2007'); insert into medicamentos values(301,'Paracetamol 500','Bago',1.90,10,'01/02/2008'); insert into medicamentos values(400,'Bayaspirina','Bayer',2.10,150,'01/08/2009'); insert into medicamentos values(560,'Amoxidal jarabe','Bayer',5.10,250,'01/10/2010'); 4- Recupere los nombres y precios de los medicamentos cuyo laboratorio sea "Bayer" o "Bago" empleando el operador "in" (4 registros) 5- Recupere los nombres y precios de los medicamentos cuyo laboratorio NO sea "Bayer" o "Bago" empleando el operador "in" (1 registro) Note que los valores nulos no se incluyen. 6- Seleccione los remedios cuya cantidad se encuentre entre 1 y 5 empleando el operador "between" y luego el operador "in" (2 registros) Note que es ms conveniente emplear, en este caso, el operador "between", simplifica la consulta. 7- Recupere los registros cuyas fechas de vencimiento se encuentra entre enero de 2005 y enero del 2007 (emplee el operador apropiado) (2 registros) 8- Recupere los registros cuyo ao de vencimiento sea 2005 o 2006 (emplee el operador apropiado) (2 registros) Solucin: drop table medicamentos; create table medicamentos( codigo number(5), nombre varchar2(20), laboratorio varchar2(20),

precio number(6,2), cantidad number(3) not null, fechavencimiento date not null, primary key(codigo) ); insert into medicamentos values(100,'Sertal','Roche',5.2,1,'01/02/2005'); insert into medicamentos values(230,'Buscapina',null,4.10,3,'01/03/2006'); insert into medicamentos values(280,'Amoxidal 500','Bayer',15.60,100,'01/05/2007'); insert into medicamentos values(301,'Paracetamol 500','Bago',1.90,10,'01/02/2008'); insert into medicamentos values(400,'Bayaspirina','Bayer',2.10,150,'01/08/2009'); insert into medicamentos values(560,'Amoxidal jarabe','Bayer',5.10,250,'01/10/2010'); select nombre,precio from medicamentos where laboratorio in ('Bayer','Bago'); select nombre,precio from medicamentos where laboratorio not in ('Bayer','Bago'); select *from medicamentos where cantidad between 1 and 5; select *from medicamentos where cantidad in (1,2,3,4,5); select *from medicamentos where fechavencimiento between '01/01/2005' and '01/01/2007'; select *from medicamentos where extract(year from fechavencimiento) in (2005,2006);

28 - Bsqueda de patrones (like - not like)


Existe un operador relacional que se usa para realizar comparaciones exclusivamente de cadenas, "like" y "not like". Hemos realizado consultas utilizando operadores relacionales para comparar cadenas. Por ejemplo, sabemos recuperar los libros cuyo autor sea igual a la cadena "Borges": select *from libros where autor='Borges'; El operador igual ("=") nos permite comparar cadenas de caracteres, pero al realizar la comparacin, busca coincidencias de cadenas completas, realiza una bsqueda exacta. Imaginemos que tenemos registrados estos 2 libros:

"El Aleph", "Borges"; "Antologia poetica", "J.L. Borges"; Si queremos recuperar todos los libros de "Borges" y especificamos la siguiente condicin: select *from libros where autor='Borges'; slo aparecer el primer registro, ya que la cadena "Borges" no es igual a la cadena "J.L. Borges". Esto sucede porque el operador "=" (igual), tambin el operador "<>" (distinto) comparan cadenas de caracteres completas. Para comparar porciones de cadenas utilizamos los operadores "like" y "not like". Entonces, podemos comparar trozos de cadenas de caracteres para realizar consultas. Para recuperar todos los registros cuyo autor contenga la cadena "Borges" debemos tipear: select *from libros where autor like "%Borges%"; El smbolo "%" (porcentaje) reemplaza cualquier cantidad de caracteres (incluyendo ningn caracter). Es un caracter comodn. "like" y "not like" son operadores de comparacin que sealan igualdad o diferencia. Para seleccionar todos los libros que comiencen con "M": select *from libros where titulo like 'M%'; Note que el smbolo "%" ya no est al comienzo, con esto indicamos que el ttulo debe tener como primera letra la "M" y luego, cualquier cantidad de caracteres. Para seleccionar todos los libros que NO comiencen con "M": select *from libros where titulo not like 'M%'; As como "%" reemplaza cualquier cantidad de caracteres, el guin bajo "_" reemplaza un caracter, es otro caracter comodn. Por ejemplo, queremos ver los libros de "Lewis Carroll" pero no recordamos si se escribe "Carroll" o "Carrolt", entonces tipeamos esta condicin: select *from libros where autor like "%Carrol_"; "like" se emplea con tipos de datos caracter y date. Si empleamos "like" con tipos de datos que no son caracteres, Oracle convierte (si es posible) el tipo de dato a caracter. Por ejemplo, queremos buscar todos los libros cuyo precio se encuentre entre 10.00 y 19.99: select titulo,precio from libros where precio like '1_,%'; Queremos los libros que NO incluyen centavos en sus precios:

select titulo,precio from libros where precio not like '%,%'; Los valores nulos no se incluyen en las bsquedas con "like" y "not like". Ejercicio: Primer problema: Una empresa almacena los datos de sus empleados en una tabla "empleados". 1- Elimine la tabla: drop table empleados; 2- Cree la tabla: create table empleados( nombre varchar2(30), documento char(8) not null, domicilio varchar2(30), fechaingreso date, seccion varchar2(20), sueldo number(6,2), primary key(documento) ); 3- Ingrese algunos registros: insert into empleados values('Juan Perez','22333444','Colon 123','08/10/1990','Gerencia',900.50); insert into empleados values('Ana Acosta','23444555','Caseros 987','18/12/1995','Secretaria',590.30); insert into empleados values('Lucas Duarte','25666777','Sucre 235','15/05/2005','Sistemas',790); insert into empleados values('Pamela Gonzalez','26777888','Sarmiento 873','12/02/1999','Secretaria',550); insert into empleados values('Marcos Juarez','30000111','Rivadavia 801','22/09/2002','Contaduria',630.70); insert into empleados values('Yolanda perez','35111222','Colon 180','08/10/1990','Administracion',400); insert into empleados values('Rodolfo perez','35555888','Coronel Olmedo 588','28/05/1990','Sistemas',800); 4- Muestre todos los empleados con apellido "Perez" empleando el operador "like" (1 registro) Note que no incluye los "perez" (que comienzan con minscula). 5- Muestre todos los empleados cuyo domicilio comience con "Co" y tengan un "8" (2 registros) 6- Seleccione todos los empleados cuyo documento finalice en 0 4 (2 registros)

7- Seleccione todos los empleados cuyo documento NO comience con 2 y cuyo nombre finalice en "ez" (1 registro) 8- Recupere todos los nombres que tengan una "G" o una "J" en su nombre o apellido (3 registros) 9- Muestre los nombres y seccin de los empleados que pertenecen a secciones que comiencen con "S" o "G" y tengan 8 caracteres (3 registros) 10- Muestre los nombres y seccin de los empleados que pertenecen a secciones que NO comiencen con "S" (3 registros) 11- Muestre todos los nombres y sueldos de los empleados cuyos sueldos se encuentren entre 500,00 y 599,99 empleando "like" (2 registros) 12- Muestre los empleados que hayan ingresado en la dcada del 90 (5 registros) 13- Agregue 50 centavos a todos los sueldos que no tengan centavos (4 registros) y verifique recuperando todos los registros. 14- Elimine todos los empleados cuyos apellidos comiencen con "p" (minscula) (2 registros)

Solucion: drop table empleados; create table empleados( nombre varchar2(30), documento char(8) not null, domicilio varchar2(30), fechaingreso date, seccion varchar2(20), sueldo number(6,2), primary key(documento) ); insert into empleados values('Juan Perez','22333444','Colon 123','08/10/1990','Gerencia',900.50); insert into empleados values('Ana Acosta','23444555','Caseros 987','18/12/1995','Secretaria',590.30); insert into empleados values('Lucas Duarte','25666777','Sucre 235','15/05/2005','Sistemas',790);

insert into empleados values('Pamela Gonzalez','26777888','Sarmiento 873','12/02/1999','Secretaria',550); insert into empleados values('Marcos Juarez','30000111','Rivadavia 801','22/09/2002','Contaduria',630.70); insert into empleados values('Yolanda perez','35111222','Colon 180','08/10/1990','Administracion',400); insert into empleados values('Rodolfo perez','35555888','Coronel Olmedo 588','28/05/1990','Sistemas',800); select *from empleados where nombre like '%Perez%'; select *from empleados where domicilio like 'Co%8%'; select *from empleados where documento like '%1' or documento like '%4'; select *from empleados where documento not like '2%' and nombre like '%ez'; select nombre from empleados where nombre like '%G%' or nombre like '%J%'; select nombre,seccion from empleados where seccion like 'S_______' or seccion like 'G_______'; select nombre,seccion from empleados where seccion not like 'S%'; select nombre,sueldo from empleados where sueldo like '5__%'; select *from empleados where fechaingreso like '%9_'; update empleados set sueldo=sueldo+0.50 where sueldo not like '%,%'; select sueldo from empleados; delete from empleados where nombre like '% p%';

29 - Contar registros (count)

Existen en Oracle funciones que nos permiten contar registros, calcular sumas, promedios, obtener valores mximos y mnimos. Estas funciones se denominan funciones de grupo y operan sobre un conjunto de valores (registros), no con datos individuales y devuelven un nico valor. Imaginemos que nuestra tabla "libros" contiene muchos registros. Para averiguar la cantidad sin necesidad de contarlos manualmente usamos la funcin "count()": select count(*) from libros; La funcin "count()" cuenta la cantidad de registros de una tabla, incluyendo los que tienen valor nulo. Tambin podemos utilizar esta funcin junto con la clausula "where" para una consulta ms especfica. Queremos saber la cantidad de libros de la editorial "Planeta": select count(*) from libros where editorial='Planeta'; Para contar los registros que tienen precio (sin tener en cuenta los que tienen valor nulo), usamos la funcin "count()" y en los parntesis colocamos el nombre del campo que necesitamos contar: select count(precio) from libros; Note que "count(*)" retorna la cantidad de registros de una tabla (incluyendo los que tienen valor "null") mientras que "count(precio)" retorna la cantidad de registros en los cuales el campo "precio" no es nulo. No es lo mismo. "count(*)" cuenta registros, si en lugar de un asterisco colocamos como argumento el nombre de un campo, se contabilizan los registros cuyo valor en ese campo NO es nulo. Ejercicio 1: Primer problema: Trabaje con la tabla llamada "medicamentos" de una farmacia. 1- Elimine la tabla: drop table medicamentos; 2- Cree la tabla con la siguiente estructura: create table medicamentos( codigo number(5), nombre varchar2(20), laboratorio varchar2(20), precio number(6,2), cantidad number(3), fechavencimiento date not null, numerolote number(6) default null,

primary key(codigo) ); 3- Ingrese algunos registros: insert into medicamentos values(120,'Sertal','Roche',5.2,1,'01/02/2005',123456); insert into medicamentos values(220,'Buscapina','Roche',4.10,3,'01/02/2006',null); insert into medicamentos values(228,'Amoxidal 500','Bayer',15.60,100,'01/05/2007',null); insert into medicamentos values(324,'Paracetamol 500','Bago',1.90,20,'01/02/2008',null); insert into medicamentos values(587,'Bayaspirina',null,2.10,null,'01/12/2009',null); insert into medicamentos values(789,'Amoxidal jarabe','Bayer',null,null,'15/12/2009',null); 4- Muestre la cantidad de registros empleando la funcin "count(*)" (6 registros) 5- Cuente la cantidad de medicamentos que tienen laboratorio conocido (5 registros) 6- Cuente la cantidad de medicamentos que tienen precio y cantidad, con alias (5 y 4 respectivamente) 7- Cuente la cantidad de remedios con precio conocido, cuyo laboratorio comience con "B" (2 registros) 8- Cuente la cantidad de medicamentos con nmero de lote distinto de "null" (1 registro) 9- Cuente la cantidad de medicamentos con fecha de vencimiento conocida (6 registros) Solucion: drop table medicamentos; create table medicamentos( codigo number(5), nombre varchar2(20), laboratorio varchar2(20), precio number(6,2), cantidad number(3), fechavencimiento date not null, numerolote number(6) default null, primary key(codigo) ); insert into medicamentos values(120,'Sertal','Roche',5.2,1,'01/02/2005',123456); insert into medicamentos values(220,'Buscapina','Roche',4.10,3,'01/02/2006',null); insert into medicamentos

values(228,'Amoxidal 500','Bayer',15.60,100,'01/05/2007',null); insert into medicamentos values(324,'Paracetamol 500','Bago',1.90,20,'01/02/2008',null); insert into medicamentos values(587,'Bayaspirina',null,2.10,null,'01/12/2009',null); insert into medicamentos values(789,'Amoxidal jarabe','Bayer',null,null,'15/12/2009',null); select count(*) from medicamentos; select count(laboratorio) from medicamentos; select count(precio) as "Con precio", count(cantidad) as "Con cantidad" from medicamentos; select count(precio) from medicamentos where laboratorio like 'B%'; select count(numerolote) from medicamentos; select count(fechavencimiento) from medicamentos;

30 - Funciones de grupo (count - max - min - sum - avg)


Hemos visto que Oracle dispone de funciones que nos permiten contar registros, calcular sumas, promedios, obtener valores mximos y mnimos, las funciones de grupo. Las funciones de grupo operan sobre un conjunto de valores (registros) y retornan un solo valor. Ya hemos aprendido una de ellas, "count()", veamos otras. Se pueden usar en una instruccin "select" y combinarlas con la clusula "group by" (la veremos posteriormente). Todas estas funciones retornan "null" si ningn registro cumple con la condicion del "where" (excepto "count" que en tal caso retorna cero). El tipo de dato del campo determina las funciones que se pueden emplear con ellas. Las relaciones entre las funciones de agrupamiento y los tipos de datos es la siguiente:

- count: se puede emplear con cualquier tipo de dato. - min y max: con cualquier tipo de dato. - sum y avg: slo en campos de tipo numrico. La funcin "sum()" retorna la suma de los valores que contiene el campo especificado. Si queremos saber la cantidad total de libros que tenemos disponibles para la venta, debemos sumar todos los valores del campo "cantidad": select sum(cantidad) from libros; Para averiguar el valor mximo o mnimo de un campo usamos las funciones "max()" y "min()" respectivamente. Queremos saber cul es el mayor precio de todos los libros: select max(precio) from libros; Entonces, dentro del parntesis de la funcin colocamos el nombre del campo del cul queremos el mximo valor. La funcin "avg()" retorna el valor promedio de los valores del campo especificado. Queremos saber el promedio del precio de los libros referentes a "PHP": select avg(precio) from libros where titulo like '%PHP%'; Ahora podemos entender porque estas funciones se denominan "funciones de grupo", porque operan sobre conjuntos de registros, no con datos individuales. Tratamiento de los valores nulos: Si realiza una consulta con la funcin "count" incluyendo entre parntesis un campo y la tabla contiene 18 registros, 2 de los cuales contienen valor nulo en "precio", el resultado devuelve un total de 16 filas porque no considera aquellos con valor nulo. Todas las funciones de grupo, excepto "count(*)", excluye los valores nulos de los campos; "count(*)" cuenta todos los registros, incluidos los que contienen "null". Ejercicio: Primer problema: Una empresa almacena los datos de sus empleados en una tabla "empleados". 1- Elimine la tabla y crela con la siguiente estructura: drop table empleados;

create table empleados( nombre varchar2(30), documento char(8), domicilio varchar2(30), seccion varchar2(20), sueldo number(6,2), cantidadhijos number(2), fechaingreso date, primary key(documento) ); 3- Ingrese algunos registros: insert into empleados values('Juan Perez','22333444','Colon 123','Gerencia',5000,2,'10/10/1980'); insert into empleados values('Ana Acosta','23444555','Caseros 987','Secretaria',2000,0,'15/08/1998'); insert into empleados values('Lucas Duarte','25666777','Sucre 235','Sistemas',4000,1,null); insert into empleados values('Pamela Gonzalez','26777888','Sarmiento 873','Secretaria',2200,3,null); insert into empleados values('Marcos Juarez','30000111','Rivadavia 801','Contaduria',3000,0,'26/08/2000'); insert into empleados values('Yolanda Perez','35111222','Colon 180','Administracion',3200,1,'25/09/2001'); insert into empleados values('Rodolfo Perez','35555888','Coronel Olmedo 588','Sistemas',4000,3,null); insert into empleados values('Martina Rodriguez','30141414','Sarmiento 1234','Administracion',3800,4,'14/12/2000'); insert into empleados values('Andres Costa','28444555',default,'Secretaria',null,null,'08/08/1990'); 4- Muestre la cantidad de empleados usando "count" (9 empleados) 5- Muestre la cantidad de empleados con fecha de ingreso conocida (6 empleados) 6- Muestre la cantidad de empleados con sueldo (8 empleados) 7- Muestre la cantidad de empleados con sueldo de la seccin "Secretaria" (2 empleados) 8- Muestre el sueldo ms alto y el ms bajo colocando un alias (5000 y 2000 respectivamente) 9- Muestre el valor mayor de "cantidadhijos" de los empleados "Perez" (3 hijos) 10- Muestre la fecha de ingreso ms reciente (max) y la ms lejana (min) (25/09/01 y 10/10/80 respectivamente) 11- Muestre el documento menor (22333444) 12- Muestre el promedio de sueldos de todo los empleados (3400. Note que hay un sueldo nulo y no es tenido en cuenta)

13- Muestre el promedio de sueldos de los empleados de la seccin "Secretara" (2100. Note que hay 3 registros de la seccin solicitada, pero como uno de ellos tiene sueldo nulo, no es tenido en cuenta) 14- Muestre el promedio de hijos de todos los empleados de "Sistemas" (retorna 2) 15- Muestre la cantidad de empleados, la cantidad de empleados con domicilio conocido, la suma de los hijos, el promedio de los sueldos y los valores mnimo y mximo del campo "fechaingreso" de todos los empleados. Empleamos todas las funciones de grupo en una sola consulta y nos retorna 9, 8, 14, 3400, 10/10/80 y 25/09/01. 16- Realice la misma consulta anterior pero ahora de los empleados de la seccin "Recursos". Al no existir tal seccin, "count(*)" y "count(domicilio)" retornan 0 (cero) y las dems funciones de grupo retornan "null". Solucion: drop table empleados; create table empleados( nombre varchar2(30), documento char(8), domicilio varchar2(30), seccion varchar2(20), sueldo number(6,2), cantidadhijos number(2), fechaingreso date, primary key(documento) ); insert into empleados values('Juan Perez','22333444','Colon 123','Gerencia',5000,2,'10/10/1980'); insert into empleados values('Ana Acosta','23444555','Caseros 987','Secretaria',2000,0,'15/08/1998'); insert into empleados values('Lucas Duarte','25666777','Sucre 235','Sistemas',4000,1,null); insert into empleados values('Pamela Gonzalez','26777888','Sarmiento 873','Secretaria',2200,3,null); insert into empleados values('Marcos Juarez','30000111','Rivadavia 801','Contaduria',3000,0,'26/08/2000'); insert into empleados values('Yolanda Perez','35111222','Colon 180','Administracion',3200,1,'25/09/2001'); insert into empleados values('Rodolfo Perez','35555888','Coronel Olmedo 588','Sistemas',4000,3,null); insert into empleados values('Martina Rodriguez','30141414','Sarmiento 1234','Administracion',3800,4,'14/12/2000'); insert into empleados values('Andres Costa','28444555',default,'Secretaria',null,null,'08/08/1990'); select count(*) from empleados;

select count(fechaingreso) from empleados; select count(sueldo) from empleados; select count(sueldo) from empleados where seccion='Secretaria'; select max(sueldo) as "Mayor sueldo", min(sueldo) as "Menor sueldo" from empleados; select max(cantidadhijos) from empleados where nombre like '%Perez%'; select max(fechaingreso),min(fechaingreso) from empleados; select min(documento) from empleados; select avg(sueldo) from empleados; select avg(sueldo) from empleados where seccion='Secretaria'; select avg(cantidadhijos) from empleados where seccion='Sistemas'; select count(*),count(domicilio),sum(cantidadhijos),avg(sueldo),min(fechaingreso),max(fech aingreso) from empleados; select count(*),count(domicilio),sum(cantidadhijos),avg(sueldo),min(fechaingreso),max(fech aingreso) from empleados where seccion='Recursos';

31 - Agrupar registros (group by)


Hemos aprendido que las funciones de grupo permiten realizar varios clculos operando con conjuntos de registros. Las funciones de grupo solas producen un valor de resumen para todos los registros de un campo.

Podemos generar valores de resumen para un solo campo, combinando las funciones de agregado con la clusula "group by", que agrupa registros para consultas detalladas. Queremos saber la cantidad de libros de cada editorial, podemos tipear la siguiente sentencia: select count(*) from libros where editorial='Planeta'; y repetirla con cada valor de "editorial": select where select where ... count(*) from libros editorial='Emece'; count(*) from libros editorial='Paidos';

Pero hay otra manera, utilizando la clusula "group by": select editorial, count(*) from libros group by editorial; La instruccin anterior solicita que muestre el nombre de la editorial y cuente la cantidad agrupando los registros por el campo "editorial". Como resultado aparecen los nombres de las editoriales y la cantidad de registros para cada valor del campo. Los valores nulos se procesan como otro grupo. Entonces, para saber la cantidad de libros que tenemos de cada editorial, utilizamos la funcin "count()", agregamos "group by" (que agrupa registros) y el campo por el que deseamos que se realice el agrupamiento, tambin colocamos el nombre del campo a recuperar; la sintaxis bsica es la siguiente: select CAMPO, FUNCIONDEAGREGADO from NOMBRETABLA group by CAMPO; Tambin se puede agrupar por ms de un campo, en tal caso, luego del "group by" se listan los campos, separados por comas. Todos los campos que se especifican en la clusula "group by" deben estar en la lista de seleccin. select CAMPO1, CAMPO2, FUNCIONDEAGREGADO from NOMBRETABLA group by CAMPO1,CAMPO2; Para obtener la cantidad libros con precio no nulo, de cada editorial utilizamos la funcin "count()" envindole como argumento el campo "precio", agregamos "group by" y el campo por el que deseamos que se realice el agrupamiento (editorial): select editorial, count(precio) from libros group by editorial;

Como resultado aparecen los nombres de las editoriales y la cantidad de registros de cada una, sin contar los que tienen precio nulo. Recuerde la diferencia de los valores que retorna la funcin "count()" cuando enviamos como argumento un asterisco o el nombre de un campo: en el primer caso cuenta todos los registros incluyendo los que tienen valor nulo, en el segundo, los registros en los cuales el campo especificado es no nulo. Para conocer el total de libros agrupados por editorial: select editorial, sum(cantidad) from libros group by editorial; Para saber el mximo y mnimo valor de los libros agrupados por editorial: select editorial, max(precio) as mayor, min(precio) as menor from libros group by editorial; Para calcular el promedio del valor de los libros agrupados por editorial: select editorial, avg(precio) from libros group by editorial; Es posible limitar la consulta con "where". Si incluye una clusula "where", slo se agrupan los registros que cumplen las condiciones. Vamos a contar y agrupar por editorial considerando solamente los libros cuyo precio sea menor a 30 pesos: select editorial, count(*) from libros where precio<30 group by editorial; Note que las editoriales que no tienen libros que cumplan la condicin, no aparecen en la salida. Entonces, usamos "group by" para organizar registros en grupos y obtener un resumen de dichos grupos. Oracle produce una columna de valores por cada grupo, devolviendo filas por cada grupo especificado. Ejercicio 1: Primer problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos.

1- Elimine la tabla "visitantes" y crela con la siguiente estructura: drop table visitantes; create table visitantes( nombre varchar2(30), edad number(2), sexo char(1) default 'f', domicilio varchar2(30), ciudad varchar2(20) default 'Cordoba', telefono varchar2(11), mail varchar2(30) default 'no tiene', montocompra number(6,2) ); 3- Ingrese algunos registros: insert into visitantes values ('Susana Molina',35,default,'Colon 123',default,null,null,59.80); insert into visitantes values ('Marcos Torres',29,'m',default,'Carlos Paz',default,'marcostorres@hotmail.com',150.50); insert into visitantes values ('Mariana Juarez',45,default,default,'Carlos Paz',null,default,23.90); insert into visitantes (nombre, edad,sexo,telefono, mail) values ('Fabian Perez',36,'m','4556677','fabianperez@xaxamail.com'); insert into visitantes (nombre, ciudad, montocompra) values ('Alejandra Gonzalez','La Falda',280.50); insert into visitantes (nombre, edad,sexo, ciudad, mail,montocompra) values ('Gaston Perez',29,'m','Carlos Paz','gastonperez1@gmail.com',95.40); insert into visitantes values ('Liliana Torres',40,default,'Sarmiento 876',default,default,default,85); insert into visitantes values ('Gabriela Duarte',21,null,null,'Rio Tercero',default,'gabrielaltorres@hotmail.com',321.50); 4- Queremos saber la cantidad de visitantes de cada ciudad utilizando la clusula "group by" (4 filas devueltas) 5- Queremos la cantidad visitantes con telfono no nulo, de cada ciudad (4 filas devueltas) 6- Necesitamos el total del monto de las compras agrupadas por sexo (3 filas) Note que los registros con valor nulo en el campo "sexo" se procesan como un grupo diferente. 7- Se necesita saber el mximo y mnimo valor de compra agrupados por sexo y ciudad (6 filas) 8- Calcule el promedio del valor de compra agrupados por ciudad (4 filas) 9- Cuente y agrupe por ciudad sin tener en cuenta los visitantes que no tienen mail (3 filas) Solucion: drop table visitantes;

create table visitantes( nombre varchar2(30), edad number(2), sexo char(1) default 'f', domicilio varchar2(30), ciudad varchar2(20) default 'Cordoba', telefono varchar2(11), mail varchar2(30) default 'no tiene', montocompra number(6,2) ); insert into visitantes values ('Susana Molina',35,default,'Colon 123',default,null,null,59.80); insert into visitantes values ('Marcos Torres',29,'m',default,'Carlos Paz',default,'marcostorres@hotmail.com',150.50); insert into visitantes values ('Mariana Juarez',45,default,default,'Carlos Paz',null,default,23.90); insert into visitantes (nombre, edad,sexo,telefono, mail) values ('Fabian Perez',36,'m','4556677','fabianperez@xaxamail.com'); insert into visitantes (nombre, ciudad, montocompra) values ('Alejandra Gonzalez','La Falda',280.50); insert into visitantes (nombre, edad,sexo, ciudad, mail,montocompra) values ('Gaston Perez',29,'m','Carlos Paz','gastonperez1@gmail.com',95.40); insert into visitantes values ('Liliana Torres',40,default,'Sarmiento 876',default,default,default,85); insert into visitantes values ('Gabriela Duarte',21,null,null,'Rio Tercero',default,'gabrielaltorres@hotmail.com',321.50); select ciudad, count(*) from visitantes group by ciudad; select ciudad, count(telefono) from visitantes group by ciudad; select sexo, sum(montocompra) from visitantes group by sexo; select sexo,ciudad, max(montocompra) as mayor, min(montocompra) as menor from visitantes group by sexo,ciudad; select ciudad, avg(montocompra) as "promedio de compras" from visitantes group by ciudad;

select ciudad, count(*) as "cantidad con mail" from visitantes where mail is not null and mail<>'no tiene'

group by ciudad; Ejercicio 2:


Segundo problema: Una empresa almacena los datos de sus empleados en una tabla "empleados". 1- Elimine la tabla y luego crela con la estructura definida a continuacin: drop table empleados; create table empleados( nombre varchar2(30), documento char(8), domicilio varchar2(30), seccion varchar2(20), sueldo number(6,2), cantidadhijos number(2), fechaingreso date, primary key(documento) ); 3- Ingrese algunos registros: insert into empleados values('Juan Perez','22333444','Colon 123','Gerencia',5000,2,'10/05/1980'); insert into empleados values('Ana Acosta','23444555','Caseros 987','Secretaria',2000,0,'12/10/1980'); insert into empleados values('Lucas Duarte','25666777','Sucre 235','Sistemas',4000,1,'25/05/1985'); insert into empleados values('Pamela Gonzalez','26777888','Sarmiento 873','Secretaria',2200,3,'25/06/1990'); insert into empleados values('Marcos Juarez','30000111','Rivadavia 801','Contaduria',3000,0,'01/05/1996'); insert into empleados values('Yolanda Perez','35111222','Colon 180','Administracion',3200,1,'01/05/1996'); insert into empleados values('Rodolfo Perez','35555888','Coronel Olmedo 588','Sistemas',4000,3,'01/05/1996'); insert into empleados values('Martina Rodriguez','30141414','Sarmiento 1234','Administracion',3800,4,'01/09/2000'); insert into empleados values('Andres Costa','28444555',default,'Secretaria',null,null,null);

4- Cuente la cantidad de empleados agrupados por seccin (5 filas) 5- Calcule el promedio de hijos por seccin (5 filas) 6- Cuente la cantidad de empleados agrupados por ao de ingreso (6 filas) 7- Calcule el promedio de sueldo por seccin de los empleados con hijos (4 filas) Solucin 2: drop table empleados; create table empleados( nombre varchar2(30), documento char(8), domicilio varchar2(30), seccion varchar2(20), sueldo number(6,2), cantidadhijos number(2), fechaingreso date, primary key(documento) ); insert into empleados values('Juan Perez','22333444','Colon 123','Gerencia',5000,2,'10/05/1980'); insert into empleados values('Ana Acosta','23444555','Caseros 987','Secretaria',2000,0,'12/10/1980'); insert into empleados values('Lucas Duarte','25666777','Sucre 235','Sistemas',4000,1,'25/05/1985'); insert into empleados values('Pamela Gonzalez','26777888','Sarmiento 873','Secretaria',2200,3,'25/06/1990'); insert into empleados values('Marcos Juarez','30000111','Rivadavia 801','Contaduria',3000,0,'01/05/1996'); insert into empleados values('Yolanda Perez','35111222','Colon 180','Administracion',3200,1,'01/05/1996'); insert into empleados values('Rodolfo Perez','35555888','Coronel Olmedo 588','Sistemas',4000,3,'01/05/1996'); insert into empleados values('Martina Rodriguez','30141414','Sarmiento 1234','Administracion',3800,4,'01/09/2000'); insert into empleados values('Andres Costa','28444555',default,'Secretaria',null,null,null); select seccion, count(*) from empleados group by seccion; select seccion, avg(cantidadhijos) as "promedio de hijos" from empleados group by seccion;

select datepart(year,fechaingreso) as ingreso, count(*) from empleados group by datepart(year,fechaingreso); select seccion, avg(sueldo) as "promedio de sueldo" from empleados where cantidadhijos>0 and cantidadhijos is not null group by seccion;

32 - Seleccionar grupos (Having)


As como la clusula "where" permite seleccionar (o rechazar) registros individuales; la clusula "having" permite seleccionar (o rechazar) un grupo de registros. Si queremos saber la cantidad de libros agrupados por editorial usamos la siguiente instruccin ya aprendida: select editorial, count(*) from libros group by editorial; Si queremos saber la cantidad de libros agrupados por editorial pero considerando slo algunos grupos, por ejemplo, los que devuelvan un valor mayor a 2, usamos la siguiente instruccin: select editorial, count(*) from libros group by editorial having count(*)>2; Se utiliza "having", seguido de la condicin de bsqueda, para seleccionar ciertas filas retornadas por la clusula "group by". Veamos otros ejemplos. Queremos el promedio de los precios agrupados por editorial, pero solamente de aquellos grupos cuyo promedio supere los 25 pesos: select editorial, avg(precio) from libros group by editorial having avg(precio)>25; En algunos casos es posible confundir las clusulas "where" y "having". Queremos contar los registros agrupados por editorial sin tener en cuenta a la editorial "Planeta". Analicemos las siguientes sentencias: select editorial, count(*) from libros where editorial<>'Planeta' group by editorial; select editorial, count(*) from libros group by editorial having editorial<>'Planeta';

Ambas devuelven el mismo resultado, pero son diferentes. La primera, selecciona todos los registros rechazando los de editorial "Planeta" y luego los agrupa para contarlos. La segunda, selecciona todos los registros, los agrupa para contarlos y finalmente rechaza fila con la cuenta correspondiente a la editorial "Planeta". No debemos confundir la clusula "where" con la clusula "having"; la primera establece condiciones para la seleccin de registros de un "select"; la segunda establece condiciones para la seleccin de registros de una salida "group by". Veamos otros ejemplos combinando "where" y "having". Queremos la cantidad de libros, sin considerar los que tienen precio nulo, agrupados por editorial, sin considerar la editorial "Planeta": select editorial, count(*) from libros where precio is not null group by editorial having editorial<>'Planeta'; Aqu, selecciona los registros rechazando los que no cumplan con la condicin dada en "where", luego los agrupa por "editorial" y finalmente rechaza los grupos que no cumplan con la condicin dada en el "having". Se emplea la clusula "having" con funciones de grupo, esto no puede hacerlo la clusula "where". Por ejemplo queremos el promedio de los precios agrupados por editorial, de aquellas editoriales que tienen ms de 2 libros: select editorial, avg(precio) from libros group by editorial having count(*) > 2; En una clusula "having" puede haber varias condiciones. Cuando utilice varias condiciones, tiene que combinarlas con operadores lgicos (and, or, not). Podemos encontrar el mayor valor de los libros agrupados y ordenados por editorial y seleccionar las filas que tengan un valor menor a 100 y mayor a 30: select editorial, max(precio) as mayor from libros group by editorial having min(precio)<100 and min(precio)>30 order by editorial;

Entonces, usamos la clausula "having" para restringir las filas que devuelve una salida "group by". Va siempre despus de la clusula "group by" y antes de la clusula "order by" si la hubiere. Ejercicios: Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes".

1- Elimine la tabla "clientes": drop table clientes; 2- Crela con la siguiente estructura: create table clientes ( nombre varchar2(30) not null, domicilio varchar2(30), ciudad varchar2(20), provincia varchar2(20), telefono varchar2(11) ); 3- Ingrese algunos registros: insert into clientes values ('Lopez Marcos','Colon 111','Cordoba','Cordoba','null'); insert into clientes values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba','4578585'); insert into clientes values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba','4578445'); insert into clientes values ('Perez Luis','Sarmiento 444','Rosario','Santa Fe',null); insert into clientes values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba','4253685'); insert into clientes values ('Gomez Ines','San Martin 666','Santa Fe','Santa Fe','0345252525'); insert into clientes values ('Torres Fabiola','Alem 777','Villa del Rosario','Cordoba','4554455'); insert into clientes values ('Lopez Carlos',null,'Cruz del Eje','Cordoba',null); insert into clientes values ('Ramos Betina','San Martin 999','Cordoba','Cordoba','4223366'); insert into clientes values ('Lopez Lucas','San Martin 1010','Posadas','Misiones','0457858745'); 4- Obtenga el total de los registros agrupados por ciudad y provincia (6 filas) 5- Obtenga el total de los registros agrupados por ciudad y provincia sin considerar los que tienen menos de 2 clientes (3 filas) 6- Obtenga el total de los clientes que viven en calle "San Martin" (where), agrupados por provincia (group by), de aquellas ciudades que tengan menos de 2 clientes (having) y omitiendo la fila correspondiente a la ciudad de "Cordoba" (having) (2 filas devueltas) Solucion: drop table clientes; create table clientes ( nombre varchar2(30) not null,

domicilio varchar2(30), ciudad varchar2(20), provincia varchar2(20), telefono varchar2(11) ); insert into clientes values ('Lopez Marcos','Colon 111','Cordoba','Cordoba','null'); insert into clientes values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba','4578585'); insert into clientes values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba','4578445'); insert into clientes values ('Perez Luis','Sarmiento 444','Rosario','Santa Fe',null); insert into clientes values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba','4253685'); insert into clientes values ('Gomez Ines','San Martin 666','Santa Fe','Santa Fe','0345252525'); insert into clientes values ('Torres Fabiola','Alem 777','Villa del Rosario','Cordoba','4554455'); insert into clientes values ('Lopez Carlos',null,'Cruz del Eje','Cordoba',null); insert into clientes values ('Ramos Betina','San Martin 999','Cordoba','Cordoba','4223366'); insert into clientes values ('Lopez Lucas','San Martin 1010','Posadas','Misiones','0457858745'); select ciudad, provincia, count(*) as cantidad from clientes group by ciudad,provincia; select ciudad, provincia, count(*) as cantidad from clientes group by ciudad,provincia having count(*)>1; select ciudad, count(*) from clientes where domicilio like '%San Martin%' group by all ciudad having count(*)<2 and

ciudad <> 'Cordoba'; Ejercicio 2:


Segundo problema: Un comercio que tiene un stand en una feria registra en una tabla llamada "visitantes" algunos datos de las personas que visitan o compran en su stand para luego enviarle publicidad de sus productos.

1- Elimine la tabla "visitantes": drop table visitantes; 2- Crela con la siguiente estructura: create table visitantes( nombre varchar2(30), edad number(2), sexo char(1), domicilio varchar2(30), ciudad varchar2(20), telefono varchar2(11), montocompra number(6,2) not null ); 3- Ingrese algunos registros: insert into visitantes values ('Susana Molina',28,'f',null,'Cordoba',null,45.50); insert into visitantes values ('Marcela Mercado',36,'f','Avellaneda 345','Cordoba','4545454',22.40); insert into visitantes values ('Alberto Garcia',35,'m','Gral. Paz 123','Alta Gracia','03547123456',25); insert into visitantes values ('Teresa Garcia',33,'f',default,'Alta Gracia','03547123456',120); insert into visitantes values ('Roberto Perez',45,'m','Urquiza 335','Cordoba','4123456',33.20); insert into visitantes values ('Marina Torres',22,'f','Colon 222','Villa Dolores','03544112233',95); insert into visitantes values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia',null,53.50); insert into visitantes values ('Roxana Lopez',20,'f','null','Alta Gracia',null,240); insert into visitantes values ('Liliana Garcia',50,'f','Paso 999','Cordoba','4588778',48); insert into visitantes values ('Juan Torres',43,'m','Sarmiento 876','Cordoba',null,15.30); 4- Obtenga el total de las compras agrupados por ciudad y sexo de aquellas filas que devuelvan un valor superior a 50 (3 filas) 5- Obtenga el total de las compras agrupados por ciudad y sexo (group by), considerando slo los montos de compra superiores a 50 (where), los visitantes con telfono (where), sin considerar la ciudad de "Cordoba" (having), ordenados por ciudad (order by) (2 filas) 6- Muestre el monto mayor de compra agrupado por ciudad, siempre que dicho valor supere los 50 pesos (having), considerando slo los visitantes de sexo femenino y domicilio conocido (where) (2 filas)

7- Agrupe por ciudad y sexo, muestre para cada grupo el total de visitantes, la suma de sus compras y el promedio de compras, ordenado por la suma total y considerando las filas con promedio superior a 30 (3 filas) Solucion: drop table visitantes; create table visitantes( nombre varchar2(30), edad number(2), sexo char(1), domicilio varchar2(30), ciudad varchar2(20), telefono varchar2(11), montocompra number(6,2) not null ); insert into visitantes values ('Susana Molina',28,'f',null,'Cordoba',null,45.50); insert into visitantes values ('Marcela Mercado',36,'f','Avellaneda 345','Cordoba','4545454',22.40); insert into visitantes values ('Alberto Garcia',35,'m','Gral. Paz 123','Alta Gracia','03547123456',25); insert into visitantes values ('Teresa Garcia',33,'f',default,'Alta Gracia','03547123456',120); insert into visitantes values ('Roberto Perez',45,'m','Urquiza 335','Cordoba','4123456',33.20); insert into visitantes values ('Marina Torres',22,'f','Colon 222','Villa Dolores','03544112233',95); insert into visitantes values ('Julieta Gomez',24,'f','San Martin 333','Alta Gracia',null,53.50); insert into visitantes values ('Roxana Lopez',20,'f','null','Alta Gracia',null,240); insert into visitantes values ('Liliana Garcia',50,'f','Paso 999','Cordoba','4588778',48); insert into visitantes values ('Juan Torres',43,'m','Sarmiento 876','Cordoba',null,15.30); select ciudad,sexo, sum(montocompra) as Total from visitantes group by ciudad,sexo having sum(montocompra)>50; select ciudad, sexo, sum(montocompra) as total from visitantes where montocompra>50 and telefono is not null group by ciudad,sexo having ciudad<>'Cordoba' order by ciudad;

select ciudad,max(montocompra) as maximo from visitantes where domicilio is not null and sexo='f' group by all ciudad having max(montocompra)>50; select ciudad,sexo, count(*) as cantidad, sum(montocompra) as total, avg(montocompra) as promedio from visitantes group by ciudad,sexo having avg(montocompra)>30

order by total; Interpretacin:


Problema: Trabajamos con la tabla "libros" de una librera. Eliminamos la tabla: drop table libros; Creamos la tabla: create table libros( titulo varchar2(40), autor varchar2(30), editorial varchar2(15), precio number(5,2), cantidad number(3) ); Ingresamos algunos registros: insert into libros values('El aleph','Borges','Planeta',35,null); insert into libros values('Martin Fierro','Jose Hernandez','Emece',22.20,200); insert into libros values('Martin Fierro','Jose Hernandez','Planeta',40,200); insert into libros values('Antologia poetica','J.L. Borges','Planeta',null,150); insert into libros values('Aprenda PHP','Mario Molina','Emece',18,null); insert into libros values('Manual de PHP', 'J.C. Paez', 'Siglo XXI',56,120); insert into libros values('Cervantes y el quijote','Bioy Casares- J.L. Borges','Paidos',null,100);

insert into libros values('Harry Potter y la piedra filosofal','J.K. Rowling',default,45.00,90); insert into libros values('Harry Potter y la camara secreta','J.K. Rowling','Emece',null,100); insert into libros values('Alicia en el pais de las maravillas','Lewis Carroll','Paidos',42,80); insert into libros values('PHP de la A a la Z',null,null,110,0); insert into libros values('Uno','Richard Bach','Planeta',25,null); Queremos saber la cantidad de libros agrupados por editorial: select editorial, count(*) from libros group by editorial; Nos devuelve: EDITORIAL COUNT(*) -----------------------Paidos 2 2 Planeta 4 Emece 3 Siglo XXI 1 Queremos saber la cantidad de libros agrupados por editorial pero considerando slo algunos grupos, por ejemplo, los que devuelvan un valor mayor a 2, usamos la siguiente instruccin: select editorial, count(*) from libros group by editorial having count(*)>2; La salida es la siguiente: EDITORIAL COUNT(*) ------------------------Planeta 4 Emece 3 Compare esta salida con la de la sentencia anterior. Queremos el promedio de los precios de los libros agrupados por editorial, pero solamente de aquellos grupos cuyo promedio supere los 25 pesos: select editorial, avg(precio) from libros group by editorial having avg(precio)>25; Queremos la cantidad de libros, sin considerar los que tienen precio nulo (where), agrupados por editorial (group by), sin considerar la editorial "Planeta" (having):

select editorial, count(*) from libros where precio is not null group by editorial having editorial<>'Planeta'; Necesitamos el promedio de los precios agrupados por editorial, de aquellas editoriales que tienen ms de 2 libros: select editorial, avg(precio) from libros group by editorial having count(*) > 2; Buscamos el mayor valor de los libros agrupados y ordenados por editorial y seleccionamos las filas que tienen un valor menor a 100 y mayor a 30: select editorial, max(precio) as mayor from libros group by editorial having max(precio)<100 and max(precio)>30 order by editorial;

33 - Registros duplicados (Distinct)


Con la clusula "distinct" se especifica que los registros con ciertos datos duplicados sean obviadas en el resultado. Por ejemplo, queremos conocer todos los autores de los cuales tenemos libros, si utilizamos esta sentencia: select autor from libros; Aparecen repetidos. Para obtener la lista de autores sin repeticin usamos: select distinct autor from libros; Tambin podemos tipear: select autor from libros group by autor; Note que en los tres casos anteriores aparece "null" como un valor para "autor" Si slo queremos la lista de autores conocidos, es decir, no queremos incluir "null" en la lista, podemos utilizar la sentencia siguiente: select distinct autor from libros where autor is not null;

Para contar los distintos autores, sin considerar el valor "null" usamos: select count(distinct autor) from libros; Note que si contamos los autores sin "distinct", no incluir los valores "null" pero si los repetidos: select count(autor) from libros; Esta sentencia cuenta los registros que tienen autor. Podemos combinarla con "where". Por ejemplo, queremos conocer los distintos autores de la editorial "Planeta": select distinct autor from libros where editorial='Planeta'; Tambin puede utilizarse con "group by" para contar los diferentes autores por editorial: select editorial, count(distinct autor) from libros group by editorial; La clusula "distinct" afecta a todos los campos presentados. Para mostrar los ttulos y editoriales de los libros sin repetir ttulos ni editoriales, usamos: select distinct titulo,editorial from libros order by titulo; Note que los registros no estn duplicados, aparecen ttulos iguales pero con editorial diferente, cada registro es diferente. Entonces, "distinct" elimina registros duplicados. Ejercicio: Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes". 1- Elimine la tabla "clientes" y crela con la siguiente estructura: drop table clientes; create table clientes ( nombre varchar2(30) not null, domicilio varchar2(30), ciudad varchar2(20), provincia varchar2(20) );

2- Ingrese algunos registros: insert into clientes values ('Lopez Marcos','Colon 111','Cordoba','Cordoba'); insert into clientes values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba'); insert into clientes values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba'); insert into clientes values ('Perez Luis','Sarmiento 444','Rosario','Santa Fe'); insert into clientes values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba'); insert into clientes values ('Gomez Ines','San Martin 666','Santa Fe','Santa Fe'); insert into clientes values ('Torres Fabiola','Alem 777','Villa del Rosario','Cordoba'); insert into clientes values ('Lopez Carlos',null,'Cruz del Eje','Cordoba'); insert into clientes values ('Ramos Betina','San Martin 999','Cordoba','Cordoba'); insert into clientes values ('Lopez Lucas','San Martin 1010','Posadas','Misiones'); 3- Obtenga las provincias sin repetir (3 registros) 4- Cuente las distintas provincias (retorna 3) 5- Se necesitan los nombres de las ciudades sin repetir (6 registros) 6- Obtenga la cantidad de ciudades distintas (devuelve 6) 7- Combine con "where" para obtener las distintas ciudades de la provincia de Cordoba (3 registros) 8- Contamos las distintas ciudades de cada provincia empleando "group by" (3 filas) Solucin: drop table clientes; create table clientes ( nombre varchar2(30) not null, domicilio varchar2(30), ciudad varchar2(20), provincia varchar2(20) ); insert into clientes values ('Lopez Marcos','Colon 111','Cordoba','Cordoba'); insert into clientes values ('Perez Ana','San Martin 222','Cruz del Eje','Cordoba'); insert into clientes

values ('Garcia Juan','Rivadavia 333','Villa del Rosario','Cordoba'); insert into clientes values ('Perez Luis','Sarmiento 444','Rosario','Santa Fe'); insert into clientes values ('Pereyra Lucas','San Martin 555','Cruz del Eje','Cordoba'); insert into clientes values ('Gomez Ines','San Martin 666','Santa Fe','Santa Fe'); insert into clientes values ('Torres Fabiola','Alem 777','Villa del Rosario','Cordoba'); insert into clientes values ('Lopez Carlos',null,'Cruz del Eje','Cordoba'); insert into clientes values ('Ramos Betina','San Martin 999','Cordoba','Cordoba'); insert into clientes values ('Lopez Lucas','San Martin 1010','Posadas','Misiones'); select distinct provincia from clientes; select count(distinct provincia) as cantidad from clientes; select distinct ciudad from clientes; select count(distinct ciudad) from clientes; select distinct ciudad from clientes where provincia='Cordoba'; select provincia,count(distinct ciudad) from clientes

group by provincia; Ejercicio 2:


Segundo problema: La provincia almacena en una tabla llamada "inmuebles" los siguientes datos de los inmuebles y sus propietarios para cobrar impuestos: 1- Elimine la tabla: drop table inmuebles; 2- Crela con la siguiente estructura: create table inmuebles ( documento varchar2(8) not null, apellido varchar2(30), nombre varchar2(30), domicilio varchar2(20), barrio varchar2(20),

ciudad varchar2(20), tipo char(1),--b=baldio, e: edificado superficie number(8,2) ); 3- Ingrese algunos registros: insert into inmuebles values ('11000000','Perez','Alberto','San Martin 800','Centro','Cordoba','e',100); insert into inmuebles values ('11000000','Perez','Alberto','Sarmiento 245','Gral. Paz','Cordoba','e',200); insert into inmuebles values ('12222222','Lopez','Maria','San Martin 202','Centro','Cordoba','e',250); insert into inmuebles values ('13333333','Garcia','Carlos','Paso 1234','Alberdi','Cordoba','b',200); insert into inmuebles values ('13333333','Garcia','Carlos','Guemes 876','Alberdi','Cordoba','b',300); insert into inmuebles values ('14444444','Perez','Mariana','Caseros 456','Flores','Cordoba','b',200); insert into inmuebles values ('15555555','Lopez','Luis','San Martin 321','Centro','Carlos Paz','e',500); insert into inmuebles values ('15555555','Lopez','Luis','Lopez y Planes 853','Flores','Carlos Paz','e',350); insert into inmuebles values ('16666666','Perez','Alberto','Sucre 1877','Flores','Cordoba','e',150); 4- Muestre los distintos apellidos de los propietarios, sin repetir (3 registros) 5- Recupere los distintos documentos de los propietarios y luego muestre los distintos documentos de los propietarios, sin repetir y vea la diferencia (9 y 6 registros respectivamente) 6- Cuente, sin repetir, la cantidad de propietarios de inmuebles de la ciudad de Cordoba (5) 7- Cuente la cantidad de inmuebles con domicilio en 'San Martin' (3) 8- Cuente la cantidad de inmuebles con domicilio en 'San Martin', sin repetir la ciudad (2 registros). Compare con la sentencia anterior. 9- Muestre los apellidos y nombres de todos los registros(9 registros) 10- Muestre los apellidos y nombres, sin repetir (5 registros) Note que si hay 2 personas con igual nombre y apellido aparece una sola vez. 11- Muestre la cantidad de inmuebles que tiene cada propietario en barrios conocidos, agrupando por documento (6 registros) 12- Realice la misma consulta anterior pero en esta oportunidad, sin repetir barrio (6 registros) Compare los valores con los obtenidos en el punto 11. Solucin:

drop table inmuebles; create table inmuebles ( documento varchar2(8) not null, apellido varchar2(30), nombre varchar2(30), domicilio varchar2(20), barrio varchar2(20), ciudad varchar2(20), tipo char(1),--b=baldio, e: edificado superficie number(8,2) ); insert into inmuebles values ('11000000','Perez','Alberto','San Martin 800','Centro','Cordoba','e',100); insert into inmuebles values ('11000000','Perez','Alberto','Sarmiento 245','Gral. Paz','Cordoba','e',200); insert into inmuebles values ('12222222','Lopez','Maria','San Martin 202','Centro','Cordoba','e',250); insert into inmuebles values ('13333333','Garcia','Carlos','Paso 1234','Alberdi','Cordoba','b',200); insert into inmuebles values ('13333333','Garcia','Carlos','Guemes 876','Alberdi','Cordoba','b',300); insert into inmuebles values ('14444444','Perez','Mariana','Caseros 456','Flores','Cordoba','b',200); insert into inmuebles values ('15555555','Lopez','Luis','San Martin 321','Centro','Carlos Paz','e',500); insert into inmuebles values ('15555555','Lopez','Luis','Lopez y Planes 853','Flores','Carlos Paz','e',350); insert into inmuebles values ('16666666','Perez','Alberto','Sucre 1877','Flores','Cordoba','e',150); select distinct apellido from inmuebles; select distinct documento from inmuebles; select count(distinct documento) from inmuebles where ciudad='Cordoba'; select count(ciudad) from inmuebles where domicilio like 'San Martin %'; select count(distinct ciudad) from inmuebles where domicilio like 'San Martin %'; select apellido,nombre from inmuebles; select distinct apellido,nombre from inmuebles;

select documento,count(barrio) as cantidad from inmuebles group by documento; select documento,count(distinct barrio) as cantidad from inmuebles

group by documento;

34 - Clave primaria compuesta


Las claves primarias pueden ser simples, formadas por un solo campo o compuestas, ms de un campo. Recordemos que una clave primaria identifica un solo registro en una tabla. Para un valor del campo clave existe solamente un registro. Los valores no se repiten ni pueden ser nulos. Existe una playa de estacionamiento que almacena cada da los datos de los vehculos que ingresan en la tabla llamada "vehiculos" con los siguientes campos: patente char(6) not null, tipo char (1), 'a'= auto, 'm'=moto, horallegada date, horasalida date,

Necesitamos definir una clave primaria para una tabla con los datos descriptos arriba. No podemos usar solamente la patente porque un mismo auto puede ingresar ms de una vez en el da a la playa; tampoco podemos usar la hora de entrada porque varios autos pueden ingresar a una misma hora. Tampoco sirven los otros campos. Como ningn campo, por si slo cumple con la condicin para ser clave, es decir, debe identificar un solo registro, el valor no puede repetirse, debemos usar dos campos. Definimos una clave compuesta cuando ningn campo por si solo cumple con la condicin para ser clave. En este ejemplo, un auto puede ingresar varias veces en un da a la playa, pero siempre ser a distinta hora. Usamos 2 campos como clave, la patente junto con la hora de llegada, as identificamos unvocamente cada registro. Para establecer ms de un campo como clave primaria usamos la siguiente sintaxis: create table vehiculos( patente char(6) not null, tipo char(1),--'a'=auto, 'm'=moto horallegada date, horasalida date, primary key(patente,horallegada)

); Nombramos los campos que formarn parte de la clave separados por comas. Al ingresar los registros, Oracle controla que los valores para los campos establecidos como clave primaria no estn repetidos en la tabla; si estuviesen repetidos, muestra un mensaje y la insercin no se realiza. Lo mismo sucede si realizamos una actualizacin. Para ver la clave primaria de una tabla podemos realizar la siguiente consulta: select uc.table_name, column_name, position from user_cons_columns ucc join user_constraints uc on ucc.constraint_name=uc.constraint_name where uc.constraint_type='P' and uc.table_name='VEHICULOS'; Entonces, si un solo campo no identifica unvocamente un registro podemos definir una clave primaria compuesta, es decir formada por ms de un campo.

Ejercicio: Primer problema: Un consultorio mdico en el cual trabajan 3 mdicos registra las consultas de los pacientes en una tabla llamada "consultas". 1- Elimine la tabla: drop table consultas; 2- La tabla contiene los siguientes datos: fechayhora: date not null, fecha y hora de la consulta, medico: varchar2(30), not null, nombre del mdico (Perez,Lopez,Duarte), documento: char(8) not null, documento del paciente, paciente: varchar2(30), nombre del paciente, obrasocial: varchar2(30), nombre de la obra social (IPAM,PAMI, etc.).

3- Setee el formato de "date" para que nos muestre da, mes, ao, hora y minutos: ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI';

4- Un mdico slo puede atender a un paciente en una fecha y hora determinada. En una fecha y hora determinada, varios mdicos atienden a distintos pacientes. Cree la tabla definiendo una clave primaria compuesta: create table consultas( fechayhora date not null, medico varchar2(30) not null, documento char(8) not null, paciente varchar2(30), obrasocial varchar2(30), primary key(fechayhora,medico) ); 4- Ingrese varias consultas para un mismo mdico en distintas horas el mismo da: insert into consultas values ('05/11/2006 8:00','Lopez','12222222','Acosta Betina','PAMI'); insert into consultas values ('05/11/2006 8:30','Lopez','23333333','Fuentes Carlos','PAMI'); 5- Ingrese varias consultas para diferentes mdicos en la misma fecha y hora: insert into consultas values ('05/11/2006 8:00','Perez','34444444','Garcia Marisa','IPAM'); insert into consultas values ('05/11/2006 8:00','Duarte','45555555','Pereyra Luis','PAMI'); 6- Intente ingresar una consulta para un mismo mdico en la misma hora el mismo da (mensaje de error) 7- Intente cambiar la hora de la consulta de "Acosta Betina" por una no disponible ("8:30") (error) 8- Cambie la hora de la consulta de "Acosta Betina" por una disponible ("9:30") 9- Ingrese una consulta para el da "06/11/2006" a las 10 hs. para el doctor "Perez" 10- Recupere todos los datos de las consultas de "Lopez" (3 registros) 11- Recupere todos los datos de las consultas programadas para el "05/11/2006 8:00" (2 registros) 12- Muestre da y mes de todas las consultas de "Lopez" Solucin: drop table consultas; ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI'; create table consultas( fechayhora date not null, medico varchar2(30) not null,

documento char(8) not null, paciente varchar2(30), obrasocial varchar2(30), primary key(fechayhora,medico) ); insert into consultas values ('05/11/2006 8:00','Lopez','12222222','Acosta Betina','PAMI'); insert into consultas values ('05/11/2006 8:30','Lopez','23333333','Fuentes Carlos','PAMI'); insert into consultas values ('05/11/2006 8:00','Perez','34444444','Garcia Marisa','IPAM'); insert into consultas values ('05/11/2006 8:00','Duarte','45555555','Pereyra Luis','PAMI'); insert into consultas values ('05/11/2006 8:00','Perez','25555555','Mercado Marcos','PAMI'); update consultas set fechayhora='05/11/2006 8:30' where paciente='Acosta Betina'; update consultas set fechayhora='05/11/2006 9:30' where paciente='Acosta Betina'; insert into consultas values ('06/11/2006 10:00','Lopez','25555555','Mercado Marcos','PAMI'); select *from consultas where medico='Lopez'; select *from consultas where fechayhora='05/11/2006 8:00'; select extract(day from fechayhora) as dia, extract(month from fechayhora) as mes from consultas

where medico='Lopez'; Ejercicio 2:


Segundo problema: Un club dicta clases de distintos deportes. En una tabla llamada "inscriptos" almacena la informacin necesaria. 1- Elimine la tabla "inscriptos": drop table inscriptos; 2- La tabla contiene los siguientes campos: - documento del socio alumno: char(8) not null

nombre del socio: varchar2(30), nombre del deporte (tenis, futbol, natacin, basquet): varchar2(15) not null, ao de inscripcion: date, matrcula: si la matrcula ha sido o no pagada ('s' o 'n').

3- Necesitamos una clave primaria que identifique cada registro. Un socio puede inscribirse en varios deportes en distintos aos. Un socio no puede inscribirse en el mismo deporte el mismo ao. Varios socios se inscriben en un mismo deporte en distintos aos. Cree la tabla con una clave compuesta: create table inscriptos( documento char(8) not null, nombre varchar2(30), deporte varchar2(15) not null, ao date, matricula char(1), primary key(documento,deporte,ao) ); 4- Setee el formato de "date" para que nos muestre solamente el ao (no necesitamos las otras partes de la fecha ni la hora) 5- Inscriba a varios alumnos en el mismo deporte en el mismo ao: insert into inscriptos values ('12222222','Juan Perez','tenis','2005','s'); insert into inscriptos values ('23333333','Marta Garcia','tenis','2005','s'); insert into inscriptos values ('34444444','Luis Perez','tenis','2005','n'); 6- Inscriba a un mismo alumno en varios deportes en el mismo ao: insert into inscriptos values ('12222222','Juan Perez','futbol','2005','s'); insert into inscriptos values ('12222222','Juan Perez','natacion','2005','s'); insert into inscriptos values ('12222222','Juan Perez','basquet','2005','n'); 7- Ingrese un registro con el mismo documento de socio en el mismo deporte en distintos aos: insert into inscriptos values ('12222222','Juan Perez','tenis','2006','s'); insert into inscriptos values ('12222222','Juan Perez','tenis','2007','s'); 8- Intente inscribir a un socio alumno en un deporte en el cual ya est inscripto en un ao en el cual ya se haya inscripto (mensaje de error) 9- Intente actualizar un registro para que la clave primaria se repita (error)

10- Muestre los nombres y aos de los inscriptos en "tenis" (5 registros) 11- Muestre los nombres y deportes de los inscriptos en el ao 2005 (6 registros) 12- Muestre el deporte y ao de todas las incripciones del socio documento "12222222" (6 registros) Solucin: drop table inscriptos; create table inscriptos( documento char(8) not null, nombre varchar2(30), deporte varchar2(15) not null, ao date, matricula char(1), primary key(documento,deporte,ao) ); ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY'; insert into inscriptos values ('12222222','Juan Perez','tenis','2005','s'); insert into inscriptos values ('23333333','Marta Garcia','tenis','2005','s'); insert into inscriptos values ('34444444','Luis Perez','tenis','2005','n'); insert into inscriptos values ('12222222','Juan Perez','futbol','2005','s'); insert into inscriptos values ('12222222','Juan Perez','natacion','2005','s'); insert into inscriptos values ('12222222','Juan Perez','basquet','2005','n'); insert into inscriptos values ('12222222','Juan Perez','tenis','2006','s'); insert into inscriptos values ('12222222','Juan Perez','tenis','2007','s'); insert into inscriptos values ('12222222','Juan Perez','tenis','2005','s'); update inscriptos set deporte='tenis' where documento='12222222' and deporte='futbol' and ao='2005'; select nombre,ao from inscriptos where deporte='tenis';

select nombre,deporte from inscriptos where ao='2005'; select deporte,ao from inscriptos

where documento='12222222';

35 - Secuencias (create sequence - currval - nextval - drop sequence)


Hemos aprendido que existen varios objetos de base de datos, hasta ahora hemos visto TABLAS y algunas FUNCIONES predefinidas. Otro objeto de base de datos es la secuencia. Una secuencia (sequence) se emplea para generar valores enteros secuenciales nicos y asignrselos a campos numricos; se utilizan generalmente para las claves primarias de las tablas garantizando que sus valores no se repitan. Una secuencia es una tabla con un campo numrico en el cual se almacena un valor y cada vez que se consulta, se incrementa tal valor para la prxima consulta. Sintaxis general: create sequence NOMBRESECUENCIA start with VALORENTERO increment by VALORENTERO maxvalue VALORENTERO minvalue VALORENTERO cycle | nocycle; - La clusula "start with" indica el valor desde el cual comenzar la generacin de nmeros secuenciales. Si no se especifica, se inicia con el valor que indique "minvalue". - La clusula "increment by" especifica el incremento, es decir, la diferencia entre los nmeros de la secuencia; debe ser un valor numrico entero positivo o negativo diferente de 0. Si no se indica, por defecto es 1. - "maxvalue" define el valor mximo para la secuencia. Si se omite, por defecto es 99999999999999999999999999. - "minvalue" establece el valor mnimo de la secuencia. Si se omite ser 1. - La clusula "cycle" indica que, cuando la secuencia llegue a mximo valor (valor de "maxvalue") se reinicie, comenzando con el mnimo valor ("minvalue") nuevamente, es decir, la secuencia vuelve a utilizar los nmeros. Si se omite, por defecto la secuencia se crea "nocycle". Si no se especifica ninguna clusula, excepto el nombre de la secuencia, por defecto, comenzar en 1, se incrementar en 1, el mnimo valor ser 1, el mximo ser 999999999999999999999999999 y "nocycle". En el siguiente ejemplo creamos una secuencia llamada "sec_codigolibros", estableciendo que comience en 1, sus valores estn entre 1 y 99999 y se incrementen en 1, por defecto, ser "nocycle":

create sequence sec_codigolibros start with 1 increment by 1 maxvalue 99999 minvalue 1; Si bien, las secuencias son independientes de las tablas, se utilizarn generalmente para una tabla especfica, por lo tanto, es conveniente darle un nombre que referencie a la misma. Otro ejemplo: create sequence sec_numerosocios increment by 5 cycle; La secuencia anterior, "sec_numerosocios", incrementa sus valores en 5 y al llegar al mximo valor recomenzar la secuencia desde el valor mnimo; no se especifican las otras clusulas, por lo tanto, por defecto, el valor mnimo es 1, el mximo 999999999999999999999999999 y el valor inicial es 1. Dijimos que las secuencias son tablas; por lo tanto se accede a ellas mediante consultas, empleando "select". La diferencia es que utilizamos pseudocolumnas para recuperar el valor actual y el siguiente de la secuencia. Estas pseudocolumnas pueden incluirse en el "from" de una consulta a otra tabla o de la tabla "dual". Para recuperar los valores de una secuencia empleamos las pseudocolumnas "currval" y "nextval". Primero debe inicializarse la secuencia con "nextval". La primera vez que se referencia "nextval" retorna el valor de inicio de la secuencia; las siguientes veces, incrementa la secuencia y nos retorna el nuevo valor: NOMBRESECUENCIA.NEXTVAL; se coloca el nombre de la secuencia seguido de un punto y la pseudocolumna "nextval" (que es una forma abreviada de "next value", siguiente valor). Para recuperar el valor actual de una secuencia usamos: NOMBRESECUENCIA.CURRVAL; es decir, el nombre de la secuencia, un punto y la pseudocolumna "currval" (que es una forma abreviada de "current value", valor actual). Los valores retornados por "currval" y "nextval" pueden usarse en sentencias "insert" y "update". Veamos un ejemplo completo: Creamos una secuencia para el cdigo de la tabla "libros", especificando el valor mximo, el incremento y que no sea circular: create sequence sec_codigolibros maxvalue 999999 increment by 1

nocycle; Luego inicializamos la secuencia select sec_codigolibros.nextval from dual; Recuerde que la primera vez que se referencie la secuencia debe emplearse "nextval" para inicializarla. Ingresamos un registro en "libros", almacenando en el campo "codigo" el valor actual de la secuencia: insert into libros values (sec_codigolibros.currval,'El aleph', 'Borges','Emece'); Ingresamos otro registro en "libros", almacenando en el campo "codigo" el valor siguiente de la secuencia: insert into libros values (sec_codigolibros.nextval,'Matematica estas ahi', 'Paenza','Nuevo siglo'); Para ver todas las secuencias de la base de datos actual realizamos la siguiente consulta: select *from all_sequences; Nos muestra el propietario de la secuencia, el nombre de la misma, los valores mnimo y mximo, el valor de incremento y si es circular o no, entre otros datos que no analizaremos por el momento. Tambin podemos ver todos los objetos de la base de datos actual tipeando; select *from all_objects; En la tabla resultado aparecen todos los objetos de la base de datos, incluidas las secuencias; si es una secuencia en la columna OBJECT_TYPE se muestra "SEQUENCE". Podemos consultar "all_objects" especificando que nos muestre el nombre de todas las secuencias: select object_name from all_objects where object_type='SEQUENCE'; Para eliminar una secuencia empleamos "drop sequence". Sintaxis: drop sequence NOMBRESECUENCIA; Si la secuencia no existe aparecer un mensaje indicando tal situacin. En el siguiente ejemplo se elimina la secuencia "sec_codigolibros": drop sequence sec_codigolibros;

Ejercicio: Primer problema: Una empresa registra los datos de sus empleados en una tabla llamada "empleados". 1- Elimine la tabla "empleados": drop table empleados; 2- Cree la tabla: create table empleados( legajo number(3), documento char(8) not null, nombre varchar2(30) not null, primary key(legajo) ); 3- Elimine la secuencia "sec_legajoempleados" y luego crela estableciendo el valor mnimo (1), mximo (999), valor inicial (100), valor de incremento (2) y no circular. Finalmente inicialice la secuencia. 4- Ingrese algunos registros, empleando la secuencia creada para los valores de la clave primaria: insert into empleados values (sec_legajoempleados.currval,'22333444','Ana Acosta'); insert into empleados values (sec_legajoempleados.nextval,'23444555','Betina Bustamante'); insert into empleados values (sec_legajoempleados.nextval,'24555666','Carlos Caseros'); insert into empleados values (sec_legajoempleados.nextval,'25666777','Diana Dominguez'); insert into empleados values (sec_legajoempleados.nextval,'26777888','Estela Esper'); 5- Recupere los registros de "libros" para ver los valores de clave primaria. Note que los valores se incrementaron en 2, porque as se estableci el valor de incremento al crear la secuencia. 6- Vea el valor actual de la secuencia empleando la tabla "dual". Retorna 108. 7- Recupere el valor siguiente de la secuencia empleando la tabla "dual" Retorna 110. 8- Ingrese un nuevo empleado (recuerde que la secuencia ya tiene el prximo valor, emplee "currval" para almacenar el valor de legajo) 9- Recupere los registros de "libros" para ver el valor de clave primaria ingresado anteriormente.

10- Incremente el valor de la secuencia empleando la tabla "dual" (retorna 112) 11- Ingrese un empleado con valor de legajo "112". 12- Intente ingresar un registro empleando "currval": insert into empleados values (sec_legajoempleados.currval,'29000111','Hector Huerta'); Mensaje de error porque el legajo est repetido y la clave primaria no puede repetirse. 13- Incremente el valor de la secuencia. Retorna 114. 14- Ingrese el registro del punto 11. Ahora si lo permite, pues el valor retornado por "currval" no est repetido en la tabla "empleados". 15- Recupere los registros. 16- Vea las secuencias existentes y analice la informacin retornada. Debe aparecer "sec_legajoempleados". 17- Vea todos los objetos de la base de datos actual que contengan en su nombre la cadena "EMPLEADOS". Debe aparacer la tabla "empleados" y la secuencia "sec_legajoempleados". 18- Elimine la secuencia creada. 19- Consulte todos los objetos de la base de datos que sean secuencias y verifique que "sec_legajoempleados" ya no existe. Solucin: drop table empleados; create table empleados( legajo number(3), documento char(8) not null, nombre varchar2(30) not null, primary key(legajo) ); drop sequence sec_legajoempleados; create sequence sec_legajoempleados start with 100 increment by 2 maxvalue 999

minvalue 1; select sec_legajoempleados.nextval from dual; insert into empleados values (sec_legajoempleados.currval,'22333444','Ana Acosta'); insert into empleados values (sec_legajoempleados.nextval,'23444555','Betina Bustamante'); insert into empleados values (sec_legajoempleados.nextval,'24555666','Carlos Caseros'); insert into empleados values (sec_legajoempleados.nextval,'25666777','Diana Dominguez'); insert into empleados values (sec_legajoempleados.nextval,'26777888','Estela Esper'); select *from empleados; select sec_legajoempleados.currval from dual; select sec_legajoempleados.nextval from dual; insert into empleados values (sec_legajoempleados.currval,'27888999','Federico Fuentes'); select *from empleados; select sec_legajoempleados.nextval from dual; insert into empleados values (112,'28999000','Gaston Gonzalez'); insert into empleados values (sec_legajoempleados.currval,'29000111','Hector Huerta'); select sec_legajoempleados.nextval from dual; insert into empleados values (sec_legajoempleados.currval,'29000111','Hector Huerta'); select *from empleados; select *from all_sequences; select object_name,object_type from all_objects where object_name like '%EMPLEADOS%'; drop sequence sec_legajoempleados; select object_name,object_type from all_objects where object_type='SEQUENCE';

Interpretacion: Problema: Veamos las secuencias existentes: select *from all_sequences; Aparece una tabla que nos muestra todas las secuencias; la columna "SEQUENCE_NAME" contiene el nombre de cada secuencia; las dems columnas nos informan sobre cada una de las secuencias de la base de datos actual (propietario, valores mnimo y mximo, valor de incremento, si es circular o no, etc.). Vamos a crear una secuencia denominada "sec_codigolibros" para utilizarla en la clave primaria de la tabla "libros". En primer lugar vamos a eliminar la secuencia "sec_codigolibros" porque si ya existe no podremos crear otra con el mismo nombre: drop sequence sec_codigolibros; Si la secuencia no existe aparecer un mensaje indicando tal situacin. Creamos la secuencia llamada "sec_codigolibros", estableciendo que comience en 1, sus valores estn entre 1 y 99999 y se incrementen en 1, por defecto, ser "nocycle": create sequence sec_codigolibros start with 1 increment by 1 maxvalue 99999 minvalue 1; Para acceder a las secuencias (que son tablas) empleamos "select" y la tabla "dual". En primer lugar, debemos inicializar la secuencia: select sec_codigolibros.nextval from dual; Nos retorna el valor 1. Recuperamos el valor actual de nuestra secuencia: select sec_codigolibros.currval from dual; Retorna 1. Eliminamos la tabla "libros" y la creamos con la siguiente estructura: drop table libros; create table libros(

codigo number(5) not null, titulo varchar2(40) not null, autor varchar2(30), editorial varchar2(20), primary key(codigo) ); Note que al crear la tabla no se hace referencia en ningn momento a la secuencia que luego servir para dar valores secuenciales a su clave primaria. Ingresamos un registro en "libros", almacenando en el campo "codigo" el valor actual de la secuencia: insert into libros values (sec_codigolibros.currval,'El aleph', 'Borges','Emece'); Ingresamos otro registro en "libros", almacenando en el campo "codigo" el valor siguiente de la secuencia: insert into libros values (sec_codigolibros.nextval,'Matematica estas ahi', 'Paenza','Nuevo siglo'); Recuerde que "nextval" incrementa la secuencia y retorna el nuevo valor. Recuperamos todos los registros para ver qu se ha almacenado en "codigo": select *from libros; Veamos todos los objetos de la base de datos actual que contengan en su nombre la cadena "LIBROS": select object_name,object_type from all_objects where object_name like '%LIBROS%'; En la tabla resultado aparecen la tabla "libros" y la secuencia "sec_codigolibros". Eliminamos la secuencia creada: drop sequence sec_codigolibros; Un mensaje indica que la secuencia ha sido eliminada. Si consultamos todos los objetos de la base de datos veremos que tal secuencia ya no existe: select object_name,object_type from all_objects where object_name like '%LIBROS%';

36 - Alterar secuencia (alter sequence)

Es posible modificar una secuencia, su valor de incremento, los valores mnimo y mximo y el atributo "cycle" (el valor de inicio no puede modificarse); para ello empleamos la sentencia "alter sequence". Sintaxis: alter sequence NOMBRESECUENCIA ATRIBUTOSAMODIFICAR; Definimos una secuencia denominada "sec_codigolibros" con los siguientes atributos: create sequence sec_codigolibros start with 1 increment by 1 maxvalue 999 minvalue 1 nocycle; Para modificar el mximo valor a 99999 y el incremento a 2, tipeamos: alter sequence sec_codigolibros increment by 2 maxvalue 99999; Los valores de incremento y mnimo han sido modificados, los dems atributos no especificados en la sentencia "alter sequence" se mantienen.

Ejercicio: Primer problema: Una empresa registra los datos de sus empleados en una tabla llamada "empleados". 1- Elimine la tabla "empleados": drop table empleados; 2- Cree la tabla: create table empleados( legajo number(3), documento char(8) not null, nombre varchar2(30) not null, primary key(legajo) ); 3- Elimine la secuencia "sec_legajoempleados" y luego crela estableciendo el valor mnimo (1), mximo (210), valor inicial (206), valor de incremento (2) y no circular. Finalmente inicialice la secuencia. 4- Ingrese algunos registros, empleando la secuencia creada para los valores de la clave primaria.

insert into empleados values (sec_legajoempleados.currval,'22333444','Ana Acosta'); insert into empleados values (sec_legajoempleados.nextval,'23444555','Betina Bustamante'); insert into empleados values (sec_legajoempleados.nextval,'24555666','Carlos Caseros'); 5- Recupere los registros de "libros" para ver los valores de clave primaria. 6- Vea el valor actual de la secuencia empleando la tabla "dual" 7- Intente ingresar un registro empleando "nextval": insert into empleados values (sec_legajoempleados.nextval,'25666777','Diana Dominguez'); Oracle muestra un mensaje de error indicando que la secuencia ha llegado a su valor mximo. 8- Altere la secuencia modificando el atributo "maxvalue" a 999. 9- Obtenga informacin de la secuencia. 10- Ingrese el registro del punto 7. 11- Recupere los registros. 12- Modifique la secuencia para que sus valores se incrementen en 1. 13- Ingrese un nuevo registro: insert into empleados values (sec_legajoempleados.nextval,'26777888','Federico Fuentes'); 14- Recupere los registros. 15- Elimine la secuencia creada. 16- Consulte todos los objetos de la base de datos que sean secuencias y verifique que "sec_legajoempleados" ya no existe. Solucion: drop table empleados; create table empleados( legajo number(3), documento char(8) not null, nombre varchar2(30) not null, primary key(legajo) );

drop sequence sec_legajoempleados; create sequence sec_legajoempleados start with 206 increment by 2 maxvalue 210 minvalue 1; select sec_legajoempleados.nextval from dual; insert into empleados values (sec_legajoempleados.currval,'22333444','Ana Acosta'); insert into empleados values (sec_legajoempleados.nextval,'23444555','Betina Bustamante'); insert into empleados values (sec_legajoempleados.nextval,'24555666','Carlos Caseros'); select *from empleados; select sec_legajoempleados.currval from dual; insert into empleados values (sec_legajoempleados.nextval,'25666777','Diana Dominguez'); alter sequence sec_legajoempleados maxvalue 999; select *from all_sequences where sequence_name='SEC_LEGAJOEMPLEADOS'; insert into empleados values (sec_legajoempleados.nextval,'25666777','Diana Dominguez'); select *from empleados; alter sequence sec_legajoempleados increment by 1; insert into empleados values (sec_legajoempleados.nextval,'26777888','Federico Fuentes'); select *from empleados; drop sequence sec_legajoempleados; select object_name,object_type from all_objects where object_type='SEQUENCE';

37 - Integridad de datos

Es importante, al disear una base de datos y las tablas que contiene, tener en cuenta la integridad de los datos, esto significa que la informacin almacenada en las tablas debe ser vlida, coherente y exacta. Hasta el momento, hemos controlado y restringido la entrada de valores a un campo mediante el tipo de dato que le definimos (cadena, numricos, etc.), la aceptacin o no de valores nulos, el valor por defecto. Tambin hemos asegurado que cada registro de una tabla sea nico definiendo una clave primaria y empleando secuencias. Oracle ofrece ms alternativas, adems de las aprendidas, para restringir y validar los datos, las veremos ordenadamente y al finalizar haremos un resumen de las mismas. Comenzamos por las restricciones. Las restricciones (constraints) son un mtodo para mantener la integridad de los datos, asegurando que los valores ingresados sean vlidos y que las relaciones entre las tablas se mantenga. Las restricciones pueden establecerse a nivel de campo o de tabla. Pueden definirse al crear la tabla ("create table") o agregarse a una tabla existente (empleando "alter table") y se pueden aplicar a un campo o a varios. Tambin es posible habilitarlas y deshabilitarlas. Oracle ofrece varios tipos de restricciones: - not null: a nivel de campo. - primary key: a nivel de tabla. Es un campo o varios que identifican cada registro de una tabla. - foreign key: a nivel de tabla. Establece que un campo (o varios) relacione una clave primaria de una tabla con otra. - check: a nivel de tabla. Restringe los valores que pueden ingresarse en un campo especifico. - unique: a nivel de tabla. Se pueden crear, modificar y eliminar las restricciones sin eliminar la tabla y volver a crearla. Para obtener informacin de las restricciones podemos consultar los catlogos "all_objects", "all_constraints" y "all_cons_columns". El catlogo "all_constraints" retorna varias columnas, entre ellas: OWNER (propietario), CONSTRAINT_NAME (nombre de la restriccin), CONSTRAINT_TYPE (tipo de restriccin, si es primary key (P), foreign key (), unique (U), etc.), TABLE_NAME (nombre de la tabla), SEARCH_CONDITION (en caso de ser Check u otra), DELETE_RULE (), STATUS (estado), DEFERRABLE (), DEFERRED (), VALIDATED (), GENERATED (), INDEX_OWNER (), INDEX_NAME (). El catlogo "all_cons_columnas" retorna las siguientes columnas: OWNER (propietario), CONSTRAINT_NAME (nombre), TABLE_NAME (nombre de la tabla), COLUMN_NAME (campo), POSITION (posicin).

38 - Restriccin primary key


La restriccin "primary key" asegura que los valores sean nicos para cada registro. Anteriormente, para establecer una clave primaria para una tabla emplebamos la siguiente sintaxis al crear la tabla, por ejemplo: create table libros( codigo int not null, titulo varchar(30), autor varchar(30), editorial varchar(20), primary key(codigo) ); Cada vez que establecamos la clave primaria para la tabla, Oracle creaba automticamente una restriccin "primary key" para dicha tabla. Dicha restriccin, a la cual no le dbamos un nombre, reciba un nombre dado por Oracle que consta de una serie de letras y nmeros aleatorios. Podemos agregar una restriccin "primary key" a una tabla existente con la sintaxis bsica siguiente: alter table NOMBRETABLA add constraint NOMBRECONSTRAINT primary key (CAMPO,...); En el siguiente ejemplo definimos una restriccin "primary key" para nuestra tabla "libros" para asegurarnos que cada libro tendr un cdigo diferente y nico: alter table libros add constraint PK_libros_codigo primary key(codigo); Con esta restriccin, si intentamos ingresar un registro con un valor para el campo "codigo" que ya existe o el valor "null", aparece un mensaje de error, porque no se permiten valores duplicados ni nulos. Igualmente, si actualizamos. Por convencin, cuando demos el nombre a las restricciones "primary key" seguiremos el formato "PK_NOMBRETABLA_NOMBRECAMPO". Cuando agregamos una restriccin a una tabla que contiene informacin, Oracle controla los datos existentes para confirmar que cumplen las exigencias de la restriccin, si no los cumple, la restriccin no se aplica y aparece un mensaje de error. Por ejemplo, si intentamos definir la restriccin "primary key" para "libros" y hay registros con cdigos repetidos o con un valor "null", la restriccin no se establece. Cuando establecamos una clave primaria al definir la tabla, automticamente Oracle redefina el campo como "not null"; lo mismo sucede al agregar una restriccin "primary key", los campos que se establecen como clave primaria se redefinen automticamente "not null". Se permite definir solamente una restriccin "primary key" por tabla, que asegura la unicidad de cada registro de una tabla.

Si consultamos el catlogo "user_constraints", podemos ver las restricciones "primary key" (y todos los tipos de restricciones) de todas las tablas del usuario actual. El resultado es una tabla que nos informa el propietario de la restriccin (OWNER), el nombre de la restriccin (CONSTRAINT_NAME), el tipo (CONSTRAINT_TYPE, si es "primary key" muestra una "P"), el nombre de la tabla en la cual se aplica (TABLE_NAME), y otra informacin que no analizaremos por el momento. Tambin podemos consultar el catlogo "user_cons_columns"; nos mostrar el propietario de la restriccin (OWNER), el nombre de la restriccin (CONSTRAINT_NAME), la tabla a la cual se aplica (TABLE_NAME), el campo (COLUMN_NAME) y la posicin (POSITION). Ejercicio: Primer problema: Una empresa tiene registrados datos de sus empleados en una tabla llamada "empleados". 1- Elimine la tabla: drop table empleados; 2- Crela con la siguiente estructura: create table empleados ( documento char(8), nombre varchar2(30), seccion varchar2(20) ); 3- Ingrese algunos registros, dos de ellos con el mismo nmero de documento: 4- Intente establecer una restriccin "primary key" para la tabla para que el documento no se repita ni admita valores nulos. No lo permite porque la tabla contiene datos que no cumplen con la restriccin, debemos eliminar (o modificar) el registro que tiene documento duplicado. 5- Establecezca la restriccin "primary key" del punto 4 6- Intente actualizar un documento para que se repita. No lo permite porque va contra la restriccin. 7-Intente establecer otra restriccin "primary key" con el campo "nombre". 8- Vea las restricciones de la tabla "empleados" consultando el catlogo "user_constraints" (1 restriccin "P") 9- Consulte el catlogo "user_cons_columns" Solucin: drop table empleados;

create table empleados ( documento char(8), nombre varchar2(30), seccion varchar2(20) ); insert into empleados values ('22222222','Alberto Lopez','Sistemas'); insert into empleados values ('23333333','Beatriz Garcia','Administracion'); insert into empleados values ('23333333','Carlos Fuentes','Administracion'); alter table empleados add constraint PK_empleados_documento primary key(documento); delete from empleados where nombre='Carlos Fuentes'; alter table empleados add constraint PK_empleados_documento primary key(documento); update empleados set documento='22222222' where documento='23333333'; alter table empleados add constraint PK_empleados_nombre primary key(nombre); select *from user_constraints where table_name='EMPLEADOS'; select *from user_cons_columns where table_name='EMPLEADOS'; Ejercicio 2: Segundo problema: Una empresa de remises tiene registrada la informacin de sus vehculos en una tabla llamada "remis". 1- Elimine la tabla: drop table remis; 2- Cree la tabla con la siguiente estructura: create table remis( numero number(5), patente char(6), marca varchar2(15), modelo char(4)

); 3- Ingrese algunos registros sin repetir patente y repitiendo nmero. 4- Ingrese un registro con patente nula. 5- Intente definir una restriccin "primary key" para el campo "numero". 6- Intente establecer una restriccin "primary key" para el campo "patente". 7- Modifique el valor "null" de la patente. 8- Establezca una restriccin "primary key" del punto 6. 9- Vea la informacin de las restricciones consultando "user_constraints" (1 restriccin "P") 10- Consulte el catlogo "user_cons_columns" y analice la informacin retornada (1 restriccin) Solucion: drop table remis; create table remis( numero number(5), patente char(6), marca varchar2(15), modelo char(4) ); insert into remis values(1,'ABC123','Renault 12','1990'); insert into remis values(1,'DEF456','Fiat Duna','1995'); insert into remis values(2,null,'Renault Clio','1990'); alter table remis add constraint PK_remis_numero primary key(numero); alter table remis add constraint PK_remis_patente primary key(patente); update remis set patente='AIC222' where patente is null; alter table remis add constraint PK_remis_patente primary key(patente); select *from user_constraints where table_name='REMIS';

select *from user_cons_columns where table_name='REMIS';

39 - Restriccin unique
Anteriormente aprendimos la restriccin "primary key", otra restriccin que asegura valores nicos para cada registro es "unique". La restriccin "unique" impide la duplicacin de claves alternas (no primarias), es decir, especifica que dos registros no puedan tener el mismo valor en un campo. Se permiten valores nulos. Se pueden aplicar varias restricciones de este tipo a una misma tabla, y pueden aplicarse a uno o varios campos que no sean clave primaria. Se emplea cuando ya se estableci una clave primaria (como un nmero de legajo) pero se necesita asegurar que otros datos tambin sean nicos y no se repitan (como nmero de documento). La sintaxis general es la siguiente: alter table NOMBRETABLA add constraint NOMBRERESTRICCION unique (CAMPO); Ejemplo: alter table alumnos add constraint UQ_alumnos_documento unique (documento); En el ejemplo anterior se agrega una restriccin "unique" sobre el campo "documento" de la tabla "alumnos", esto asegura que no se pueda ingresar un documento si ya existe. Esta restriccin permite valores nulos, asi que si se ingresa el valor "null" para el campo "documento", se acepta. Por convencin, cuando demos el nombre a las restricciones "unique" seguiremos la misma estructura: "UQ_NOMBRETABLA_NOMBRECAMPO". Quiz parezca innecesario colocar el nombre de la tabla, pero cuando empleemos varias tablas ver que es til identificar las restricciones por tipo, tabla y campo. Recuerde que cuando agregamos una restriccin a una tabla que contiene informacin, Oracle controla los datos existentes para confirmar que cumplen la condicin de la restriccin, si no los cumple, la restriccin no se aplica y aparece un mensaje de error. En el caso del ejemplo anterior, si la tabla contiene nmeros de documento duplicados, la restriccin no podr establecerse; si podr establecerse si tiene valores nulos. Oracle controla la entrada de datos en inserciones y actualizaciones evitando que se ingresen valores duplicados. Un campo que se estableci como clave primaria no puede definirse como clave nica; si una tabla tiene una clave primaria, puede tener una o varias claves nicas (aplicadas a otros campos que no sean clave primaria).

Si consultamos el catlogo "user_constraints", podemos ver las restricciones "unique" (y todos los tipos de restricciones) de todas las tablas del usuario actual. El resultado es una tabla que nos informa el propietario de la restriccin (OWNER), el nombre de la restriccin (CONSTRAINT_NAME), el tipo (CONSTRAINT_TYPE, si es "unique" muestra una "U"), el nombre de la tabla en la cual se aplica (TABLE_NAME), y otra informacin que no analizaremos por el momento. Tambin podemos consultar el catlogo "user_cons_columns"; nos mostrar el propietario de la restriccin (OWNER), el nombre de la restriccin (CONSTRAINT_NAME), la tabla a la cual se aplica (TABLE_NAME), el campo (COLUMN_NAME) y la posicin (POSITION). Ejercicio 1: Primer problema: Una empresa de remises tiene registrada la informacin de sus vehculos en una tabla llamada "remis". 1- Elimine la tabla: drop table remis; 2- Cree la tabla con la siguiente estructura: create table remis( numero number(5), patente char(6), marca varchar2(15), modelo char(4) ); 3- Ingrese algunos registros, 2 de ellos con patente repetida y alguno con patente nula. 4- Agregue una restriccin "primary key" para el campo "numero". 5- Intente agregar una restriccin "unique" para asegurarse que la patente del remis no tomar valores repetidos. No se puede porque hay valores duplicados, un mensaje indica que se encontraron claves duplicadas. 6- Elimine el registro con patente duplicada y establezca la restriccin. Note que hay 1 registro con valor nulo en "patente". 7- Intente ingresar un registro con patente repetida (no lo permite) 8- Ingrese un registro con valor nulo para el campo "patente". 9- Muestre la informacin de las restricciones consultando "user_constraints" y "user_cons_columns" y analice la informacin retornada (2 filas en cada consulta)

Solucin: drop table remis; create table remis( numero number(5), patente char(6), marca varchar2(15), modelo char(4) ); insert insert insert insert insert into into into into into remis remis remis remis remis values(1,'ABC123','Renault clio','1990'); values(2,'DEF456','Peugeot 504','1995'); values(3,'DEF456','Fiat Duna','1998'); values(4,'GHI789','Fiat Duna','1995'); values(5,null,'Fiat Duna','1995');

alter table remis add constraint PK_remis_numero primary key(numero); alter table remis add constraint UQ_remis_patente unique(patente); delete from remis where numero=3; alter table remis add constraint UQ_remis_patente unique(patente); insert into remis values(6,'ABC123','Renault 11','1995'); insert into remis values(7,null,'Renault 11','1995'); select *from user_constraints where table_name='REMIS'; select *from user_cons_columns where table_name='REMIS';

40 - Restriccion check
La restriccin "check" especifica los valores que acepta un campo, evitando que se ingresen valores inapropiados. La sintaxis bsica es la siguiente: alter table NOMBRETABLA add constraint NOMBRECONSTRAINT check CONDICION;

Trabajamos con la tabla "libros" de una librera que tiene los siguientes campos: codigo, titulo, autor, editorial, preciomin (que indica el precio para los minoristas) y preciomay (que indica el precio para los mayoristas). Los campos correspondientes a los precios (minorista y mayorista) se definen de tipo number(5,2), es decir, aceptan valores entre -999.99 y 999.99. Podemos controlar que no se ingresen valores negativos para dichos campos agregando una restriccin "check": alter table libros add constraint CK_libros_precio_positivo check (preciomin>=0 and preciomay>=0); Este tipo de restriccin verifica los datos cada vez que se ejecuta una sentencia "insert" o "update", es decir, acta en inserciones y actualizaciones. Si la tabla contiene registros que no cumplen con la restriccin que se va a establecer, la restriccin no se puede establecer, hasta que todos los registros cumplan con dicha restriccin. La condicin puede hacer referencia a otros campos de la misma tabla. Por ejemplo, podemos controlar que el precio mayorista no sea mayor al precio minorista: alter table libros add constraint CK_libros_preciominmay check (preciomay<=preciomin); Por convencin, cuando demos el nombre a las restricciones "check" seguiremos la misma estructura: comenzamos con "CK", seguido del nombre de la tabla, del campo y alguna palabra con la cual podamos identificar fcilmente de qu se trata la restriccin, por si tenemos varias restricciones "check" para el mismo campo. Un campo puede tener varias restricciones "check" y una restriccin "check" puede incluir varios campos. Las condiciones para restricciones "check" tambin pueden incluir una lista de valores. Por ejemplo establecer que cierto campo asuma slo los valores que se listan: ... check (CAMPO in ('lunes','miercoles','viernes')); Si un campo permite valores nulos, "null" es un valor aceptado aunque no est incluido en la condicin de restriccin. Si intentamos establecer una restriccin "check" para un campo que entra en conflicto con otra restriccin "check" establecida al mismo campo, Oracle no lo permite. Pero si establecemos una restriccin "check" para un campo que entra en conflicto con un valor "default" establecido para el mismo campo, Oracle lo permite; pero al intentar ingresar un registro, aparece un mensaje de error. En las condiciones de chequeo no es posible incluir funciones (como "sysdate"). Un campo con una restriccin "primary key" o "unique" puede tener una (o varias) restricciones "check".

En la condicin de una restriccin "check" se puede establecer que un campo no admita valores nulos: alter table libros add constraint CK_libros_titulo check (titulo is not null); Ejercicio: Primer problema: Una empresa tiene registrados datos de sus empleados en una tabla llamada "empleados". 1- Elimine la tabla: drop table empleados; 2- Crela con la siguiente estructura: create table empleados ( documento char(8), nombre varchar2(30), cantidadhijos number(2), seccion varchar2(20), sueldo number(6,2) default -1 ); 3- Agregue una restriccin "check" para asegurarse que no se ingresen valores negativos para el sueldo. Note que el campo "sueldo" tiene establecido un valor por defecto (el valor -1) que va contra la restriccin; Oracle no controla esto, permite establecer la restriccin, pero al intentar ingresar un registro con el valor por defecto en tal campo, muestra un mensaje de error. 4- Intente ingresar un registro con la palabra clave "default" en el campo "sueldo" (mensaje de error) 5- Ingrese algunos registros vlidos: insert into empleados values ('22222222','Alberto Lopez',1,'Sistemas',1000); insert into empleados values ('33333333','Beatriz Garcia',2,'Administracion',3000); insert into empleados values ('34444444','Carlos Caseres',0,'Contadura',6000); 6- Intente agregar otra restriccin "check" al campo sueldo para asegurar que ninguno supere el valor 5000. La sentencia no se ejecuta porque hay un sueldo que no cumple la restriccin. 7- Elimine el registro infractor y vuelva a crear la restriccin 8- Establezca una restriccin "check" para "seccion" que permita solamente los valores "Sistemas", "Administracion" y "Contadura".

9- Ingrese un registro con valor "null" en el campo "seccion". 10- Establezca una restriccin "check" para "cantidadhijos" que permita solamente valores entre 0 y 15. 11- Vea todas las restricciones de la tabla (4 filas) 12- Intente agregar un registro que vaya contra alguna de las restricciones al campo "sueldo". Mensaje de error porque se infringe la restriccin "CK_empleados_sueldo_positivo". 13- Intente modificar un registro colocando en "cantidadhijos" el valor "21". 14- Intente modificar el valor de algn registro en el campo "seccion" cambindolo por uno que no est incluido en la lista de permitidos. 15- Intente agregar una restriccin al campo seccin para aceptar solamente valores que comiencen con la letra "B". Note que NO se puede establecer esta restriccin porque va en contra de la establecida anteriormente para el mismo campo, si lo permitiera, no podramos ingresar ningn valor para "seccion". 16- Agregue un registro con documento nulo. 17- Intente agregar una restriccin "primary key" para el campo "documento". No lo permite porque existe un registro con valor nulo en tal campo. 18- Elimine el registro que infringe la restriccin y establezca la restriccin del punto 17. 19- Consulte "user_constraints", mostrando los campos "constraint_name", "constraint_type" y "search_condition" de la tabla "empleados" (5 filas) 20- Consulte el catlogo "user_cons_colums" recuperando el nombre de las restricciones establecidas en el campo sueldo de la tabla "empleados" (2 filas) Solucion: drop table empleados; create table empleados ( documento char(8), nombre varchar2(30), cantidadhijos number(2), seccion varchar2(20), sueldo number(6,2) default -1 ); alter table empleados add constraint CK_empleados_sueldo_positivo check (sueldo>0); insert into empleados values ('33555888','Juan Pereyra',1,'Sistemas',default);

insert into empleados values ('22222222','Alberto Lopez',1,'Sistemas',1000); insert into empleados values ('33333333','Beatriz Garcia',2,'Administracion',3000); insert into empleados values ('34444444','Carlos Caseres',0,'Contadura',6000); alter table empleados add constraint CK_empleados_sueldo_maximo check (sueldo<=5000); delete from empleados where sueldo=6000; alter table empleados add constraint CK_empleados_sueldo_maximo check (sueldo<=5000); alter table empleados add constraint CK_empleados_seccion_lista check (seccion in ('Sistemas','Administracion','Contaduria')); insert into empleados values ('31111222','Roberto Sanchez',1,null,1500); alter table empleados add constraint CK_cantidadhijos check (cantidadhijos between 0 and 15); select *from user_constraints where table_name='EMPLEADOS'; insert into empleados values ('24444444','Carlos Fuentes',2,'Administracion',-1500); update empleados set cantidadhijos=21 where documento='22222222'; update empleados set seccion='Recursos' where documento='22222222'; alter table empleados add constraint CK_seccion_letrainicial check (seccion like '%B'); insert into empleados values(null,'Federico Torres',1,'Sistemas',1800); alter table empleados add constraint PK_empleados_documento primary key (documento); delete from empleados where nombre='Federico Torres'; alter table empleados add constraint PK_empleados_documento primary key (documento); select constraint_name, constraint_type, search_condition from user_constraints where table_name='EMPLEADOS';

select constraint_name from user_cons_columns where table_name='EMPLEADOS' and column_name='SUELDO';

Ejercicio 2: Segundo problema: Una playa de estacionamiento almacena los datos de los vehculos que ingresan en la tabla llamada "vehiculos". 1- Setee el formato de "date" para que nos muestre da, mes, ao, hora y minutos: alter session set NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI'; 2- Elimine la tabla "vehiculos" y crela con la siguiente estructura: drop table vehiculos; create table vehiculos( numero number(5), patente char(6), tipo char(4), fechahoraentrada date, fechahorasalida date ); 3- Ingrese algunos registros: insert into vehiculos values(1,'AIC124','auto','17/01/2007 8:05','17/01/2007 12:30'); insert into vehiculos values(2,'CAA258','auto','17/01/2007 8:10',null); insert into vehiculos values(3,'DSE367','moto','17/01/2007 8:30','17/01/2007 18:00'); 4- Agregue una restriccin de control que especifique que el campo "tipo" acepte solamente los valores "auto" y "moto": alter table vehiculos add constraint CK_vehiculos_tipo_valores check (tipo in ('auto','moto')); 5- Intente modificar el valor del campo "tipo" ingresando un valor inexistente en la lista de valores permitidos por la restriccin establecida a dicho campo. 6- Ingrese un registro con valor nulo para "tipo". 7- Agregue una restriccin de control al campo "fechahoraentrada" que establezca que sus valores no sean posteriores a "fechahorasalida".

8- Intente modificar un registro para que la salida sea anterior a la entrada. 9- Vea todas las restricciones para la tabla "vehiculos". 10- Ingrese un registro con valor nulo para "fechahoraentrada". 11- Vea todos los registros. 12- Consulte "user_cons_columns" y analice la informacin retornada. Solucin: alter session set NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI'; drop table vehiculos; create table vehiculos( numero number(5), patente char(6), tipo char(4), fechahoraentrada date, fechahorasalida date ); insert into vehiculos values(1,'AIC124','auto','17/01/2007 8:05','17/01/2007 12:30'); insert into vehiculos values(2,'CAA258','auto','17/01/2007 8:10',null); insert into vehiculos values(3,'DSE367','moto','17/01/2007 8:30','17/01/2007 18:00'); alter table vehiculos add constraint CK_vehiculos_tipo_valores check (tipo in ('auto','moto')); update vehiculos set tipo='bici' where patente='AIC124'; insert into vehiculos values(4,'SDF134',null,null,null); alter table vehiculos add constraint CK_vehiculos_entradasalida check (fechahoraentrada<=fechahorasalida); update vehiculos set fechahorasalida='17/01/2007 7:30' where patente='CAA258'; select *from user_constraints where table_name='VEHICULOS'; insert into vehiculos values(8,'DFR156','moto',null,default); select *from vehiculos; select *from user_cons_columns where table_name='VEHICULOS';

41 - Restricciones: validacin y estados (validate - novalidate enable - disable)


Sabemos que si agregamos una restriccin a una tabla que contiene datos, Oracle los controla para asegurarse que cumplen con la condicin de la restriccin, si algn registro no la cumple, la restriccin no se establecece. Es posible deshabilitar esta comprobacin estableciendo una restriccin sin comprobar los datos existentes en la tabla. Podemos hacerlo cuando agregamos la restriccin (de cualquier tipo) a una tabla para que Oracle acepte los valores ya almacenados que infringen la restriccin. Para ello debemos incluir la opcin "novalidate" en la instruccin "alter table": alter table libros add constraint PK_libros_codigo primary key (codigo) novalidate; La restriccin no se aplica en los datos existentes, pero si intentamos ingresar un nuevo valor que no cumpla la restriccin (o actualizarlo), Oracle no lo permite. Para saber si una restriccin est validada o no, podemos consultar el catlogo "user_constraints" y fijarnos lo que informa la columna "validated". Tambin podemos deshabilitar las restricciones para agregar o actualizar datos sin comprobarla: alter table libros add constraint PK_libros_codigo primary key (codigo) disable; Entonces, para evitar la comprobacin de datos existentes y futuros al crear la restriccin, la sintaxis bsica es la siguiente: alter table TABLA add constraint NOMBRERESTRICCION TIPOdeRESTRICCION (CAMPO o CONDICION)--campo si es primary key o unique; condicin si es check disable novalidate; Por defecto (si no especificamos) la opcin es "validate", es decir, controla los datos existentes y "enable", es decir, controla futuros ingresos y actualizaciones. Tambin es posible alterar la restriccin luego de haberla creado. Sintaxis: alter table NOMBRETABLA ESTADO VALIDACION constraint NOMBRERESTRICCION; En el ejemplo siguiente deshabilitamos la restriccin "PK_libros_codigo" para poder ingresar un valor que infrija la restriccin: alter table libros

disable validate constraint PK_libros_codigo; Para habilitar una restriccin deshabilitada se ejecuta la misma instruccin pero con la clusula "enable": alter table libros enable validate constraint PK_libros_codigo; Para saber si una restriccin est habilitada o no, podemos consultar el catlogo "user_constraints" y fijarnos lo que informa la columna "status". Los estados "validate" y "novalidate" son relativamente independientes de los estados "enabled" y "disabled". Cuando habilitamos una restriccin "primary key" o "unique" con "enable", los datos existentes DEBEN cumplir con la restriccin; aunque coloquemos "novalidate" junto a "enable", Oracle no permite que se habilite la restricin y valida los datos existentes de todas maneras. No sucede lo mismo con una restriccin "check"; podemos habilitar una restriccin de control con "enable" y "novalidate", Oracle habilita la restriccin para futuros ingresos y actualizaciones y NO valida los datos existentes. Entonces, "enable" o "disable" activa o desactiva la restriccin para los nuevos datos ("enable" es la opcin predeterminada si no se especifica); "validate" o "novalidate" es la opcin para validar la restriccin en los datos existentes ("validate" es la predetermidada si se omite). Una restriccin puede estar en los siguientes estados: - validate y enabled: comprueba los valores existentes y los posteriores ingresos y actualizaciones; - validate y disable: comprueba los valores existentes pero no las posteriores inserciones y actualizaciones; - novalidate y enabled: no comprueba los datos existentes, pero si los posteriores ingresos y actualizaciones; - novalidate y disabled: no comprueba los valores existentes ni los posteriores ingresos y actualizaciones. Ejercicio: Primer problema: Una empresa tiene registrados datos de sus empleados en una tabla llamada "empleados". 1- Elimine la tabla: drop table empleados; 2- Crela con la siguiente estructura e ingrese los registros siguientes:

create table empleados ( codigo number(6), documento char(8), nombre varchar2(30), seccion varchar2(20), sueldo number(6,2) ); insert into empleados values (1,'22222222','Alberto Acosta','Sistemas',-10); insert into empleados values (2,'33333333','Beatriz Benitez','Recursos',3000); insert into empleados values (3,'34444444','Carlos Caseres','Contaduria',4000); 3- Intente agregar una restriccin "check" para asegurarse que no se ingresen valores negativos para el sueldo sin especificar validacin ni estado: alter table empleados add constraint CK_empleados_sueldo_positivo check (sueldo>=0); No se permite porque hay un valor negativo almacenado y por defecto la opcin es "validate". 5- Vuelva a intentarlo agregando la opcin "novalidate". 6- Intente ingresar un valor negativo para sueldo. 7- Deshabilite la restriccin e ingrese el registro anterior. 8- Intente establecer una restriccin "check" para "seccion" que permita solamente los valores "Sistemas", "Administracion" y "Contadura" sin especificar validacin: alter table empleados add constraint CK_empleados_seccion_lista check (seccion in ('Sistemas','Administracion','Contaduria')); No lo permite porque existe un valor fuera de la lista. 9- Establezca la restriccin anterior evitando que se controlen los datos existentes. 10- Vea si las restricciones de la tabla estn o no habilitadas y validadas. Muestra 2 filas, una por cada restriccin; ambas son de control, ninguna valida los datos existentes, "CK_empleados_sueldo_positivo" est deshabilitada, la otra habilitada. 11- Habilite la restriccin deshabilitada. Note que existe un sueldo que infringe la condicin. 12- Intente modificar la seccin del empleado "Carlos Caseres" a "Recursos" No lo permite. 13- Deshabilite la restriccin para poder realizar la actualizacin del punto precedente.

14- Agregue una restriccin "primary key" para el campo "codigo" deshabilitada. 15- Ingrese un registro con cdigo existente. 16- Intente habilitar la restriccin. No se permite porque aun cuando se especifica que no lo haga, Oracle verifica los datos existentes, y existe un cdigo repetido. 17- Modifique el registro con clave primaria repetida. 18- Habilite la restriccin "primary key" 19- Agregue una restriccin "unique" para el campo "documento" 20- Vea todas las restricciones de la tabla "empleados" Muestra las 4 restricciones: 2 de control (1 habilitada y la otra no, no validan datos existentes), 1 "primary key" (habilitada y no valida datos existentes) y 1 nica (habilitada y valida los datos anteriores). 21- Deshabilite todas las restricciones de "empleados" 22- Ingrese un registro que viole todas las restricciones. 23- Habilite la restriccin "CK_empleados_sueldo_positivo" sin validar los datos existentes. 24- Habilite la restriccin "CK_empleados_seccion_lista" sin validar los datos existentes. 25- Intente habilitar la restriccin "PK_empleados_codigo" sin validar los datos existentes. 26- Intente habilitar la restriccin "UQ_empleados_documento" sin validar los datos existentes. 27- Elimine el registro que infringe con las restricciones "primary key" y "unique". 28- Habilite las restricciones "PK_empleados_codigo" y "UQ_empleados_documento" sin validar los datos existentes. 29- Consulte el catlogo "user_constraints" y analice la informacin. Solucin: drop table empleados; create table empleados ( codigo number(6), documento char(8), nombre varchar2(30), seccion varchar2(20), sueldo number(6,2) ); insert into empleados

values (1,'22222222','Alberto Acosta','Sistemas',-10); insert into empleados values (2,'33333333','Beatriz Benitez','Recursos',3000); insert into empleados values (3,'34444444','Carlos Caseres','Contaduria',4000); alter table empleados add constraint CK_empleados_sueldo_positivo check (sueldo>=0); alter table empleados add constraint CK_empleados_sueldo_positivo check (sueldo>=0) novalidate; insert into empleados values (4,'35555555','Daniel Duarte','Administracion',-2000); alter table empleados disable novalidate constraint CK_empleados_sueldo_positivo; insert into empleados values (4,'35555555','Daniel Duarte','Administracion',-2000); alter table empleados add constraint CK_empleados_seccion_lista check (seccion in ('Sistemas','Administracion','Contaduria')); alter table empleados add constraint CK_empleados_seccion_lista check (seccion in ('Sistemas','Administracion','Contaduria')) novalidate; select constraint_name, constraint_type, status, validated from user_constraints where table_name='EMPLEADOS'; alter table empleados enable novalidate constraint CK_empleados_sueldo_positivo; update empleados set seccion='Recursos' where nombre='Carlos Caseres'; alter table empleados disable novalidate constraint CK_empleados_seccion_lista; update empleados set seccion='Recursos' where nombre='Carlos Caseres'; alter table empleados add constraint PK_empleados_codigo primary key (codigo) disable; insert into empleados values (4,'22333444','Federico Fuentes',null,null);

alter table empleados enable novalidate constraint PK_empleados_codigo; update empleados set codigo=5 where nombre='Federico Fuentes'; alter table empleados enable novalidate constraint PK_empleados_codigo; alter table empleados add constraint UQ_empleados_documento unique(documento); select constraint_name, constraint_type, status, validated from user_constraints where table_name='EMPLEADOS'; alter table empleados disable constraint PK_empleados_codigo; alter table empleados disable constraint UQ_empleados_documento; alter table empleados disable constraint CK_empleados_sueldo_positivo; alter table empleados disable constraint CK_empleados_seccion_lista; insert into empleados values (1,'33333333','Federico Fuentes','Gerencia',-1500); alter table empleados enable novalidate constraint CK_empleados_sueldo_positivo; alter table empleados enable novalidate constraint CK_empleados_seccion_lista; alter table empleados enable novalidate constraint PK_empleados_codigo; alter table empleados enable novalidate constraint UQ_empleados_documento; delete empleados where seccion='Gerencia'; alter table empleados enable novalidate constraint PK_empleados_codigo; alter table empleados enable novalidate constraint UQ_empleados_documento; select constraint_name, constraint_type, status, validated from user_constraints where table_name='EMPLEADOS';

42 - Restricciones: informacin (user_constraints user_cons_columns)


El catlogo "user_constraints" muestra la informacin referente a todas las restricciones establecidas en las tablas del usuario actual, devuelve varias columnas, explicaremos algunas de ellas: - owner: propietario de la restriccin; - constraints_name: el nombre de la restriccin; - constraint_type: tipo de restriccin. Si es una restriccin de control muestra el caracter "C", si es "primary key" muestra "P", si es "unique" el caracter "U". - table_name: nombre de la tabla en la cual se estableci la restriccin; - search_condition: solamente es aplicable a restricciones de control; indica la condicin de chequeo a cumplirse. - status: indica si est habilitada (enabled) para futuras inserciones y actualizaciones o deshabilitada (disabled) - validated: indica si valida los datos existentes en la tabla (validated) o no (no validate) El catlogo "user_cons_columns" muestra la informacin referente a todas las restricciones establecidas en las tablas del usuario actual, devuelve las siguientes columnas: - owner: propietario d la restriccin; - constraints_name: el nombre de la restriccin; - table_name: nombre de la tabla en la cual se estableci; - column_name: muestra cada campo en el cual la restriccin fue aplicada. - position: solamente es aplicable a restricciones "primary key" y "unique"; indica el orden en que fueron definidos los campos que componen la clave (primaria o nica).

43 - Restricciones: eliminacin (alter table - drop constraint)


Para eliminar una restriccin, la sintaxis bsica es la siguiente: alter table NOMBRETABLA drop constraint NOMBRERESTRICCION; Para eliminar la restriccin "PK_libros_codigo" de la tabla libros tipeamos: alter table libros drop constraint PK_LIBROS_CODIGO;

Recuerde colocar el nombre de la restriccin en maysculas, sino Oracle no la reconocer. Cuando eliminamos una tabla, todas las restricciones que fueron establecidas en ella, se eliminan tambin. La condicin de control que debe cumplir una restriccin de control no puede modificarse, hay que eliminar la restriccin y volver a crearla; igualmente con las restricciones "primary key" y "unique", no pueden modificarse los campos. Ejercicio: Primer problema: Una playa de estacionamiento almacena cada da los datos de los vehculos que ingresan en la tabla llamada "vehiculos". 1- Setee el formato de "date" para que nos muestre hora y minutos: ALTER SESSION SET NLS_DATE_FORMAT = 'HH24:MI'; 2- Elimine la tabla y crela con la siguiente estructura: drop table vehiculos; create table vehiculos( patente char(6) not null, tipo char(1),--'a'=auto, 'm'=moto horallegada date not null, horasalida date ); 3- Establezca una restriccin "check" que admita solamente los valores "a" y "m" para el campo "tipo": alter table vehiculos add constraint CK_vehiculos_tipo check (tipo in ('a','m')); 4- Agregue una restriccin "primary key" que incluya los campos "patente" y "horallegada" 5- Ingrese un vehculo. 6- Intente ingresar un registro repitiendo la clave primaria. 7- Ingrese un registro repitiendo la patente pero no la hora de llegada. 8- Ingrese un registro repitiendo la hora de llegada pero no la patente. 9- Vea todas las restricciones para la tabla "vehiculos" aparecen 4 filas, 3 correspondientes a restricciones "check" y 1 a "primary key". Dos de las restricciones de control tienen nombres dados por Oracle. 12- Elimine la restriccin "primary key"

13- Vea si se ha eliminado. Ahora aparecen 3 restricciones. 14- Elimine la restriccin de control que establece que el campo "patente" no sea nulo (busque el nombre consultando "user_constraints"). 15- Vea si se han eliminado. 16- Vuelva a establecer la restriccin "primary key" eliminada. 17- La playa quiere incluir, para el campo "tipo", adems de los valores permitidos "a" (auto) y "m" (moto), el caracter "c" (camin). No puede modificar la restriccin, debe eliminarla y luego redefinirla con los 3 valores. 18- Consulte "user_constraints" para ver si la condicin de chequeo de la restriccin "CK_vehiculos_tipo" se ha modificado.

Solucin: ALTER SESSION SET NLS_DATE_FORMAT = 'HH24:MI'; drop table vehiculos; create table vehiculos( patente char(6) not null, tipo char(1),--'a'=auto, 'm'=moto horallegada date not null, horasalida date ); alter table vehiculos add constraint CK_vehiculos_tipo check (tipo in ('a','m')); alter table vehiculos add constraint PK_vehiculos primary key(patente,horallegada); insert into vehiculos values('SDR456','a','10:10',null); insert into vehiculos values('SDR456','m','10:10',null); insert into vehiculos values('SDR456','m','12:20',null); insert into vehiculos values('SDR111','m','10:10',null); select constraint_name, constraint_type, search_condition from user_constraints where table_name='VEHICULOS';

alter table vehiculos drop constraint PK_vehiculos; select constraint_name, constraint_type, search_condition from user_constraints where table_name='VEHICULOS'; select constraint_name, constraint_type, search_condition from user_constraints where table_name='VEHICULOS'; alter table vehiculos add constraint PK_vehiculos primary key(patente,horallegada); alter table vehiculos drop constraint CK_vehiculos_tipo; alter table vehiculos add constraint CK_vehiculos_tipo check (tipo in ('a','m','c')); select search_condition from user_constraints where table_name='VEHICULOS' and constraint_name='CK_VEHICULOS_TIPO';

45 - Indices (Crear - Informacin)


Dijimos que el objetivo de un indice es acelerar la recuperacin de informacin y que es til cuando la tabla contiene miles de registros, cuando se realizan operaciones de ordenamiento y agrupamiento, etc. Es importante identificar el o los campos por los que sera til crear un ndice, aquellos campos por los cuales se realizan bsquedas con frecuencia: claves primarias, claves externas o campos que combinan tablas. No se recomienda crear ndices sobre campos que no se usan con frecuencia en consultas o en tablas muy pequeas. Para crear ndices empleamos la instruccin "create index". La sintaxis bsica es la siguiente: create TIPOdeINDICE index NOMBREINDICE on NOMBRETABLA(CAMPOS); Los ndices pueden ser: no nicos (los valores pueden estar repetidos) o nicos (los valores no pueden duplicarse). De modo predeterminado, si no se especifica el tipo de ndice, se crea uno no nico.

En el siguiente ejemplo creamos un ndice nico sobre el campo "documento" de la tabla "empleados": create unique index I_empleados_documento on empleados(documento); Para identificar los ndices fcilmente, podemos agregar un prefijo al nombre del ndice, por ejemplo "I" y luego el nombre de la tabla y/o campo. Si se intenta crear un ndice nico para un campo que tiene valores duplicados, Oracle no lo permite. Los campos de tipo "long" y "long raw" no pueden indexarse. Una tabla puede indexarse por un campo (o varios). Creamos un ndice compuesto para los campos "apellido" y "nombre": create index I_empleados_apellidonombre on empleado(apellido,nombre); Cuando creamos una restriccin "primary key" o "unique" sobre una tabla, Oracle automticamente crea un ndice sobre el campo (o los campos) de la restriccin y le da el mismo nombre que la restriccin. En caso que la tabla ya tenga un ndice, Oracle lo usa, no crea otro. Para obtener informacin sobre los ndices podemos consultar varios diccionarios. 1) "user_indexes": nos muestra las siguientes columnas (entre otras que no analizaremos): INDEX_NAME INDEX_TYPE TABLE_NAME UNIQUENESS (nombre del ndice), (tipo de ndice, nosotros crearemos el stardart normal), (nombre de la tabla), (si es nico o no).

2) "user_ind_columns": nos muestra las siguientes columnas (entre otras que no analizaremos): INDEX_NAME (nombre del ndice), TABLE_NAME (nombre de la tabla), COLUMN_NAME (nombre del campo), COLUMN_POSITION (posicin del campo),

3) "user_objects": en la columna "OBJECT_TYPE" muestra "index" si es un ndice. 4) "user_constraints": si la restriccin tiene un ndice asociado, aparece su nombre en la columna "INDEX_NAME". Ejercicio. Primer problema: Un profesor guarda algunos datos de sus alumnos en una tabla llamada "alumnos".

1- Elimine la tabla y crela con la siguiente estructura: drop table alumnos; create table alumnos( legajo char(5) not null, documento char(8) not null, nombre varchar2(30), curso char(1), materia varchar2(30), notafinal number(4,2) ); 2- Ingresamos algunos registros: insert insert insert insert insert into into into into into alumnos alumnos alumnos alumnos alumnos values values values values values ('A123','22222222','Perez Patricia','5','Matematica',9); ('A234','23333333','Lopez Ana','5','Matematica',9); ('A345','24444444','Garcia Carlos','6','Matematica',8.5); ('A348','25555555','Perez Patricia','6','Lengua',7.85); ('A457','26666666','Perez Fabian','6','Lengua',3.2);

3- Intente crear un ndice nico para el campo "nombre". No lo permite porque hay valores duplicados. 4- Cree un ndice no nico, para el campo "nombre". 5- Cree un ndice nico, para el campo "lejago". 6- Establezca una restriccin "primary key" sobre el campo "legajo". 7- Verifique que Oracle no cre un ndice al agregar la restriccin, utiliz el ndice "I_alumnos_legajo" existente. 8- Agregue una restriccin nica sobre el campo "documento". 9- Verifique que Oracle cre un ndice al agregar la restriccin y le dio el nombre de la restriccin. 10- Intente crear un ndice nico para la tabla "alumnos" sobre el campo "notafinal" 11- Indexe la tabla "alumnos" por el campo "notafinal" (ndice no nico) 12- Indexe la tabla "alumnos" por los campos "curso" y "materia" (ndice no nico) 13- Intente crear un ndice nico sobre "materia" (error pues hay datos duplicados) 14- Vea los indices de "alumnos" 15- Consulte el diccionario "user_ind_columns" y analice la informacin retornada. 16- Vea todos los ndices de la base de datos activa que contengan en su nombre el patrn "%EMPLEADOS%" (5 filas retornadas)

Solucion: drop table alumnos; create table alumnos( legajo char(5) not null, documento char(8) not null, nombre varchar(30), curso char(1), materia varchar2(30), notafinal number(4,2) ); insert insert insert insert insert into into into into into alumnos alumnos alumnos alumnos alumnos values values values values values ('A123','22222222','Perez Patricia','5','Matematica',9); ('A234','23333333','Lopez Ana','5','Matematica',9); ('A345','24444444','Garcia Carlos','6','Matematica',8.5); ('A348','25555555','Perez Patricia','6','Lengua',7.85); ('A457','26666666','Perez Fabian','6','Lengua',3.2);

create unique index I_alumnos_nombre on alumnos(nombre); create index I_alumnos_nombre on alumnos(nombre); create index I_alumnos_legajo on alumnos(legajo); alter table alumnos add constraint PK_alumnos_legajo primary key (legajo); select constraint_name, constraint_type, index_name from user_constraints where table_name='ALUMNOS'; alter table alumnos add constraint UQ_alumnos_documento unique (documento); select constraint_name, constraint_type, index_name from user_constraints where table_name='ALUMNOS'; create unique index I_alumnos_notafinal on alumnos(notafinal); create index I_alumnos_notafinal on alumnos(notafinal); create index I_alumnos_cursomateria on alumnos(curso,materia); create unique index I_alumnos_materia

on alumnos(materia); select index_name, index_type, uniqueness from user_indexes where table_name='ALUMNOS'; select index_name,column_name,column_position from user_ind_columns where table_name='ALUMNOS'; select *from user_objects where object_type='INDEX' and object_name like '%ALUMNOS%';

46 - Indices (eliminar)
Los ndices se eliminan con "drop index"; la siguiente es la sintaxis bsica: drop index NOMBREINDICE; Eliminamos el ndice "I_empleados_documento": drop index I_empleados_documento; Los ndices usados por las restricciones "primary key" y "unique" no pueden eliminarse con "drop index", se eliminan automticamente cuando quitamos la restriccin. Si eliminamos una tabla, todos los ndices asociados a ella se eliminan. Ejercicio Primer problema: Un profesor guarda algunos datos de sus alumnos en una tabla llamada "alumnos". 1- Elimine la tabla y crela con la siguiente estructura: drop table alumnos; create table alumnos( legajo char(5) not null, documento char(8) not null, nombre varchar2(30), curso char(1) not null, materia varchar2(20) not null, notafinal number(4,2) );

2- Cree un ndice no nico para el campo "nombre". 3- Establezca una restriccin "primary key" para el campo "legajo" 4- Verifique que se cre un ndice con el nombre de la restriccin. 5- Verifique que se cre un ndice nico con el nombre de la restriccin consultando el diccionario de ndices. 6- Intente eliminar el ndice "PK_alumnos_legajo" con "drop index". 7- Cree un ndice nico para el campo "documento". 8- Agregue a la tabla una restriccin nica sobre el campo "documento" y verifique que no se cre un ndice, Oracle emplea el ndice creado en el punto anterior. 9- Intente eliminar el ndice "I_alumnos_documento" (no se puede porque una restriccin lo est utilizando) 10- Elimine la restriccin nica establecida sobre "documento". 11- Verifique que el ndice "I_alumnos_documento" an existe. 12- Elimine el ndice "I_alumnos_documento", ahora puede hacerlo porque no hay restriccin que lo utilice. 13-Elimine el ndice "I_alumnos_nombre". 14- Elimine la restriccin "primary key"/ 15- Verifique que el ndice "PK_alumnos_legajo" fue eliminado (porque fue creado por Oracle al establecerse la restriccin) 16- Cree un ndice compuesto por los campos "curso" y "materia", no nico. 17- Verifique su existencia. 18- Elimine la tabla "alumnos" y verifique que todos los ndices han sido eliminados junto con ella. Solucin: drop table alumnos; create table alumnos( legajo char(5) not null, documento char(8) not null, nombre varchar(30), curso char(1) not null, materia varchar2(20) not null, notafinal number(4,2) );

create index I_alumnos_nombre on alumnos(nombre); alter table alumnos add constraint PK_alumnos_legajo primary key (legajo); select constraint_name, constraint_type, index_name from user_constraints where table_name='ALUMNOS'; select index_name,uniqueness from user_indexes where table_name='ALUMNOS'; drop index PK_alumnos_legajo; create unique index I_alumnos_documento on alumnos(documento); alter table alumnos add constraints UQ_alumnos_documento unique (documento); select constraint_name, constraint_type, index_name from user_constraints where table_name='ALUMNOS'; drop index I_alumnos_documento; alter table alumnos drop constraint UQ_ALUMNOS_DOCUMENTO; select index_name,uniqueness from user_indexes where table_name='ALUMNOS'; drop index I_alumnos_documento; drop index I_alumnos_nombre; alter table alumnos drop constraint PK_ALUMNOS_LEGAJO; select index_name,uniqueness from user_indexes where table_name='ALUMNOS'; create index I_alumnos_cursomateria on alumnos(curso,materia); select index_name,uniqueness from user_indexes

where table_name='ALUMNOS'; drop table alumnos; select index_name,uniqueness from user_indexes where table_name='ALUMNOS';

47 - Varias tablas (join)


Hasta el momento hemos trabajado con una sola tabla, pero generalmente, se trabaja con ms de una. Para evitar la repeticin de datos y ocupar menos espacio, se separa la informacin en varias tablas. Cada tabla almacena parte de la informacin que necesitamos registrar. Por ejemplo, los datos de nuestra tabla "libros" podran separarse en 2 tablas, una llamada "libros" y otra "editoriales" que guardar la informacin de las editoriales. En nuestra tabla "libros" haremos referencia a la editorial colocando un cdigo que la identifique. Veamos: create table libros( codigo number(4), titulo varchar2(40) not null, autor varchar2(30), codigoeditorial number(3) not null, precio number(5,2), primary key (codigo) ); create table editoriales( codigo number(3), nombre varchar2(20) not null, primary key(codigo) ); De esta manera, evitamos almacenar tantas veces los nombres de las editoriales en la tabla "libros" y guardamos el nombre en la tabla "editoriales"; para indicar la editorial de cada libro agregamos un campo que hace referencia al cdigo de la editorial en la tabla "libros" y en "editoriales". Al recuperar los datos de los libros con la siguiente instruccin: select* from libros; vemos que en el campo "editorial" aparece el cdigo, pero no sabemos el nombre de la editorial. Para obtener los datos de cada libro, incluyendo el nombre de la editorial, necesitamos consultar ambas tablas, traer informacin de las dos. Cuando obtenemos informacin de ms de una tabla decimos que hacemos un "join" (combinacin).

Veamos un ejemplo: select *from libros join editoriales on libros.codigoeditorial=editoriales.codigo; Resumiendo: si distribuimos la informacin en varias tablas evitamos la redundancia de datos y ocupamos menos espacio fsico en el disco. Un join es una operacin que relaciona dos o ms tablas para obtener un resultado que incluya datos (campos y registros) de ambas; las tablas participantes se combinan segn los campos comunes a ambas tablas. Hay tres tipos de combinaciones. En los siguientes captulos explicamos cada una de ellas.

48 - Combinacin interna (join)


Un join es una operacin que relaciona dos o ms tablas para obtener un resultado que incluya datos (campos y registros) de ambas; las tablas participantes se combinan segn los campos comunes a ambas tablas. Hay tres tipos de combinaciones: 1) combinaciones internas (inner join o join), 2) combinaciones externas y 3) combinaciones cruzadas. Tambin es posible emplear varias combinaciones en una consulta "select", incluso puede combinarse una tabla consigo misma. La combinacin interna emplea "join", que es la forma abreviada de "inner join". Se emplea para obtener informacin de dos tablas y combinar dicha informacin en una salida. La sintaxis bsica es la siguiente: select CAMPOS from TABLA1 join TABLA2 on CONDICIONdeCOMBINACION; Ejemplo: select *from libros join editoriales on codigoeditorial=editoriales.codigo; Analicemos la consulta anterior.

- especificamos los campos que aparecern en el resultado en la lista de seleccin; - indicamos el nombre de la tabla luego del "from" ("libros"); - combinamos esa tabla con "join" y el nombre de la otra tabla ("editoriales"); se especifica qu tablas se van a combinar y cmo; - cuando se combina informacin de varias tablas, es necesario especificar qu registro de una tabla se combinar con qu registro de la otra tabla, con "on". Se debe especificar la condicin para enlazarlas, es decir, el campo por el cual se combinarn, que tienen en comn. "on" hace coincidir registros de ambas tablas basndose en el valor de tal campo, en el ejemplo, el campo "codigoeditorial" de "libros" y el campo "codigo" de "editoriales" son los que enlazarn ambas tablas. Se emplean campos comunes, que deben tener tipos de datos iguales o similares. La condicion de combinacin, es decir, el o los campos por los que se van a combinar (parte "on"), se especifica segn las claves primarias y externas. Note que en la consulta, al nombrar el campo usamos el nombre de la tabla tambin. Cuando las tablas referenciadas tienen campos con igual nombre, esto es necesario para evitar confusiones y ambiguedades al momento de referenciar un campo. En el ejemplo, si no especificamos "editoriales.codigo" y solamente tipeamos "codigo", Oracle no sabr si nos referimos al campo "codigo" de "libros" o de "editoriales" y mostrar un mensaje de error indicando que "codigo" es ambiguo. Entonces, si las tablas que combinamos tienen nombres de campos iguales, DEBE especificarse a qu tabla pertenece anteponiendo el nombre de la tabla al nombre del campo, separado por un punto (.). Si una de las tablas tiene clave primaria compuesta, al combinarla con la otra, en la clusula "on" se debe hacer referencia a la clave completa, es decir, la condicin referenciar a todos los campos clave que identifican al registro. Se puede incluir en la consulta join la clusula "where" para restringir los registros que retorna el resultado; tambin "order by", "distinct", etc.. Se emplea este tipo de combinacin para encontrar registros de la primera tabla que se correspondan con los registros de la otra, es decir, que cumplan la condicin del "on". Si un valor de la primera tabla no se encuentra en la segunda tabla, el registro no aparece; si en la primera tabla el valor es nulo, tampoco aparece. Para simplificar la sentencia podemos usar un alias para cada tabla: select l.codigo,titulo,autor,nombre from libros l join editoriales e on l.codigoeditorial=e.codigo; En algunos casos (como en este ejemplo) el uso de alias es para fines de simplificacin y hace ms legible la consulta si es larga y compleja, pero en algunas consultas es absolutamente necesario. Ejercicio:

Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", tambin tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Elimine las tablas "clientes" y "provincias": drop table clientes; drop table provincias; 2- Crelas con las siguientes estructuras: create table clientes ( codigo number(5), nombre varchar2(30), domicilio varchar2(30), ciudad varchar2(20), codigoprovincia number(2) ); create table provincias( codigo number(2), nombre varchar2(20) ); 3- Ingrese algunos registros para ambas tablas: insert insert insert insert insert insert insert insert insert insert insert insert into into into into into into into into into into into into provincias provincias provincias provincias clientes clientes clientes clientes clientes clientes clientes clientes values(1,'Cordoba'); values(2,'Santa Fe'); values(3,'Corrientes'); values(null,'La Pampa'); (1,'Lopez Marcos','Colon 111','Crdoba',1); (2,'Perez Ana','San Martin 222','Cruz del Eje',1); (3,'Garcia Juan','Rivadavia 333','Villa Maria',null); (4,'Perez Luis','Sarmiento 444','Rosario',2); (5,'Pereyra Lucas','San Martin 555','Cruz del Eje',1); (6,'Gomez Ines','San Martin 666','Santa Fe',2); (7,'Torres Fabiola','Alem 777','Ibera',3); (8,'Garcia Paco','Avellaneda 888','Rawson',5);

values values values values values values values values

4- Obtenga los datos de ambas tablas, usando alias. Note que los registros de "clientes" cuyo valor de "codigoprovincia" que NO encuentran coincidencia con "codigo" de "provincias" no aparecen en el resultado de la consulta; caso de "Garcia Juan", que cdigo de provincia nulo y "Garcia Paco", que tiene un cdigo de provincia que no est presente en "provincias". 5- Obtenga la misma informacin anterior pero ordenada por nombre de provincia (join y order by)

6- Recupere todos los datos de los clientes de la provincia "Santa Fe" (join con where) (2 registros devueltos) Solucion: drop table clientes; drop table provincias; create table clientes ( codigo number(5), nombre varchar2(30), domicilio varchar2(30), ciudad varchar2(20), codigoprovincia number(2) ); create table provincias( codigo number(2), nombre varchar2(20) ); insert insert insert insert insert insert insert insert insert insert insert insert into into into into into into into into into into into into provincias provincias provincias provincias clientes clientes clientes clientes clientes clientes clientes clientes values(1,'Cordoba'); values(2,'Santa Fe'); values(3,'Corrientes'); values(null,'La Pampa'); (1,'Lopez Marcos','Colon 111','Crdoba',1); (2,'Perez Ana','San Martin 222','Cruz del Eje',1); (3,'Garcia Juan','Rivadavia 333','Villa Maria',null); (4,'Perez Luis','Sarmiento 444','Rosario',2); (5,'Pereyra Lucas','San Martin 555','Cruz del Eje',1); (6,'Gomez Ines','San Martin 666','Santa Fe',2); (7,'Torres Fabiola','Alem 777','Ibera',3); (8,'Garcia Paco','Avellaneda 888','Rawson',5);

values values values values values values values values

select c.nombre,domicilio,ciudad,p.nombre from clientes c join provincias p on c.codigoprovincia=p.codigo; select c.nombre,domicilio,ciudad,p.nombre from clientes c join provincias p on c.codigoprovincia=p.codigo order by p.nombre; select c.nombre,domicilio,ciudad from clientes c join provincias p on c.codigoprovincia=p.codigo

where p.nombre='Santa Fe';

Segundo problema: Un club dicta clases de distintos deportes. Almacena la informacin en una tabla llamada "inscriptos" que incluye el documento, el nombre, el deporte y si la matricula esta paga o no y una tabla llamada "inasistencias" que incluye el documento, el deporte y la fecha de la inasistencia. 1- Elimine las tablas y crelas: drop table inscriptos; drop table inasistencias; create table inscriptos( nombre varchar2(30), documento char(8), deporte varchar2(15), matricula char(1), --'s'=paga; 'n'=impaga primary key(documento,deporte) ); create table inasistencias( documento char(8), deporte varchar2(15), fecha date ); 2- Ingrese algunos registros para ambas tablas: insert insert insert insert insert insert insert insert insert insert insert insert into into into into into into into into into into into into inscriptos inscriptos inscriptos inscriptos inscriptos inscriptos values('Juan Perez','22222222','tenis','s'); values('Maria Lopez','23333333','tenis','s'); values('Agustin Juarez','24444444','tenis','n'); values('Marta Garcia','25555555','natacion','s'); values('Juan Perez','22222222','natacion','s'); values('Maria Lopez','23333333','natacion','n'); values('22222222','tenis','01/12/2006'); values('22222222','tenis','08/12/2006'); values('23333333','tenis','01/12/2006'); values('24444444','tenis','08/12/2006'); values('22222222','natacion','02/12/2006'); values('23333333','natacion','02/12/2006');

inasistencias inasistencias inasistencias inasistencias inasistencias inasistencias

3- Muestre el nombre, el deporte y las fechas de inasistencias, ordenado por nombre y deporte. Note que la condicin es compuesta porque para identificar los registros de la tabla "inasistencias" necesitamos ambos campos. Note que la persona con documento '25555555' no aparece en la consulta porque no est presente en "inasistencias". 4- Obtenga el nombre, deporte y las fechas de inasistencias de un determinado inscripto en un determinado deporte (3 registros).

5- Obtenga el nombre, deporte y las fechas de inasistencias de todos los inscriptos que pagaron la matrcula (4 registros) Solucin: drop table inscriptos; drop table inasistencias; create table inscriptos( nombre varchar2(30), documento char(8), deporte varchar2(15), matricula char(1), --'s'=paga; 'n'=impaga primary key(documento,deporte) ); create table inasistencias( documento char(8), deporte varchar2(15), fecha date ); insert insert insert insert insert insert insert insert insert insert insert insert into into into into into into into into into into into into inscriptos inscriptos inscriptos inscriptos inscriptos inscriptos values('Juan Perez','22222222','tenis','s'); values('Maria Lopez','23333333','tenis','s'); values('Agustin Juarez','24444444','tenis','n'); values('Marta Garcia','25555555','natacion','s'); values('Juan Perez','22222222','natacion','s'); values('Maria Lopez','23333333','natacion','n'); values('22222222','tenis','01/12/2006'); values('22222222','tenis','08/12/2006'); values('23333333','tenis','01/12/2006'); values('24444444','tenis','08/12/2006'); values('22222222','natacion','02/12/2006'); values('23333333','natacion','02/12/2006');

inasistencias inasistencias inasistencias inasistencias inasistencias inasistencias

select nombre,insc.deporte,ina.fecha from inscriptos insc join inasistencias ina on insc.documento=ina.documento and insc.deporte=ina.deporte order by nombre, insc.deporte; select nombre,insc.deporte, ina.fecha from inscriptos insc join inasistencias ina on insc.documento=ina.documento and insc.deporte=ina.deporte where insc.documento='22222222'; select nombre,insc.deporte, ina.fecha from inscriptos insc join inasistencias ina

on insc.documento=ina.documento and insc.deporte=ina.deporte where insc.matricula='s';

49 - Combinacin externa izquierda (left join)


Vimos que una combinacin interna (join) encuentra registros de la primera tabla que se correspondan con los registros de la segunda, es decir, que cumplan la condicin del "on" y si un valor de la primera tabla no se encuentra en la segunda tabla, el registro no aparece. Si queremos saber qu registros de una tabla NO encuentran correspondencia en la otra, es decir, no existe valor coincidente en la segunda, necesitamos otro tipo de combinacin, "outer join" (combinacin externa). Las combinaciones externas combinan registros de dos tablas que cumplen la condicin, ms los registros de la segunda tabla que no la cumplen; es decir, muestran todos los registros de las tablas relacionadas, an cuando no haya valores coincidentes entre ellas. Este tipo de combinacin se emplea cuando se necesita una lista completa de los datos de una de las tablas y la informacin que cumple con la condicin. Las combinaciones externas se realizan solamente entre 2 tablas. Hay tres tipos de combinaciones externas: "left outer join", "right outer join" y "full outer join"; se pueden abreviar con "left join", "right join" y "full join" respectivamente. Vamos a estudiar las primeras. Se emplea una combinacin externa izquierda para mostrar todos los registros de la tabla de la izquierda. Si no encuentra coincidencia con la tabla de la derecha, el registro muestra los campos de la segunda tabla seteados a "null". En el siguiente ejemplo solicitamos el ttulo y nombre de la editorial de los libros: select titulo,nombre from editoriales e left join libros l on codigoeditorial = e.codigo; El resultado mostrar el ttulo y nombre de la editorial; las editoriales de las cuales no hay libros, es decir, cuyo cdigo de editorial no est presente en "libros" aparece en el resultado, pero con el valor "null" en el campo "titulo". Es importante la posicin en que se colocan las tablas en un "left join", la tabla de la izquierda es la que se usa para localizar registros en la tabla de la derecha. Entonces, un "left join" se usa para hacer coincidir registros en una tabla (izquierda) con otra tabla (derecha); si un valor de la tabla de la izquierda no encuentra coincidencia en la tabla de la derecha, se genera una fila extra (una por cada valor no encontrado) con todos los campos correspondientes a la tabla derecha seteados a "null". La sintaxis bsica es la siguiente: select CAMPOS

from TABLAIZQUIERDA left join TABLADERECHA on CONDICION; En el siguiente ejemplo solicitamos el ttulo y el nombre la editorial, la sentencia es similar a la anterior, la diferencia est en el orden de las tablas: select titulo,nombre from libros l left join editoriales e on codigoeditorial = e.codigo; El resultado mostrar el ttulo del libro y el nombre de la editorial; los ttulos cuyo cdigo de editorial no est presente en "editoriales" aparecen en el resultado, pero con el valor "null" en el campo "nombre". Un "left join" puede tener clausula "where" que restringa el resultado de la consulta considerando solamente los registros que encuentran coincidencia en la tabla de la derecha, es decir, cuyo valor de cdigo est presente en "libros": select titulo,nombre from editoriales e left join libros l on e.codigo=codigoeditorial where codigoeditorial is not null; Tambin podemos mostrar las editoriales que NO estn presentes en "libros", es decir, que NO encuentran coincidencia en la tabla de la derecha: select titulo,nombre from editoriales e left join libros l on e.codigo=codigoeditorial where codigoeditorial is null; Ejercicio: Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", tambin tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Elimine las tablas "clientes" y "provincias", crelas y agregue restricciones nicas para los campos "codigo" de ambas tablas: drop table clientes; drop table provincias; create table clientes ( codigo number(5), nombre varchar2(30), domicilio varchar2(30), ciudad varchar2(20), codigoprovincia number(3) );

create table provincias( codigo number(3), nombre varchar2(20) ); alter table clientes add constraints UQ_clientes_codigo unique (codigo); alter table provincias add constraints UQ_provincias_codigo unique (codigo); 2- Ingrese algunos registros para ambas tablas. Incluya valores nulos para el campo "codigo" de "provincias" y valores nulos para el campo "codigoprovincia" de "clientes". Incluya en "clientes" un cdigo de provincia que no exista en "provincias": insert insert insert insert insert insert insert insert insert insert insert insert insert into into into into into into into into into into into into into provincias provincias provincias provincias provincias provincias clientes clientes clientes clientes clientes clientes clientes values(1,'Cordoba'); values(2,'Santa Fe'); values(3,'Corrientes'); values(4,'Santa Cruz'); values(null,'Salta'); values(null,'Jujuy'); (100,'Lopez Marcos','Colon 111','Crdoba',1); (200,'Perez Ana','San Martin 222','Cruz del Eje',1); (300,'Garcia Juan','Rivadavia 333','Villa Maria',null); (400,'Perez Luis','Sarmiento 444','Rosario',2); (500,'Gomez Ines','San Martin 666','Santa Fe',2); (600,'Torres Fabiola','Alem 777','La Plata',5); (700,'Garcia Luis','Sucre 475','Santa Rosa',null);

values values values values values values values

3- Muestre todos los datos de los clientes, incluido el nombre de la provincia Note que los clientes de "Santa Rosa", "Villa Maria" y "La Plata" se muestran seteados a null en la columna corespondiente al nombre de la provincia porque tienen valores nulos o inexistentes. 4- Realice la misma consulta anterior pero alterando el orden de las tablas. 5- Muestre solamente los clientes de las provincias que existen en "provincias" (4 registros) Note que los clientes de "Jujuy", "Salta", "Santa Cruz" y "Corrientes" se muestran seteados a null en los campos pertenecientes a la tabla "clientes" porque tienen valores nulos o inexistentes en dicha tabla. 6- Muestre todos los clientes cuyo cdigo de provincia NO existe en "provincias" ordenados por nombre del cliente (3 registros) 7- Obtenga todos los datos de los clientes de "Cordoba" (2 registros) Solucin:

drop table clientes; drop table provincias; create table clientes ( codigo number(5), nombre varchar2(30), domicilio varchar2(30), ciudad varchar2(20), codigoprovincia number(3) ); create table provincias( codigo number(3), nombre varchar2(20) ); alter table clientes add constraints UQ_clientes_codigo unique (codigo); alter table provincias add constraints UQ_provincias_codigo unique (codigo); insert insert insert insert insert insert insert insert insert insert insert insert insert into into into into into into into into into into into into into provincias provincias provincias provincias provincias provincias clientes clientes clientes clientes clientes clientes clientes values(1,'Cordoba'); values(2,'Santa Fe'); values(3,'Corrientes'); values(4,'Santa Cruz'); values(null,'Salta'); values(null,'Jujuy'); (100,'Lopez Marcos','Colon 111','Crdoba',1); (200,'Perez Ana','San Martin 222','Cruz del Eje',1); (300,'Garcia Juan','Rivadavia 333','Villa Maria',null); (400,'Perez Luis','Sarmiento 444','Rosario',2); (500,'Gomez Ines','San Martin 666','Santa Fe',2); (600,'Torres Fabiola','Alem 777','La Plata',5); (700,'Garcia Luis','Sucre 475','Santa Rosa',null);

values values values values values values values

select c.nombre,domicilio,ciudad, p.nombre as provincia from clientes c left join provincias p on codigoprovincia = p.codigo; select c.nombre,domicilio,ciudad, p.nombre from provincias p left join clientes c on codigoprovincia = p.codigo; select c.nombre,domicilio,ciudad, p.nombre as provincia from clientes c left join provincias p on codigoprovincia = p.codigo

where p.codigo is not null; select c.nombre,domicilio,ciudad, p.nombre as provincia from clientes c left join provincias p on codigoprovincia = p.codigo where p.codigo is null order by c.nombre; select c.nombre,domicilio,ciudad, p.nombre as provincia from clientes c left join provincias p on codigoprovincia = p.codigo where p.nombre='Cordoba';

50 - Combinacin externa derecha (right join)


Vimos que una combinacin externa izquierda (left join) encuentra registros de la tabla izquierda que se correspondan con los registros de la tabla derecha y si un valor de la tabla izquierda no se encuentra en la tabla derecha, el registro muestra los campos correspondientes a la tabla de la derecha seteados a "null". Una combinacin externa derecha ("right outer join" o "right join") opera del mismo modo slo que la tabla derecha es la que localiza los registros en la tabla izquierda. En el siguiente ejemplo solicitamos el ttulo y nombre de la editorial de los libros empleando un "right join": select titulo,nombre as editorial from libros l right join editoriales e on codigoeditorial = e.codigo; El resultado mostrar el ttulo y nombre de la editorial; las editoriales de las cuales no hay libros, es decir, cuyo cdigo de editorial no est presente en "libros" aparece en el resultado, pero con el valor "null" en el campo "titulo". Es FUNDAMENTAL tener en cuenta la posicin en que se colocan las tablas en los "outer join". En un "left join" la primera tabla (izquierda) es la que busca coincidencias en la segunda tabla (derecha); en el "right join" la segunda tabla (derecha) es la que busca coincidencias en la primera tabla (izquierda). En la siguiente consulta empleamos un "left join" para conseguir el mismo resultado que el "right join" anterior": select titulo,nombre from editoriales e left join libros l

on codigoeditorial = e.codigo; Note que la tabla que busca coincidencias ("editoriales") est en primer lugar porque es un "left join"; en el "right join" precedente, estaba en segundo lugar. Un "right join" hace coincidir registros en una tabla (derecha) con otra tabla (izquierda); si un valor de la tabla de la derecha no encuentra coincidencia en la tabla izquierda, se genera una fila extra (una por cada valor no encontrado) con todos los campos correspondientes a la tabla izquierda seteados a "null". La sintaxis bsica es la siguiente: select CAMPOS from TABLAIZQUIERDA right join TABLADERECHA on CONDICION; Un "right join" tambin puede tener clusula "where" que restringa el resultado de la consulta considerando solamente los registros que encuentran coincidencia en la tabla izquierda: select titulo,nombre from libros l right join editoriales e on e.codigo=codigoeditorial where codigoeditorial is not null; Mostramos las editoriales que NO estn presentes en "libros", es decir, que NO encuentran coincidencia en la tabla de la derecha empleando un "right join": select titulo,nombre from libros l right join editoriales e on e.codigo=codigoeditorial where codigoeditorial is null; Ejercicio: Primer problema: Una empresa tiene registrados sus clientes en una tabla llamada "clientes", tambin tiene una tabla "provincias" donde registra los nombres de las provincias. 1- Elimine las tablas "clientes" y "provincias" y crelas: drop table clientes; drop table provincias; create table clientes ( codigo number(5), nombre varchar2(30), domicilio varchar2(30), ciudad varchar2(20), codigoprovincia number(2), primary key(codigo)

); create table provincias( codigo number(2), nombre varchar2(20), primary key (codigo) ); 2- Ingrese algunos registros para ambas tablas: insert into provincias values(1,'Cordoba'); insert into provincias values(2,'Santa Fe'); insert into provincias values(3,'Corrientes'); insert insert insert insert insert insert insert into into into into into into into clientes clientes clientes clientes clientes clientes clientes values values values values values values values (101,'Lopez Marcos','Colon 111','Crdoba',1); (102,'Perez Ana','San Martin 222','Cruz del Eje',1); (103,'Garcia Juan','Rivadavia 333','Villa Maria',1); (104,'Perez Luis','Sarmiento 444','Rosario',2); (105,'Gomez Ines','San Martin 666','Santa Fe',2); (106,'Torres Fabiola','Alem 777','La Plata',4); (107,'Garcia Luis','Sucre 475','Santa Rosa',5);

3- Muestre todos los datos de los clientes, incluido el nombre de la provincia empleando un "right join". 4- Obtenga la misma salida que la consulta anterior pero empleando un "left join". 5- Empleando un "right join", muestre solamente los clientes de las provincias que existen en "provincias" (5 registros) 6- Muestre todos los clientes cuyo cdigo de provincia NO existe en "provincias" ordenados por ciudad (2 registros) Solucin: drop table clientes; drop table provincias; create table clientes ( codigo number(5), nombre varchar2(30), domicilio varchar2(30), ciudad varchar2(20), codigoprovincia number(2), primary key(codigo) ); create table provincias( codigo number(2), nombre varchar2(20), primary key (codigo) );

insert into provincias values(1,'Cordoba'); insert into provincias values(2,'Santa Fe'); insert into provincias values(3,'Corrientes'); insert insert insert insert insert insert insert into into into into into into into clientes clientes clientes clientes clientes clientes clientes values values values values values values values (101,'Lopez Marcos','Colon 111','Crdoba',1); (102,'Perez Ana','San Martin 222','Cruz del Eje',1); (103,'Garcia Juan','Rivadavia 333','Villa Maria',1); (104,'Perez Luis','Sarmiento 444','Rosario',2); (105,'Gomez Ines','San Martin 666','Santa Fe',2); (106,'Torres Fabiola','Alem 777','La Plata',4); (107,'Garcia Luis','Sucre 475','Santa Rosa',5);

select c.nombre,domicilio,ciudad, p.nombre from provincias p right join clientes c on codigoprovincia = p.codigo; select c.nombre,domicilio,ciudad, p.nombre from clientes c left join provincias p on codigoprovincia = p.codigo; select c.nombre,domicilio,ciudad, p.nombre from provincias p right join clientes c on codigoprovincia = p.codigo where p.codigo is not null; select c.nombre,domicilio,ciudad, p.nombre from provincias p right join clientes c on codigoprovincia = p.codigo where p.codigo is null order by ciudad;

Potrebbero piacerti anche