Sesion 2
Sesion 2
Sesion 2
SESION 2
"null" significa "dato desconocido" o "valor inexistente". No es lo mismo que un valor "0", una
cadena vacía o una cadena literal "null".
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.
Veamos un ejemplo. Tenemos nuestra tabla "libros". El campo "titulo" no debería estar vacío
nunca, igualmente el campo "autor". Para ello, al crear la tabla, debemos especificar que
dichos campos no admitan valores nulos:
Para especificar que un campo no admita valores nulos, debemos colocar "not null" luego de la
definición del campo.
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").
Si ingresamos los datos de un libro, para el cual aún 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.
Si intentamos ingresar el valor "null" en campos que no admiten valores nulos (como "titulo" o
"autor"), SQL Server no lo permite, muestra un mensaje y la inserción no se realiza; por
ejemplo:
insert into libros (titulo,autor,editorial,precio)
values(null,'Borges','Siglo XXI',25);
Para ver cuáles campos admiten valores nulos y cuáles no, podemos emplear el procedimiento
almacenado "sp_columns" junto al nombre de la tabla. Nos muestra mucha información, en la
columna "IS_NULLABLE" vemos que muestra "NO" en los campos que no permiten valores
nulos y "YES" en los campos que si los permiten.
Para recuperar los registros que contengan el valor "null" en algún 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):
select * from libros
where precio is null;
Con la primera sentencia veremos los libros cuyo precio es igual a "null" (desconocido); con la
segunda, los libros cuyo precio es 0.
Igualmente para campos de tipo cadena, las siguientes sentencias "select" no retornan los
mismos registros:
select * from libros where editorial is null;
select * from libros where editorial='';
Con la primera sentencia veremos los libros cuya editorial es igual a "null", con la segunda, los
libros cuya editorial guarda una cadena vacía.
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:
Creamos la tabla especificando que los campos "titulo" y "autor" no admitan valores nulos:
Los campos "editorial" y "precio" si permiten valores nulos; el primero, porque lo especificamos colocando
"null" en la definición del campo, el segundo lo asume por defecto.
Recuerde que el valor "null" no es una cadena de caracteres, por lo tanto no se coloca entre comillas.
Ingresamos otro registro, con valor nulo para el campo "editorial", campo que admite valores "null":
insert into libros (titulo,autor,editorial,precio)
values('Alicia en el pais','Lewis Carroll',null,0);
Veamos lo que sucede si intentamos ingresar el valor "null" en campos que no lo admiten, como "titulo":
Para ver cuáles campos admiten valores nulos y cuáles no, empleamos el procedimiento almacenado
"sp_columns":
sp_columns libros;
nos muestra muchas columnas, una de ellas tiene el encabezado "IS_NULLABLE", vemos que aparece "NO"
en los campos que no permiten valores nulos y "YES" en los campos que si los permiten.
Dijimos que el valor "null" no es lo mismo que una cadena vacía. Vamos a ingresar un registro con cadena
vacía para el campo "editorial":
Ingresamos otro registro, ahora cargamos una cadena vacía en el campo "titulo":
Con la primera sentencia veremos los libros cuyo precio es igual a "null" (desconocido); con la segunda, los
libros cuyo precio es 0.
Ahora veamos los libros cuya editorial almacena una cadena vacía:
2 - Clave primaria
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 número 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. Hay 2 maneras de
hacerlo, por ahora veremos la sintaxis más sencilla.
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 varchar(20),
clave varchar(10),
primary key(nombre)
);
Lo que hacemos agregar luego de la definición de cada campo, "primary key" y entre
paréntesis, el nombre del campo que será clave primaria.
Una tabla sólo 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, automáticamente SQL Server lo convierte a "not
null".
Luego de haber establecido un campo como clave primaria, al ingresar los registros, SQL
Server controla que los valores para el campo establecido como clave primaria no estén
repetidos en la tabla; si estuviesen repetidos, muestra un mensaje y la inserción 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
instrucción "insert" no se ejecuta.
Igualmente, si realizamos una actualización, SQL Server controla que los valores para el
campo establecido como clave primaria no estén repetidos en la tabla, si lo estuviese, aparece
un mensaje indicando que se viola la clave primaria y la actualización no se realiza.
Ejercicio:
Al campo "nombre" no lo definimos "not null", pero al establecerse como clave primaria, SQL Server lo
convierte en "not null", veamos que en la columna "IS_NULLABLE" aparece "NO":
sp_columns usuarios;
Recordemos que cuando un campo es clave primaria, sus valores no se repiten. Intentamos ingresar un
valor de clave primaria existente:
Cuando un campo es clave primaria, sus valores no pueden ser nulos. Intentamos ingresar el valor "null" en
el campo clave primaria:
Si realizamos alguna actualización, SQL Server controla que los valores para el campo establecido como
clave primaria no estén repetidos en la tabla. Intentemos actualizar el nombre de un usuario colocando un
nombre existente:
Un campo numérico puede tener un atributo extra "identity". Los valores de un campo con
este atributo genera valores secuenciales que se inician en 1 y se incrementan en 1
automáticamente.
Para que un campo pueda establecerse como "identity", éste debe ser entero (también puede
ser de un subtipo de entero o decimal con escala 0, tipos que estudiaremos posteriormente).
Para que un campo genere sus valores automáticamente, debemos agregar el atributo
"identity" luego de su definición al crear la tabla:
create table libros(
codigo int identity,
titulo varchar(40) not null,
autor varchar(30),
editorial varchar(15),
precio float
);
Cuando un campo tiene el atributo "identity" no se puede ingresar valor para él, porque se
inserta automáticamente tomando el último valor como referencia, o 1 si es el primero.
Para ingresar registros omitimos el campo definido como "identity", por ejemplo:
insert into libros (titulo,autor,editorial,precio)
values('El aleph','Borges','Emece',23);
Los valores secuenciales de un campo "identity" se generan tomando como referencia el último
valor ingresado; si se elimina el último registro ingresado (por ejemplo 3) y luego se inserta
otro registro, SQL Server seguirá la secuencia, es decir, colocará el valor "4".
Ejercicio:
Creamos la tabla especificando que el campos "codigo" genere valores secuenciales comenzando en 1 e
incrementándose en 1 automáticamente:
Ingresamos algunos registros, recordando que si un campo tiene el atributo "identity" debemos omitirlo en
la inserción:
Un campo "identity" tampoco puede ser actualizado. Intentemos cambiar el valor de código de un registro:
sp_columns libros;
Note que en el campo "codigo", en la columna "TYPE_NAME" aparece "int identity" y en la columna
IS_NULLABLE" aparece "NO", porque un campo "identity" automáticamente se convierte en "not null". En el
campo "titulo", en la columna "IS_NULLABLE" aparece "NO" porque explícitamente indicamos que el campo
fuera "not null".
Ingresamos un quinto registro y luego vemos que en el campo código se guardó el valor secuencial sin
considerar que el valor "4" ya no existe:
El atributo "identity" permite indicar el valor de inicio de la secuencia y el incremento, para ello
usamos la siguiente sintaxis:
create table libros(
codigo int identity(100,2),
titulo varchar(20),
autor varchar(30),
precio float
);
La función "ident_seed()" retorna el valor de inicio del campo "identity" de la tabla que
nombramos:
select ident_seed('libros');
Cuando "identity_insert" está en ON, las instrucciones "insert" deben explicitar un valor:
insert into libros (codigo,titulo)
values (5,'Alicia en el pais de las maravillas');
El atributo "identity" no implica unicidad, es decir, permite repetición de valores; por ello hay
que tener cuidado al explicitar un valor porque se puede ingresar un valor repetido.
Para desactivar la opción "identity_insert" tipeamos:
set identity_insert libros off;
Ejercicio:
Creamos la tabla especificando que el campos "codigo" genere valores secuenciales comenzando en 100 e
incrementándose en 2 automáticamente:
Ingresamos algunos registros, recordando que si un campo tiene el atributo "identity" debemos omitirlo en
la inserción:
el código (dato que no ingresamos) se cargó automáticamente, iniciándose en 100 y siguiendo la secuencia
de autoincremento (2).
Para saber cuál es el valor de inicio del campo "identity" de la tabla "libros" tipeamos:
select ident_seed('libros');
retorna "2".
Recordemos que si "identity_insert" está en ON, la instrucción "insert" DEBE explicitar un valor:
Note que ingresamos un valor de código menor al valor de inicio de la secuencia, está permitido.
5 - Truncate table
Aprendimos que para borrar todos los registro de una tabla se usa "delete" sin condición
"where".
También podemos eliminar todos los registros de una tabla con "truncate table".
La sentencia "truncate table" vacía la tabla (elimina todos los registros) y conserva la
estructura de la tabla.
La diferencia con "drop table" es que esta sentencia borra la tabla, "truncate table" la vacía.
La diferencia con "delete" es la velocidad, es más rápido "truncate table" que "delete" (se nota
cuando la cantidad de registros es muy grande) ya que éste borra los registros uno a uno.
Otra diferencia es la siguiente: cuando la tabla tiene un campo "identity", si borramos todos
los registros con "delete" y luego ingresamos un registro, al cargarse el valor en el campo de
identidad, continúa con la secuencia teniendo en cuenta el valor mayor que se había guardado;
si usamos "truncate table" para borrar todos los registros, al ingresar otra vez un registro, la
secuencia del campo de identidad vuelve a iniciarse en 1.
Por ejemplo, tenemos la tabla "libros" con el campo "codigo" definido "identity", y el valor más
alto de ese campo es "2", si borramos todos los registros con "delete" y luego ingresamos un
registro, éste guardará el valor de código "3"; si en cambio, vaciamos la tabla con "truncate
table", al ingresar un nuevo registro el valor del código se iniciará en 1 nuevamente.
Ejercicio:
Trabajamos con la tabla "libros" que almacena los datos de los libros de una librería.
Eliminamos la tabla, si existe:
Creamos la tabla:
Truncamos la tabla:
Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto es, definir
los campos y sus tipos más precisos, según el caso.
El tipo de dato especificado en la definición de cada campo indica los valores permitidos para
cada uno de ellos.
Hasta ahora hemos visto 3 tipos de datos: varchar, integer y float. Hay más tipos, incluso,
subtipos.
Entonces, cuando creamos una tabla y definir sus campos debemos elegir el tipo de dato más
preciso. Por ejemplo, si necesitamos almacenar nombres usamos texto; si un campo numérico
almacenará solamente valores enteros el tipo "integer" es más adecuado que, por ejemplo un
"float"; si necesitamos almacenar precios, lo más lógico es utilizar el tipo "money".
Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto es, definir
los campos y sus tipos más precisos, según el caso.
Podemos almacenar letras, símbolos y dígitos con los que no se realizan operaciones
matemáticas, por ejemplo, códigos de identificación, números de documentos, números
telefónicos.
Por ejemplo, si en un campo definido como varchar(5) ingresamos el valor 12345, lo toma
como si hubiésemos tipeado '12345', igualmente, si ingresamos el valor 23.56, lo convierte a
'23.56'. Si el valor numérico, al ser convertido a cadena supera la longitud definida, aparece
un mensaje de error y la sentencia no se ejecuta.
Para almacenar cadenas que varían en su longitud, es decir, no todos los registros tendrán la
misma longitud en un campo determinado, se emplea "varchar" 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 varían en su longitud, es decir, todos los registros tendrán la
misma longitud en un campo determinado, se emplea "char".
Por ejemplo, definimos un campo "codigo" que constará de 5 caracteres, todos los registros
tendrán un código de 5 caracteres, ni más ni menos.
Ejercicio:
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.
Eliminamos la tabla "visitantes", si existe:
Los campos "nombre", "domicilio" y "ciudad" almacenarán valores cuya longitud varía, por ello elegimos el
tipo "varchar" y le damos a cada uno una longitud máxima estimando su tamaño. El campo "sexo" se define
de tipo "char", porque necesitamos solamente 1 caracter "f" o "m", que siempre será fijo. El campo
"telefono" también se define como varchar porque no todos los números telefónicos tienen la misma
longitud.
Ingresamos un número telefónico olvidando las comillas, es decir, como un valor numérico:
Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto es, definir
los campos y sus tipos más precisos, según el caso.
Para almacenar valores ENTEROS, por ejemplo, en campos que hacen referencia a cantidades,
usamos:
2) decimal o numeric (t,d): Pueden tener hasta 38 digitos, guarda un valor exacto. El primer
argumento indica el total de dígitos y el segundo, la cantidad de decimales.
Por ejemplo, si queremos almacenar valores entre -99.99 y 99.99 debemos definir el campo
como tipo "decimal(4,2)". Si no se indica el valor del segundo argumento, por defecto es "0".
Por ejemplo, si definimos "decimal(4)" se pueden guardar valores entre -9999 y 9999.
Es importante elegir el tipo de dato adecuado según el caso, el más preciso. Por ejemplo, si un
campo numérico almacenará valores positivos menores a 255, el tipo "int" no es el más
adecuado, conviene el tipo "tinyint", de esta manera usamos el menor espacio de
almacenamiento posible.
Ejercicio:
Note que definimos el campo "codigo" de tipo "smallint", esto es porque estimamos que no tendremos más
de 30000 libros. Si necesitáramos un rango mayor podemos emplear "int".
Como en el campo "precio" no almacenaremos valores mayores a 200000, definimos el campo de tipo
"smallmoney".
También podemos definirlo de tipo "decimal(5,2)" porque el máximo precio no superará los 999.99.
El tipo "float" no es el más adecuado para representar precios porque no es exacto y muestra muchos
decimales innecesarios.
Como los valores para el campo "cantidad" no superarán los 255, definimos el campo de tipo "tinyint". Si
estimamos que tendremos más cantidad de libros podemos emplear "smallint" que tiene un rango mayor;
no es adecuado usar int (cuyo rango llega hasta 4000 millones aprox.), porque ocuparíamos más espacio (4
bytes).
Intentemos ingresar un valor fuera del rango definido, una cantidad que supera el rango del tipo "tinyint",
el valor 260:
Intentamos ingresar un precio que supera el rango del tipo "smallmoney", el valor 250000:
Intentamos ingresar una cadena que SQL Server no pueda convertir a valor numérico en el campo "precio"
(error):
Ya explicamos que al crear una tabla debemos elegir la estructura adecuada, esto es, definir
los campos y sus tipos más precisos, según el caso.
Para almacenar valores de tipo FECHA Y HORA SQL Server dispone de dos tipos:
1) datetime: puede almacenar valores desde 01 de enero de 1753 hasta 31 de diciembre de
9999.
2) smalldatetime: el rango va de 01 de enero de 1900 hasta 06 de junio de 2079.
Para almacenar valores de tipo fecha se permiten como separadores "/", "-" y ".".
SQL Server reconoce varios formatos de entrada de datos de tipo fecha. Para establecer el
orden de las partes de una fecha (dia, mes y año) empleamos "set dateformat". Estos son los
formatos:
Podemos ingresar una fecha, sin hora, en tal caso la hora se guarda como "00:00:00". Por
ejemplo, si ingresamos '25-12-01' (año de 2 dígitos), lo mostrará así: '2001-12-25
00:00:00.000'.
Podemos ingresar una hora sin fecha, en tal caso, coloca la fecha "1900-01-01". Por ejemplo,
si ingresamos '10:15', mostrará '1900-01-01 10:15.000'.
Ejercicio:
Una empresa almacena los datos de sus empleados en una tabla "empleados".
Eliminamos la tabla, si existe:
El segundo registro ingresado tiene 2 dígitos correspondientes al año; en el tercero empleamos la barra
('/') como separador y en el cuarto empleamos como separador el punto ('.') y colocamos un sólo dígito en
la part del día y el mes.
Mostramos los datos de los empleados cuya fecha de ingreso es anterior a '01-01-1985':
Actualizamos el nombre a "Maria Carla Juarez' del empleado cuya fecha de ingreso es igual a '20/05/1983':
Veamos si se actualizó:
Veamos si se eliminaron:
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:
SQL Server almacenará el valor "null" en el campo "editorial", para el cual no hemos
explicitado un valor.
Ejercicio:
Trabajamos con la tabla "libros" que almacena los datos de los libros de una librería.
Eliminamos la tabla, si existe:
Creamos la tabla:
Si ingresamos valores para todos los campos, podemos omitir la lista de campos:
No podemos omitir el valor para un campo declarado "not null", como el campo "titulo":