Manual Practico de Mysql PDF
Manual Practico de Mysql PDF
El directorio puede variar, por ejemplo, puede estar localizado en la raíz del disco C:, o en cualquier
otro lugar donde podamos haber instalado MySQL. Para acceder a la consola de MySQL en
Windows tendremos que estar situados dentro de ese directorio.
Para el efecto utilizaremos el Wamp Server 2.0 el cual al ser instalado se ubica en:
C:\wamp\bin\mysql\mysql5.1.36\bin>_
O seleccionar:
En Linux, por supuesto, también se puede acceder a MySQL por línea de comandos. Posiblemente
desde cualquier directorio podamos acceder a la consola de MySQL, sin necesidad de situarse en el
directorio donde esté instalado.
Lo primero que tendremos que hacer es conectar con el sistema gestor de MySQL. Para ello,
simplemente tenemos que escribir el comando "mysql" e indicarle unas opciones de conexión.
% mysql
Con el "%" expresamos el principio de la línea de comandos. Ese principio es el prompt que
tengamos en nuestra consola de Linux o MsDOS, que puede ser algo como
(C:\wamp\bin\mysql\mysql5.1.36\bin>). El carácter "%", por tanto, no tenemos que escribirlo.
Con esa sentencia se conecta uno con la base de datos con los parámetros por defecto. Es decir, al
servidor local, con usuario y password igual a cadenas vacías.
Lo más normal es que tengamos que indicar algún otro dato para conectar con la base de datos, como
el usuario, la clave o la dirección del servidor con el que queremos conectar. La sintaxis sería la
siguiente:
Si deseamos conectarnos a la base de datos en local y con nombre de usuario root tendríamos que
escribir:
1 Ing. Gabriel Demera Ureta MgSc.
Aplicaciones de Base de Datos
Lo primero que nos preguntará será el password para el usuario root. Una vez introducida la clave,
ya estaremos dentro de la línea de comandos de MySQL. Con ello el prompt cambiará a algo como
esto:
mysql>
Podríamos haber indicado la contraseña directamente en la línea de comandos para iniciar la sesión
con MySQL, pero esto se desaconseja por razones de seguridad. De todos modos, la sintaxis hubiera
sido:
% mysql -h localhost -u root -pmi_clave
Nos fijamos que entre -h y el nombre del host hay un espacio en blanco, igual que entre -u y el
nombre de usuario. Sin embargo, entre -p y la clave no debemos poner ningún espacio.
Una vez dentro, tendremos a nuestra disposición todas las sentencias de MySQL para el trabajo con
la base de datos y el lenguaje SQL.
Lo más normal es que necesites conectarte con una base de datos en concreto, de entre todas las que
puedes tener creadas en tu servidor MySQL. Eso se hace con el comando use, seguido del nombre de
la base de datos que deseas conectar.
ATENCIÓN: Hay que fijarse que todas las sentencias dentro de la línea de comandos de MySQL
acaban en ";". Si no colocamos el punto y coma, lo más seguro es que NO se ejecute el comando y
nos vuelva a salir el prompt para que sigamos introduciendo el comando. Si lo que queríamos era
ejecutar la sentencia que habíamos escrito antes, con simplemente entrar el ";" será suficiente. Es
decir, no debemos escribir de nuevo la sentencia entera, sólo el ";" y volver a apretar "enter".
Si queremos ver una lista de las bases de datos alojadas en nuestro servidor podemos escribir el
comando show databases. Así:
mysql>show databases;
Con esto nos mostraría una lista de las bases de datos de nuestro servidor. Algo como esto:
Si queremos crear una base datos, podremos hacerlo con el comando "create database" seguido del
nombre de la nueva base de datos.
Eso nos creará una base de datos que se llama "miprueba". Si ya existe una base de datos con ese
nombre, MySQL devolverá un error. Si queremos crear una base de datos solo cuando no exista ya (y
por lo tanto no obtener este error) podemos añadir el texto IF NOT EXISTS que evita el error en caso
de existir
Lógicamente, esta base de datos recién creada estará vacía, pero si estuviéramos usando una base de
datos ya creada y queremos ver las tablas que tiene escribiríamos el comando "show tables".
mysql> show tables;
Si no hay tablas, nos dirá algo como "Empty set", pero si tenemos varias tablas dadas de alta en la
base de datos que estamos usando, nos saldrá una lista de ellas:
mysql> show tables;
En este apartado se resumen las principales sentencias SQL que pueden ser utilizadas en el gestor de
base de datos MySQL, por ejemplo también se puede utilizar SHOW FULL COLUMNS FROM tabla; para
mostrar la estructura de una tabla.
CREACIÓN DE TABLAS
Una tabla es utilizada para organizar y presentar información. Las tablas se componen de filas y
columnas de celdas que se pueden rellenar con información, las tablas se componen de dos
estructuras:
3 Ing. Gabriel Demera Ureta MgSc.
Aplicaciones de Base de Datos
Registro: se la podría definir como una fila que contiene datos de los mismos tipos que las demás
filas. Ejemplo: en una tabla que tiene columnas como nombres y direcciones, cada fila contendrá un
nombre y una dirección.
Campo: es cada una de las columnas que forman la tabla. Contienen datos de tipo diferente a los de
otros campos. En el ejemplo anterior, un campo contendrá un tipo de datos único, como una
dirección, o un número de teléfono, un nombre, etc.
Cada tabla creada debe tener un nombre único en la cada Base de Datos, haciéndola accesible
mediante su nombre o su seudónimo (Alias). Las tablas son los objetos principales de bases de datos
que se utilizan para guardar gran cantidad de datos.
Después de la fase de diseño de una base de datos, en necesario crear las tablas correspondientes
dentro de la base de datos. Para cada campo o columna de cada una de las tablas, es necesario
determinar el tipo de datos que contiene, para de esa forma ajustar el diseño de la base de datos, y
conseguir un almacenamiento óptimo con la menor utilización de espacio. Los tipos de datos que
puede haber en un campo, se pueden agrupar en tres grandes grupos:
TinyInt: es un número entero con o sin signo. Con signo el rango de valores válidos va desde
-128 a 127. Sin signo, el rango de valores es de 0 a 255
Bit ó Bool: un número entero que puede ser 0 ó 1
SmallInt: número entero con o sin signo. Con signo el rango de valores va desde -32768 a
32767. Sin signo, el rango de valores es de 0 a 65535.
MediumInt: número entero con o sin signo. Con signo el rango de valores va desde -
8.388.608 a 8.388.607. Sin signo el rango va desde 0 a16777215.
Integer, Int: número entero con o sin signo. Con signo el rango de valores va desde -
2147483648 a 2147483647. Sin signo el rango va desde 0 a 429.4967.295
BigInt: número entero con o sin signo. Con signo el rango de valores va desde -
9.223.372.036.854.775.808 a 9.223.372.036.854.775.807. Sin signo el rango va desde 0 a
18.446.744.073.709.551.615.
Float: número pequeño en coma flotante de precisión simple. Los valores válidos van desde -
3.402823466E+38 a -1.175494351E-38, 0 y desde 1.175494351E-38 a 3.402823466E+38.
xReal, Double: número en coma flotante de precisión doble. Los valores permitidos van
desde -1.7976931348623157E+308 a -2.2250738585072014E-308, 0 y desde
2.2250738585072014E-308 a 1.7976931348623157E+308
Decimal, Dec, Numeric: Número en coma flotante desempaquetado. El número se almacena
como una cadena
A la hora de almacenar fechas, hay que tener en cuenta que Mysql no comprueba de una
manera estricta si una fecha es válida o no. Simplemente comprueba que el mes está
comprendido entre 0 y 12 y que el día está comprendido entre 0 y 31.
Date: tipo fecha, almacena una fecha. El rango de valores va desde el 1 de enero del 1001 al
31 de diciembre de 9999. El formato de almacenamiento es de año-mes-dia
DateTime: Combinación de fecha y hora. El rango de valores va desde el 1 de enero del 1001
a las 0 horas, 0 minutos y 0 segundos al 31 de diciembre del 9999 a las 23 horas, 59 minutos y
59 segundos. El formato de almacenamiento es de año-mes-dia horas:minutos:segundos
Tamaño Formato
AñoMesDiaHoraMinutoSegundo
14
aaaammddhhmmss
AñoMesDiaHoraMinutoSegundo
12
aammddhhmmss
8 ñoMesDia aaaammdd
6 AñoMesDia aammdd
4 AñoMes aamm
2 Año aa
Time: almacena una hora. El rango de horas va desde -838 horas, 59 minutos y 59 segundos a
838, 59 minutos y 59 segundos. El formato de almacenamiento es de 'HH:MM:SS'
Year: almacena un año. El rango de valores permitidos va desde el año 1901 al año 2155. El
campo puede tener tamaño dos o tamaño 4 dependiendo de si queremos almacenar el año con
dos o cuatro dígitos.
Tamaño de
Tipo de Campo
Almacenamiento
DATE 3 bytes
DATETIME 8 bytes
TIMESTAMP 4 bytes
TIME 3 bytes
YEAR 1 byte
Char(n): almacena una cadena de longitud fija. La cadena podrá contener desde 0 a 255
caracteres.
VarChar(n): almacena una cadena de longitud variable. La cadena podrá contener desde 0 a
255 caracteres.
Dentro de los tipos de cadena se pueden distinguir otros dos subtipos, los tipo Test y los tipo
BLOB (Binary large Object)
La diferencia entre un tipo y otro es el tratamiento que reciben a la hora de realizar
ordenamientos y comparaciones. Mientras que el tipo test se ordena sin tener en cuenta las
Mayúsculas y las minúsculas, el tipo BLOB se ordena teniéndolas en cuenta.
Los tipos BLOB se utilizan para almacenar datos binarios como pueden ser ficheros.
TinyText y TinyBlob: Columna con una longitud máxima de 255 caracteres.
Blob y Text: un texto con un máximo de 65535 caracteres.
MediumBlob y MediumText: un texto con un máximo de 16.777.215 caracteres.
LongBlob y LongText: un texto con un máximo de caracteres 4.294.967.295. Hay que tener
en cuenta que debido a los protocolos de comunicación los paquetes pueden tener un máximo
de 16 Mb.
Enum: campo que puede tener un único valor de una lista que se especifica. El tipo Enum
acepta hasta 65535 valores distintos
Set: un campo que puede contener ninguno, uno ó varios valores de una lista. La lista puede
tener un máximo de 64 valores.
Tipo de campo Tamaño de Almacenamiento
CHAR(n) n bytes
VARCHAR(n) n +1 bytes
TINYBLOB, TINYTEXT Longitud+1 bytes
BLOB, TEXT Longitud +2 bytes
MEDIUMBLOB, MEDIUMTEXT Longitud +3 bytes
LONGBLOB, LONGTEXT Longitud +4 bytes
1 ó dos bytes dependiendo del número de
ENUM('value1','value2',...)
valores
1, 2, 3, 4 ó 8 bytes, dependiendo del número
SET('value1','value2',...)
de valores
Almace Almace
Valor CHAR(4) VARCHAR(4)
namiento namiento
'' '' 4 bytes " 1 byte
'ab' 'ab ' 4 bytes 'ab' 3 bytes
'abcd' 'abcd' 4 bytes 'abcd'
'abcdefgh' 'abcd' 4 bytes 'abcd' 5 bytes
TYPE=INNODB es para especificar el tipo de motor de base de datos que utilizará para crear la tabla,
también se puede crear una tabla utilizando el motor que se encuentra ejecutando por defecto con el
siguiente formato:
CREATE TABLE usuario (
id_usuario INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(50) NOT NULL,
direccion VARCHAR(50) NOT NULL,
ciudad VARCHAR(20) NOT NULL,
edad TINYINT NOT NULL
);
Asumiendo que se le olvidó crear un campo fecha de registro a la tabla usuario usted tendría que
utilizar el comando ALTER TABLE, por ejemplo:
Cambia el nombre de la columna 'ciudad' al nuevo nombre ' accesos_permitidos' que incluye la
definición del tipo de dato:
ALTER TABLE usuario CHANGE ciudad accesos_permitidos int(4);
DESCRIBE usuario;
Para cambia solo el tipo de datos de la columna 'edad' y especifica que no admite nulos:
ALTER TABLE usuario MODIFY edad FLOAT(6,2) NOT NULL;
En la tabla 'usuario' cualquiera que sea la columna que tenga 'AUTO_INCREMENT' en sus
propiedades (solo puede haber una), los nuevos registros comenzarán a partir de '1000' o cualquier
número indicado, no es posible utilizar un valor ya existente.
1. ALTER TABLE usuario AUTO_INCREMENT=1000;
2. INSERT INTO usuario(nombre,direccion,accesos_permitidos,edad,Fecha_Registro,email)
VALUES („Carlos‟,‟portoviejo‟,20,16,‟2013-09-26‟,‟[email protected]‟);
3. SELECT * FROM usuario;
Al aplicar la sentencia número 3 SELECT, notará que el primer registro ya no empezará por el índice
1 sino que comenzará por el 1000.
Para eliminar la columna 'edad' de la tabla 'usuario', usted tendría que realizar lo siguiente:
ALTER TABLE usuario DROP COLUMN edad;
DESCRIBE usuario;
Para ejemplificar la creación de una base de datos con sus respectivas tablas, tomaremos como
referencia el almacenamiento de registros datos para una unidad educativa, para el siguiente análisis
considere que un alumno puede ser con el tiempo ser un padre de familia, o un docente de la misma
institución:
use Unidad;
Los datos registrados pueden ser extraídos de la tabla mediante el uso de la instrucción SELECT , por
ejemplo, si se necesita el listado se todas las personas con todos sus datos podríamos hacerlo de la siguiente
forma:
SELECT IdPersona, ApellidoPaterno, ApellidoMaterno, Nombres, Direccion, telefono, sexo, FechaNacimiento,
EstadoCivil FROM personas;
Cuando se desea omitir el listado de todos los campos y obtener el mismo resultado usted puede hacer uso del
asterisco (*), por ejemplo:
SELECT * FROM personas;
Cuando se desea datos específicos usted puede utilizar de la lista de campos los que desee, por ejemplo, listar
los apellidos, nombres, direcciones y fechas de nacimiento de todos los ingresados:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, Direccion, FechaNacimiento FROM personas;
Sí lo solicitado incluye la condición de que solo sea para los de sexo femenino, se debe incluir la clausula
WHERE que permite agregar condiciones de clasificación de datos, por ejemplo:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, Direccion, FechaNacimiento
FROM personas
WHERE sexo=‟f‟;
Si necesitamos la lista de personas mayores de 30 años de edad, se tendría que conocer la fecha de
hoy asumamos que es 18 de agosto de 2013, si resto 30 años quedaría 1983/09/18 (este es el formato
de MySQL), así que la instrucción quedaría:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, telefono, sexo, FechaNacimiento
FROM personas
WHERE FechaNacimiento <‟1983/09/18‟;
Podemos cambiar los formatos de salida que se utilizan en MySQL, por ejemplo, mostraremos
unidos los apellidos y el nombre, fecha de nacimiento con el formato día mes y año, y sexo mostrará
masculino o femenino:
SELECT concat(personas.ApellidoPaterno, ' ',personas.ApellidoMaterno ,' ',personas.Nombres) As Estudiante,
if(sexo='F','Femenino','Masculino') As Sexo, date_format(FechaNacimiento,‟%d/%m/%Y‟)
FROM personas;
Sí se necesita ver las edades de todas las personas utilizaremos la función TIMESTAMPDIFF que
devuelve la diferencia en años entre dos fechas, la cláusula CURRENT_DATE devuelve la fecha
actual que registra el computador:
SELECT concat(personas.ApellidoPaterno, ' ',personas.ApellidoMaterno ,' ',personas.Nombres) As Nombre,
TIMESTAMPDIFF(YEAR,fechanacimiento,CURRENT_DATE) as edad FROM personas;
Sí necesitamos la lista ordenada por apellido paterno de forma ascendente o descendente se utilizaría:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, telefono, sexo, FechaNacimiento
FROM personas ORDER BY ApellidoPaterno;
Por defecto ordena ascendentemente o si prefiere puede utilizar la instrucción ASC, también puede
incluir sub órdenes agregando una lista separado por comas, por ejemplo:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, telefono, sexo, FechaNacimiento
FROM personas ORDER BY ApellidoPaterno ASC, ApellidoMaterno DESC;
Asumiendo que necesitamos las tres personas que tengan más edad podríamos utilizar:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, sexo, FechaNacimiento
FROM personas ORDER BY FechaNacimiento ASC LIMIT 3;
Para obtener un listado de años de nacimiento sin que se repitan tendríamos que realizar lo siguiente:
SELECT DISTINCT YEAR(FechaNacimiento) AS anio
FROM personas ORDER BY anio;
A menudo tenemos columnas que son cadenas de caracteres, y queremos buscar las cadenas que
contienen cierta palabra. Esto se realiza a través de un nuevo tipo de condición:
Nombre_de_columna LIKE cadena_de_caracteres.
Con LIKE puede usar los siguientes dos caracteres comodines en el patrón:
Carácter Descrición
% Coincidencia de cualquier número de caracteres, incluso cero caracteres
_ Coincide exactamente un carácter
Listar todas las personas cuya segunda letra del apellido paterno es E
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, sexo, FechaNacimiento
FROM personas
WHERE ApellidoPaterno LIKE „_E%‟;
Si se necesita listar todos las personas cuyo apellido paterno no empiece con Z entonces quedaría así:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, sexo, FechaNacimiento
FROM personas
WHERE ApellidoPaterno NOT LIKE „Z%‟;
Para testear instancias literales de un carácter comodín, preceda el carácter con el carácter de escape.
Si no especifica el carácter ESCAPE , se asume '\' .
Cadena Descrición
\% Coincide un carácter '%'
\_ Coincide un carácter '_'
Si desea filtrar registros utilizando una lista de valores o palabras puede hacer uso de la cláusula IN,
por ejemplo asumamos que queremos ver la lista de personas cuyo apellido paterno es VACA,
PANTA y SALAZAR tendríamos que hacer lo siguiente:
En algún momento necesitaremos consultas que nos devuelva totales (1 solo registro), para ello se
utilizará unas funciones estandarizadas de cálculo de registros COUNT(), SUM(), AVG(), MAX(),
NIM(), entre otros.
Existe la posibilidad de utilizar agrupamientos para que puedan existir varios totales dependiendo de
las necesidades de agrupar, para esto se utiliza la cláusula GROUP BY
Para conocer cuántas personas nacieron por año de las que se encuentran registradas en nuestra tabla
podríamos realizar lo siguiente:
LAS SUBCONSULTAS
Una subconsulta, es una sentencia SELECT que aparece dentro de otra sentencia SELECT que
llamaremos consulta principal. Se puede encontrar en la lista de selección, en la cláusula WHERE
o en la cláusula HAVING de la consulta principal.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando que aparece
encerrada entre paréntesis, no puede contener la cláusula ORDER BY, ni puede ser la UNION de
varias sentencias SELECT, además tiene algunas restricciones en cuanto a número de columnas
según el lugar donde aparece en la consulta principal.
Cuando se ejecuta una consulta que contiene una subconsulta, la subconsulta se ejecuta por cada
fila de la consulta principal.
Las consultas que utilizan subconsultas suelen ser más fáciles de interpretar por el usuario.
Para realizar las siguientes prácticas agregaremos más registros a las tablas “Personas y Profesores”:
INSERT INTO Personas
(ApellidoPaterno,ApellidoMaterno,Nombres,Direccion,telefono,sexo,FechaNacimiento,EstadoCivil)
VALUES ('Falcones','Canchingre','Ángela', 'Cdla. Los tamarindos', '052636456','F','1982/06/18','C'),
('Mora', 'Hidalgo', 'Octavio', 'Cdla. Ceibos del Norte','052360789','M','1970/05/08','C'),
('Delgado', 'Ramirez', 'Maricela', 'Cdla. Ceibos del Norte','054511133','F','1996/08/12','C'),
('Zambrano','Delgado', 'Javier', 'Cdla. Los Bosques', '052456123','M','1984-05-28','D'),
('Cardenas','Flores', 'Ana María', 'Eloy Alfaro y Plaza', '052100456','F','1991-03-18','D'),
('Basurto', 'Cedeño', 'Dolores', 'Cdla. Los Mangos', '052390987','F','1971/04/01','C'),
('Zambrano','López', 'José', 'parroq. San Placido', '052111654','M','1973/03/30','C'),
('Montesdeoca','Ureta','Elena ', 'Cdla. Forestal', '052222321','F','1974/01/25','C'),
('Farías', 'Salazar', 'Joel', 'Cdla. Terra Nostra', '052333254','M','1979/08/13','C'),
('Delgado', 'Manuel', 'Benedicto', 'Cdla. Los Bosques', '052444157','M','1979/09/23','C'),
('Navarrete','Ormaza', 'Yolanda', 'Cdla. Los tamarindos', '052534876','F','1981/01/10','C'),
('Giler', 'Mejía', 'Sócrates', 'Cdla. Ceibos del Norte','052778654','M','1985/03/18','C'),
('Mendieta','Vera', 'Juan Carlos','No Registrada', '052580505','M','1974/05/18','C'),
('Briónes', 'Zambrano','Gema', '25 de Diciembre', '052654987','F','1980/04/14','S'),
('Moya', 'Loor', 'Fernando', 'Morales', '052654987','M','1982/09/28','S'),
('Arias', 'De la Cruz','Ivan', 'Ramos y Duarte', '321654987','M','1990/08/25','V'),
('Andrade', 'Castro', 'Viviana ', 'San Placido', '052222233','F','2000/03/01','S'),
('Benitez', 'Sabando', 'Carmen', 'Calderon', '053333233','F','2001/06/30','S'),
('Burbano', 'Vera', 'José ', 'Rio Chico', '054444233','M','1995/02/17','S'),
('Zambrano','Cardenas', 'María José','Cdla. Bosques', '054561233','F','1999/06/10','S'),
('Zambrano','Cardenas','Eduardo', 'Rio Chico', '051111233','M','1995/03/01','S'),
('Zambrano','Falcones','Paola', 'Los tamarindos', '054871233','F','2000/03/18','S'),
('Demera', 'Montero', 'Alejandro', ' Cdla Parque Forestal', '055551233','M','2001/01/20','S'),
('Mora', 'Delgado', 'Miguel Ángel','18 de octubre', '056666233','M','2002/03/15','S'),
('Zambrano','Bazurto', 'Leonardo', 'Los Mangos', '057771233','M','2000/08/11','S'),
('Zambrano','Bazurto', 'Enrique ', 'Los Tamarindos', '058888233','M','2002/11/11','S'),
('Farías', 'Montesdeoca','Francisco','Los Bosques', '059999233','M','1996/03/19','S'),
('Delgado','Navarrete','Carlos Luis','San Placido', '050001233','M','2001/12/31','S'),
('Giler', 'Briones', 'LilY Anabel', 'Cdla Forestal', '051112222','F','1990/03/21','S'),
('Mendieta','Andrade', 'Marcos', 'Cdla Primero de Mayo', '051114444','M','1993/10/10','S'),
('Moya', 'Aveiga', 'Antonio', 'Parroquia Calderon', '051115555','M','2000/05/25','S'),
('Arias', 'Benitez', 'John Jairo', 'Vía a Rio Chico', '051116666','M','2002/07/30','S'),
('Burbano', 'Moncayo', 'Pedro Andrés','Floron 1', '051117777','M','1998/01/17','S'),
('Demera', 'Montero','María Gabriela',' Cdla Parque Forestal','051118888','F','1995/05/09','S'),
('Mora', 'Delgado', 'Virginia Yessenia','Parr. Rio Chico','051119999','F','2001/06/04','S'),
Para mostrar el listado de personas que son autoridades en la institución se lo realizaría así:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres
FROM personas
WHERE IdPersona IN (SELECT IdPersona FROM Profesores WHERE cargo <>‟Profesor‟);
Para mostrar lo nombres y apellidos de los profesores que son padres de familia en la institución se lo
realizaría así:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres
FROM personas
WHERE IdPersona IN (SELECT IdPersona FROM Padres WHERE ocupacion like ‟Profe%‟);
Si necesita mostrar la lista de estudiantes cuyas madres sean profesoras de la institución quedaría así:
SELECT ApellidoPaterno, ApellidoMaterno, Nombres
FROM personas
WHERE IdPersona IN (SELECT IdPersona FROM Estudiante WHERE IdPersonaMama IN (SELECT idpersona
FROM Profesores)) ORDER BY ApellidoPaterno;
Las subconsultas permiten comparar, desde la consulta principal con datos extraídos desde la misma
u otras tablas, pero no se pueden mostrar los campos de las subconsulta con los campos de la
consulta principal.
CONSULTAS MULTI-TABLAS
Hasta ahora todas las consultas que hemos usado se refieren a mostrar datos de sólo una tabla, pero
también es posible hacer consultas usando varias tablas en la misma sentencia SELECT.
Este proceso permite realizar dos operaciones de álgebra relacional: el producto cartesiano y la
composición.
Producto cartesiano.- Este es un operador binario, se aplica a dos relaciones y el resultado es otra
relación. El resultado es una relación que contendrá todas las combinaciones de las tuplas de los dos
operandos.
Esto es: si partimos de dos relaciones, R y S, cuyos grados son n y m, y cuyas cardinalidades a y b, la
relación producto tendrá todos los atributos presentes en ambas relaciones, por lo tanto, el grado será
n+m. Además la cardinalidad será el producto de a y b.
Para ver un ejemplo usaremos dos tablas inventadas al efecto:
tabla2
id número
15 12345678
26 21222112
15 66525425
El resultado del producto cartesiano de tabla1 y tabla2: tabla1 x tabla2 es:
tabla1 x tabla2
id nombre apellido id número
15 Fulginio Liepez 15 12345678
26 Cascanio Suanchiez 15 12345678
15 Fulginio Liepez 26 21222112
26 Cascanio Suanchiez 26 21222112
15 Fulginio Liepez 15 66525425
26 Cascanio Suanchiez 15 66525425
Podemos ver que el grado resultante es 3+2=5, y la cardinalidad 2*3 = 6.
Composición (Join).- Una composición (Join en inglés) es una restricción del producto cartesiano, en la
relación de salida sólo se incluyen las tuplas que cumplan una determinada condición.
La condición que se usa más frecuentemente es la igualdad entre dos atributos, uno de cada tabla.
<relación1>[<condición>]<relación2>
tabla2
id número
15 12345678
26 21222112
15 66525425
La composición de estas dos tablas, para una condición en que 'id' sea igual en ambas sería:
tabla1[tabla1.id = tabla2.id]tabla2
id nombre apellido t2.id número
15 Fulginio Liepez 15 12345678
26 Cascanio Suanchiez 26 21222112
15 Fulginio Liepez 15 66525425
Para aplicar el producto cartesiano en consultas multi-tablas crearemos otras entidades a nuestra base
de datos UNIDAD:
INSERT INTO
Matriculas(IdPersonaEstudiante,IdPeriodoLectivo,IdEspecialidad,IdCurso,IdParalelo,IdPersonaRepresentante,Folder)
VALUES (46,2,1,7,1,30,'Archivador A 25'),
(47,2,1,7,1,33,'Archivador A 26'),
(42,2,1,7,1,24,'Archivador A 25'),
(37,2,1,7,1,1, 'Archivador A 26'),
(48,2,1,6,1,2 ,'Archivador A 27'),
(41,2,1,7,1,22,'Archivador A 27'),
(54,2,1,6,1,23,'Archivador A 28'),
(43,2,1,7,1,26,'Archivador A 28'),
(52,2,1,6,1,26,'Archivador A 29'),
(44,2,1,7,1,27,'Archivador A 29'),
(53,2,1,6,1,27,'Archivador A 30'),
(38,2,1,7,1,16,'Archivador A 30'),
(49,2,1,7,1,16,'Archivador A 31'),
(45,2,1,6,1,29,'Archivador A 31'),
(51,2,1,6,1,29,'Archivador A 32'),
(35,2,1,6,1,19,'Archivador A 32'),
(40,2,1,6,1,20,'Archivador A 33'),
(39,2,1,7,1,20,'Archivador A 33'),
(36,2,1,6,1,15,'Archivador A 34'),
(34,2,1,7,1,19,'Archivador A 34');
(Aplicando producto cartesiano con dos tablas) Si se necesita conocer la lista de profesores con sus
datos personales tendríamos que hacer lo siguiente:
SELECT concat(ApellidoPaterno,‟ „, ApellidoMaterno,‟ „,Nombres) AS Personas, cargo, titulacion
FROM Personas, Profesores
WHERE Personas.IdPersona=Profesores.IdPersona;
(Aplicando producto cartesiano con tres tablas) Sí necesitamos el listado de estudiantes matriculados
con sus respectivos representantes, tendríamos:
SELECT concat(personas.ApellidoPaterno, „ „,
personas.ApellidoMaterno, „ „, personas.Nombres) As
Estudiantes, Matriculas.IdMatricula As Matricula,
concat(personas_1.ApellidoPaterno, „ „,
personas_1.ApellidoMaterno,‟ „, personas_1.Nombres) As
Representante
FROM Personas AS personas_1, Personas, Matriculas
WHERE
personas.IdPersona = matriculas.IdPersonaEstudiante AND
personas_1.IdPersona = matriculas.IdPersonaRepresentante;
El INNER JOIN es otro tipo de composición de tablas, permite emparejar filas de distintas tablas de
forma más eficiente que con el producto cartesiano cuando una de las columnas de emparejamiento
está indexada. Ya que en vez de hacer el producto cartesiano completo y luego seleccionar la filas
que cumplen la condición de emparejamiento, para cada fila de una de las tablas busca directamente
en la otra tabla las filas que cumplen la condición, con lo cual se emparejan sólo las filas que luego
aparecen en el resultado.
La sintaxis es la siguiente:
tabla1 y tabla2 son especificaciones de tabla (nombre de tabla con alias o no, nombre de consulta
guardada), de las tablas cuyos registros se van a combinar.
Observar que dentro de la cláusula ON los nombres de columna deben ser nombres cualificados
(llevan delante el nombre de la tabla y un punto).
Las columnas de emparejamiento deben contener la misma clase de datos, las dos de tipo texto, de
tipo fecha etc... los campos numéricos deben ser de tipos similares. Por ejemplo, se puede combinar
campos AutoNumérico y Long puesto que son tipos similares, sin embargo, no se puede combinar
campos de tipo Simple y Doble. Además las columnas no pueden ser de tipo Memo ni OLE.
comp representa cualquier operador de comparación ( =, <, >, <=, >=, o <> ) y se utiliza para
establecer la condición de emparejamiento.
Se pueden definir varias condiciones de emparejamiento unidas por los operadores AND y OR
poniendo cada condición entre paréntesis.
Ejemplo:
Si necesitamos ver el listado de profesores, tendríamos:
SELECT personas.ApellidoPaterno, personas.ApellidoMaterno, personas.Nombres, profesores.cargo,
profesores.Titulacion
FROM personas INNER JOIN profesores ON personas.IdPersona = profesores.IdPersona;
Se pueden combinar más de dos tablas, en este caso hay que sustituir en la sintaxis una tabla por un
INNER JOIN completo.
Por ejemplo, sí necesitamos el listado de todos los estudiantes matriculados con sus respectivos
representantes, tendríamos:
VISTAS EN MySQL
Las vistas tienen la misma estructura que una tabla: filas y columnas. La única diferencia es que sólo
se almacena de ellas la definición, no los datos. Los datos que se recuperan mediante una consulta a
una vista se presentarán igual que los de una tabla. De hecho, si no se sabe que se está trabajando con
una vista, nada hace suponer que es así. Al igual que sucede con una tabla, se pueden insertar,
actualizar, borrar y seleccionar datos en una vista. Aunque siempre es posible seleccionar datos de
una vista, en algunas condiciones existen restricciones para realizar el resto de las operaciones sobre
vistas.
Una vista se especifica a través de una expresión de consulta (una sentencia SELECT) que la calcula
y que puede realizarse sobre una o más tablas. Sobre un conjunto de tablas relacionales se puede
trabajar con un número cualquiera de vistas.
La mayoría de los SGBD soportan la creación y manipulación de vistas. Las vistas se crean cuando
se necesitan hacer varias sentencias para devolver una tabla final.
CREANDO UNA VISTA: Se emplea la sentencia CREATE VIEW, que incluye una
subconsulta (subquery) para determinar los datos a ser mostrados a través de la vista.
Sintaxis:
CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW <vista>
[(<alias>[, <alias>] … )]
AS <subconsulta>
[WITH CHECK OPTION [CONSTRAINT <restricción>]]
[WITH READ ONLY [CONSTRAINT <restricción>]];
Dónde: OR REPLACE Se utiliza por si la vista ya estuviera creada anteriormente. En ese caso, la
sustituye por la nueva definición. Por ejemplo si necesitamos crear una vista que muestra el listado de
profesores:
CREATE VIEW V_Lista_Profesores AS
SELECT ApellidoPaterno, ApellidoMaterno,Nombres, Titulacion
FROM profesores INNER JOIN personas ON profesores.IdPersona = personas.IdPersona
WHERE profesores.cargo Like 'prof%'
ORDER BY ApellidoPaterno;
Si necesita chequear la creación de la vista, utilice el comando (SHOW TABLES;), para verificar el
contenido de la vista utilice (DESCRIBE V_lista_Profesores;), para observar la codificación de la
vista se utiliza (SHOW CREATE VIEW V_lista_Profesores;), para ver la vista ejecutada utilice el
comando (SELECT * FROM v_lista_profesores;), asumiendo que la vista tiene fallas, lo más
recomendable es volver a ejecutar la vista utilizando la sintaxis OR REPLACE, por ejemplo:
Una vez desarrollada la vista, se la define como una tabla temporal, sí usted utiliza el comando
SHOW TABLES; podrá observarla como si se tratara de una tabla adicional, de hecho se puede
aplicar condiciones y relaciones sobre ellas, por ejemplo si necesitara clasificar la lista de estudiantes
por cursos y paralelos, tendríamos:
#Vista que muestra el listado de estudiantes
CREATE VIEW V_Lista_Estudiantes AS
SELECT ApellidoPaterno, ApellidoMaterno, Nombres, Curso, Paralelo
FROM personas INNER JOIN (paralelos INNER JOIN (cursos INNER JOIN matriculas ON cursos.IdCurso =
matriculas.IdCurso)
ON paralelos.IdParalelo = matriculas.IdParalelo) ON personas.IdPersona = matriculas.IdPersonaEstudiante
ORDER BY ApellidoPaterno, ApellidoMaterno;
Para aplicar una condición a la vista como si se tratara de una tabla se lo realiza de la siguiente
manera:
SELECT * FROM V_lista_Estudiantes WHERE curso='septimo' AND paralelo=‟A‟;
Es importante entender que los campos a utilizar en la comparación deben estar en el listado de la
vista.
El siguiente ejemplo se creara 2 vistas para ser utilizadas en una relación, el resultado consiste en
mostrar la lista de estudiantes cuyos padres sean profesores:
Sin embargo, normalmente no será una buena práctica dejar que todos los usuario con acceso al
servidor tengan todos los privilegios. Para conservar la integridad de los datos y de las estructuras
será conveniente que sólo algunos usuarios puedan realizar determinadas tareas, y que otras, que
requieren mayor conocimiento sobre las estructuras de bases de datos y tablas, sólo puedan realizarse
por un número limitado y controlado de usuarios.
Los conceptos de usuarios y privilegios están íntimamente relacionados. No se pueden crear usuarios
sin asignarle al mismo tiempo privilegios. De hecho, la necesidad de crear usuarios está ligada a la
necesidad de limitar las acciones que tales usuarios pueden llevar a cabo.
MySQL permite definir diferentes usuarios, y además, asignar a cada uno determinados privilegios
en distintos niveles o categorías de ellos.
NIVELES DE PRIVILEGIOS
Globales: se aplican al conjunto de todas las bases de datos en un servidor. Es el nivel más alto de
privilegio, en el sentido de que su ámbito es el más general.
Estos permisos se almacenan en la tabla mysql.user. GRANT ALL ON *.* y REVOKE ALL ON
*.* otorgan y quitan sólo permisos globales.
De base de datos: se refieren a bases de datos individuales, y por extensión, a todos los objetos que
contiene cada base de datos.
Estos permisos se almacenan en las tablas mysql.db y mysql.host. GRANT ALL ON db_name.* y
REVOKE ALL ON db_name.* otorgan y quitan sólo permisos de bases de datos.
De tabla: se aplican a tablas individuales, y por lo tanto, a todas las columnas de esas tabla.
Estos permisos se almacenan en la tabla mysql.tables_priv. GRANT ALL ON db_name.tbl_name y
REVOKE ALL ON db_name.tbl_name otorgan y quian permisos sólo de tabla.
De columna: se aplican a una columna en una tabla concreta.
Estos permisos se almacenan en la tabla mysql.columns_priv . Usando REVOKE, debe especificar
las mismas columnas que se otorgaron los permisos.
De rutina: se aplican a los procedimientos almacenados. Aún no hemos visto nada sobre este tema,
pero en MySQL se pueden almacenar procedimietos consistentes en varias consultas SQL.
CREAR USUARIOS
Aunque en la versión 5.0.2 de MySQL existe una sentencia para crear usuarios, CREATE USER, en
versiones anteriores se usa exclusivamente la sentencia GRANT para crearlos.
En general es preferible usar GRANT, ya que si se crea un usuario mediante CREATE USER,
posteriormente hay que usar una sentencia GRANT para concederle privilegios.
Usando GRANT podemos crear un usuario y al mismo tiempo concederle también los privilegios que
tendrá. La sintaxis simplificada que usaremos para GRANT, es:
La primera parte priv_type [(column_list)] permite definir el tipo de privilegio concedido para
determinadas columnas. La segunda ON {tbl_name | * | *.* | db_name.*}, permite conceder
privilegios en niveles globales, de base de datos o de tablas.
Hay que tener en cuenta que la contraseña se debe introducir entre comillas de forma obligatoria.
Un usuario 'anonimo' podrá abrir una sesión MySQL mediante una orden:
C:\mysql -h localhost -u anonimo -p
Pero no podrá hacer mucho más, ya que no tiene privilegios. No tendrá, por ejemplo, oportunidad de
hacer selecciones de datos, de crear bases de datos o tablas, insertar datos, etc.
CONCEDER PRIVILEGIOS
Para que un usuario pueda hacer algo más que consultar algunas variables del sistema debe tener
algún privilegio. Lo más simple es conceder el privilegio para seleccionar datos de una tabla
concreta. Esto se haría así:
Esta sentencia concede al usuario 'anonimo' el privilegio de ejecutar sentencias SELECT sobre la
tabla 'gente' de la base de datos 'prueba'.
Un usuario que abra una sesión y se identifique como 'anonimo' podrá ejecutar estas sentencias:
mysql> SHOW DATABASES;
+-----------+
| database |
+-----------+
| prueba |
+-----------+
1 row in set (0.01 sec)
+----------------------+
1 row in set (0.00 sec)
Como se ve, para este usuario sólo existe la base de datos 'prueba' y dentro de esta, la tabla 'gente'.
Además, podrá hacer consultas sobre esa tabla, pero no podrá añadir ni modificar datos, ni por
supuesto, crear o destruir tablas ni bases de datos.
Para conceder privilegios globales se usa ON *.*, para indicar que los privilegios se conceden en
todas las tablas de todas las bases de datos.
Para conceder privilegios en bases de datos se usa ON nombre_db.*, indicando que los privilegios
se conceden sobre todas las tablas de la base de datos 'nombre_db'.
Para ver una lista de todos los privilegios existentes consultar la sintaxis de la sentencia GRANT.
Un detalle importante es que para crear usuarios se debe tener el privilegio GRANT OPTION, y que
sólo se pueden conceder privilegios que se posean.
REVOCAR PRIVILEGIOS
ON
FROM user [, user] ...
La sintaxis es similar a la de GRANT, por ejemplo, para revocar el privilegio SELECT de nuestro
usuario 'anonimo', usaremos la sentencia:
mysql> REVOKE SELECT ON prueba.gente FROM anonimo;
Podemos ver qué privilegios se han concedido a un usuario mediante la sentencia SHOW GRANTS.
La salida de esta sentencia es una lista de sentencias GRANT que se deben ejecutar para conceder los
privilegios que tiene el usuario. Por ejemplo:
mysql> SHOW GRANTS FOR anonimo;
+------------------------------------------------------------------------------------------------------+
| Grants for anonimo@% |
+------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anonimo'@'%' IDENTIFIED BY PASSWORD '*5...' |
| GRANT SELECT ON `prueba`.`gente` TO 'anonimo'@'%' |
+------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
Como podemos ver por la salida de la sentencia SHOW GRANTS, el nombre de usuario no se limita
a un nombre simple, sino que tiene dos partes. La primera consiste en un nombre de usuario, en
nuestro ejemplo 'anonimo'. La segunda parte, que aparece separada de la primera por el carácter '@'
es un nombre de máquina (host). Este nombre puede ser bien el de una máquina, por ejemplo,
'localhost' para referirse al ordenador local, o cualquier otro nombre, o bien una ip.
Si creamos un usuario para una máquina o conjunto de máquinas determinado, ese usuario no se
podrá conectar desde otras máquinas. Por ejemplo:
mysql> GRANT USAGE ON * TO anonimo@localhost IDENTIFIED BY 'clave';
Un usuario que se identifique como 'anonimo' sólo podrá entrar desde el mismo ordenador donde se
está ejecutando el servidor.
El usuario 'anonimo' sólo puede conectarse desde un ordenador cuyo IP sea '10.28.56.15'.
Aunque asignar una contraseña es opcional, por motivos de seguridad es recomendable asignar
siempre una.
La contraseña se puede escribir entre comillas simples cuando se crea un usuario, o se puede usar la
salida de la función PASSWORD() de forma literal, para evitar enviar la clave en texto legible.
Si al añadir privilegios se usa una clave diferente en la cláusula IDENTIFIED BY, sencillamente se
sustituye la contraseña por la nueva.
BORRAR USUARIOS
Para eliminar el usuario primero hay que revocar todos sus privilegios:
mysql> SHOW GRANTS FOR anonimo;
+------------------------------------------------------------------------------------------------------+
| Grants for anonimo@% |
+------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anonimo'@'%' IDENTIFIED BY PASSWORD '*5....' |
| GRANT SELECT ON `prueba`.`gente` TO 'anonimo'@'%' |
+------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
PROCEDIMIENTOS ALMACENADOS
Los procedimientos almacenados (stored procedure en inglés) y funciones son nuevas
funcionalidades de la versión de MySQL 5.0. Un procedimiento almacenado es un conjunto de
comandos SQL que pueden almacenarse en el servidor. Una vez que se hace, los clientes no
necesitan relanzar los comandos individuales pero pueden en su lugar referirse al procedimiento
almacenado.
Algunas situaciones en que los procedimientos almacenados pueden ser particularmente útiles:
Los procedimientos almacenados pueden mejorar el rendimiento ya que se necesita enviar menos
información entre el servidor y el cliente. El intercambio que hay es que aumenta la carga del
servidor de la base de datos ya que la mayoría del trabajo se realiza en la parte del servidor y no en el
cliente.
Los Procedimientos Almacenados se guardan en la propia Base de Datos aunque se pueden crear de
forma interactiva desde la propia Base de Datos o desde un gestor de aplicaciones.
Por ejemplo, el siguiente código es un Procedimiento Almacenado que inserta un registro con un
valor en función del parámetro recibido.
Delimiter //
CREATE PROCEDURE procedure1 (IN parameter1 INTEGER)
BEGIN
DECLARE variable1 CHAR(10);
IF parameter1 = 17 THEN
SET variable1 = 'birds';
ELSE
SET variable1 = 'beasts';
END IF;
INSERT INTO table1 VALUES (variable1);
END//
Delimiter ;
Este Procedimiento Almacenado lo podrías crear interactivamente mediante la versión para MySQL
5.0. Si quisieras Procedimiento Almacenado tendrías que aplicar el siguiente formato:
parameter:
[ IN | OUT | INOUT ] param_name type
La lista de parámetros entre paréntesis debe estar siempre presente. Si no hay parámetros, se debe
usar una lista de parámetros vacía ( ) . Cada parámetro es un parámetro IN por defecto, que indica
que el contenido de la variable solo es de entrada. Para especificar otro tipo de parámetro, use la
palabra clave OUT que indica que el contenido de la variable es retornado desde el procedimiento al
lugar donde fue llamado, o INOUT que indica que su contenido en de ingreso y salida al mismo
tiempo, estos indicadores se describen antes del nombre del parámetro. Especificando IN, OUT, o
INOUT sólo son validos para una PROCEDURE. El procedimiento almacenado debe de tener un
cuerpo y un final para eso usamos las etiquetas BEGIN y END
Se tiene que cambiar el delimitador (;) en la consola, ya que los procedimientos almacenados lo
utilizan para especificar el final de una instrucción, para ejemplo se utilizará //, esto se logra mediante
el comando DELIMITER //, este proceso se debe repetir para dejarlo como estaba, para ello se
utiliza el comando DELIMITER ;
DELIMITER //
CREATE PROCEDURE mysp ()
BEGIN
Proceso que desee realizar
END //
DELIMITER ;
CALL mysp();
El nombre del store procedure (Procedimiento Almacenado) puede ser en mayúsculas o minúsculas
pues no son case sensitive.
Ahora la forma de ejecutarlo es muy diferente a los manejadores como SQL Server o Sybase donde
se hacen mediante la sentencia exec, aquí se usa la sentencia call y colocando al final los paréntesis.
Sobre las sentencias que no se pueden usar dentro de un procedimiento almacenado son: CREATE
PROCEDURE, ALTER PROCEDURE, DROP PROCEDURE, CREATE FUNCTION, DROP
FUNCTION, CREATE TRIGGER, DROP TRIGGER. También el uso de “USE database” no es
permitido, ya que MySQL asume que la base de datos por default es donde se encuentra creado el
procedimiento.
Sentencia DECLARE
Este comando se usa para declarar variables locales. Para proporcionar un valor por defecto para la
variable, incluye una cláusula DEFAULT . El valor puede especificarse como expresión, no necesita
ser una constante. Si la cláusula DEFAULT no está presente, el valor inicial es NULL. La visibilidad
de una variable local es dentro del bloque BEGIN ... END donde está declarado.
El comando SET en procedimientos almacenados es una versión extendida del comando general
SET. El comando SET en procedimientos almacenados se implementa como parte de la sintaxis SET
pre-existente. Esto permite una sintaxis extendida de SET a=x, b=y, ... donde distintos tipos de
variables pueden mezclarse.
La sentencia CALL
CALL sp_nombre([parameter[,...]])
CALL puede pasar valores al llamador usando parámetros declarados como OUT o INOUT .
También “retorna” el número de registros afectados, que con un programa cliente puede obtenerse a
nivel SQL llamando la función ROW_COUNT() y desde C llamando la función de la API C
mysql_affected_rows() .
Esta sintaxis SELECT almacena columnas seleccionadas directamente en variables. Por lo tanto, sólo
un registro puede retornarse.
Sentencia IF
IF expresión THEN
-- que hacer en caso correcto
ELSE
-- que hacer en caso contrario
END IF; -- necesario para cerrar el bloque
DELIMITER //
CREATE PROCEDURE autos(IN velocidad INT, IN marca VARCHAR(50))
BEGIN
IF velocidad < 120 THEN
INSERT INTO familiares VALUES (velocidad,marca);
ELSE
INSERT INTO deportivos VALUES (velocidad,marca);
END IF;
END
//
DELIMITER;
Otro ejemplo de utilización de la instrucción de control:
delimiter //
CREATE procedure compara(IN cadena varchar(25), IN cadena2 varchar(25))
begin
IF strcmp(cadena, cadena2) = 0 then
SELECT "son iguales!";
else
SELECT "son diferentes!!";
end IF;
end;
//
delimiter ;
call compara("hola","Hola");
La sentencia CASE
CASE case_value
WHEN Coincidencia_Valor THEN lista_de_instrucciones
[WHEN Coincidencia_Valor THEN lista_de_instrucciones] ...
[ELSE lista_de_instrucciones]
END CASE
O:
CASE
WHEN condición_de_búsqueda THEN lista_de_instrucciones
Nota: La sitaxis de un comando CASE mostrado aquí para uso dentro de procedimientos almacenados
difiere ligeramente de la expresión CASE SQL. El comando CASE no puede tener una cláusula ELSE
NULL y termina con END CASE en lugar de END.
Ejemplo:
-> 'one'
mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
-> 'true'
-> NULL
Sentencia LOOP
[begin_label:] LOOP
lista_de_instrucciones
END LOOP [end_label]
LOOP implementa un constructor de bucle simple que permite ejecución repetida de comandos
particulares. El comando dentro del bucle se repite hasta que acaba el bucle, usualmente con un
comando LEAVE .
Un comando LOOP puede etiquetarse. end_label no puede darse hasta que esté presente begin_label ,
y si ambos lo están, deben ser el mismo.
Sentencia LEAVE
LEAVE label
Este comando se usa para abandonar cualquier control de flujo etiquetado. Puede usarse con BEGIN
... END o bucles.
La setencia ITERATE
ITERATE label
ITERATE sólo puede aparecer en comandos LOOP, REPEAT, y WHILE . ITERATE significa
“vuelve a hacer el bucle.”
Por ejemplo:
Sentencia REPEAT
[begin_label:] REPEAT
lista_de_instrucciones
UNTIL condición_de_búsqueda
END REPEAT [end_label]
Un comando REPEAT puede etiquetarse. end_label no puede darse a no ser que begin_label esté
presente, y si lo están, deben ser el mismo. Por ejemplo:
delimiter //
CREATE PROCEDURE dorepeat(p1 INT)
BEGIN
SET x = 0;
REPEAT SET x = x + 1; UNTIL x > p1 END REPEAT;
END
//
CALL dorepeat(1000)//
SELECT x//
+------+
|x |
+------+
| 1001 |
+------+
1 row in set (0.00 sec)
REPEAT
INSERT INTO lista VALUES(v);
SET v = v + 1;
UNTIL v >= 1
END REPEAT;
END;
//
Sentencia WHILE
[begin_label:] WHILE condición_de_búsqueda DO
lista_de_instrucciones
END WHILE [end_label]
Un comando WHILE puede etiquetarse. end_label no puede darse a no ser que begin_label también
esté presente, y si lo están, deben ser el mismo. Por ejemplo:
delimiter //
CREATE procedure p14()
BEGIN
declare v int;
SET v = 0;
while v < 5 do
INSERT INTO lista VALUES (v);
SET v = v +1 ;
end while;
END;
//
Para eliminar procedimientos almacenados se utiliza la instrucción DROP PROCEDURE, se puede
utilizar el complemento IF EXISTS para evitar errores en caso de no existir en la base de datos:
Drop procedure if exists sp_name;
FUNCIONES EN MYSQL
El format de una function es:
CREATE FUNCTION sp_name ([parameter[,...]])
RETURNS type
[characteristic ...] routine_body
La cláusula RETURNS puede especificarse sólo con FUNCTION, donde es obligatorio. Se usa para
indicar el tipo de retorno de la función, y el cuerpo de la función debe contener un comando RETURN
value. La lista de parámetros entre paréntesis debe estar siempre presente. Si no hay parámetros, se
debe usar una lista de parámetros vacía () . Cada parámetro es un parámetro IN por defecto.
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQ
L DATA in its declaration and binary logging is enabled (you *might* want to use
the less safe log_bin_trust_function_creators variable)
DELIMITER //
DROP PROCEDURE IF EXISTS micursor//
CREATE PROCEDURE micursor()
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE uid integer;
DECLARE newdate integer;
open c1;
c1_loop: LOOP
fetch c1 into uid, newdate;
IF done THEN LEAVE c1_loop; END IF;
UPDATE calendar SET timestamp=newdate WHERE id=uid;
END LOOP c1_loop;
close c1;
END //
Los cursores deben declararse antes de declarar los handlers, y las variables y condiciones deben
declararse antes de declarar cursores o handlers.
MySQL tiene sus propios códigos de error que son únicos para MySQL Server. Por ejemplo:
Un código de error SQLSTATE es definido por ANSI standard y son independientes de la base de
datos, lo que significa que deberías tener el mismo valor de error para cualquier base de datos ANSI
compatible. Por ejemplo:
Así, Oracle, SQL Server, DB2, y MySQL reportarán el mismo SQLSTATEvalue (23000) cuando hay
un error de primary key duplicada..
SET flag=0;
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET flag = 1;
INSERT INTO TABLA........;
-- Si flag=1 es porque se dio la condicion SQLSTATE '23000'
-- (23000, en realidad, engloba muchos errores de violacion)
-- Como no se ejecuto el INSERT entonces probamos con UPDATE.
IF flag = 1 THEN
UPDATE TABLA...........;
END IF;
END
Sentencia CLOSE
CLOSE nombre_de_cursor
Cierra el cursor, el cual deberá estar abierto. Un cursor abierto es cerrado automáticamente cuando el
bloque BEGIN dentro del cual está termina.
Sentencia FETCH
FETCH [[NEXT] FROM] nombre_de_cursor INTO variable [, variable2,…]
Obtiene el siguiente renglón para el cursor actual y almacena cada una de sus columnas en las
variables mencionadas. El cursor debe estar abierto. Si no está disponible ningún renglón, un error
con un valor de SQLSTATE igual a 02000 ocurre.
Sentencia OPEN
OPEN nombre_de_cursor
Abre el cursor para que pueda ser utilizado con la instrucción FETCH.
Comentarios
En las rutinas de MySQL, los comentarios pueden hacerse de tres maneras:
Empezando una línea con "#":
# Este es un comentario
Encerrando un texto entre "/*" y "*/":
/* Este es un comentario de una línea */
/* Este es un comentario
que abarca
varias líneas */
Anteponiendo a una línea dos guiones y un espacio:
--
-- Este es un comentario
--
TRIGGERS (Disparadores)
El soporte para TRIGGERS en MySQL se realizó a partir de la versión 5.0.2. Un trigger puede ser
definido para activarse en un INSERT, DELETE o UPDATE en una tabla y puede configurarse para
activarse ya sea antes o después de que se haya procesado cada renglón por el query.
Los TRIGGERS en MySQL tienen la misma limitante que las funciones. No pueden referirse a una
tabla en general. Pueden solamente referirse a un valor del renglón que está siendo modificado por el
query que se está ejecutando. Las características más importantes de los TRIGGERS son:
Puede examinar el contenido actual de un renglón antes de que sea borrado o actualizado
Puede examinar un nuevo valor para ser insertado o para actualizar un renglón de una tabla
Un BEFORE TRIGGER, puede cambiar el nuevo valor antes de que sea almacenado en la base
de datos, lo que permite realizar un filtrado de la información.
Los triggers tienen dos palabras clave, OLD y NEW que se refieren a los valores que tienen las
columnas antes y después de la modificación. Los INSERT permiten NEW, los DELETE sólo OLD y
los UPDATE ambas.
PRÁCTICA Nº 1
La Facultad de Ciencias Veterinarias necesita una base de datos que permita registrar los datos de
los animales (canes) y las vacunas aplicadas a los mismos:
Si se desea ingresar y activar la base de datos directamente, puede utilizar la siguiente instrucción:
mysql -h localhost -u root NombreBaseDatos -p
Muestra el nombre de las tablas que tengamos creadas en nuestra base de datos que estamos
utilizando en este caso no muestra nada porque no hemos creado tablas.
ShowTables;
De ésta forma queda creada la tabla llamada animal con sus atributos y su llave primaria.
describe animal;
El siguiente comando es para seleccionar la tabla de la base de datos “animal” y nos muestra los
registros la tabla animal. (El * quiere decir todas las columnas).
Select * From animal;
Sí se requiere especificar los atributos que queremos ver, como nombre y la edad de la tabla animal,
este podría ser una de las formas:
Select nombre, edad From animal;
Este comando es para seleccionar solo los nombres de la tabla animal y nos muestra todos los
nombres que tiene esa tabla.
SELECT Nombre FROM animal;
Este comando nos muestra solo los animales donde la edad sea mayor a 2
SELECT * FROM animal WHERE edad > 2;
Este comando actualiza de la tabla animal el nombre animalito donde el id sea igual a 1
UPDATE animal SET nombre = „animalito‟ WHERE IdAnimal = „1‟;
En el ejemplo, se puede ver el diccionario de datos en cada uno de los atributos, de que tipo son,
cuales permiten nulos, cuales no, la llave primaria, etc. ( el comando que muestra la estructura de la
tabla)
describe vacunas;
Este comando nos muestra los nombres de animales y sus vacunas aplicadas
SELECT animal.Nombre, vacunas.Nombre FROM animal, vacunas WHERE
animal.IdAnimal=vacunas.Id_Animal;
Este comando nos muestra lo mismo pero ordenado por el nombre de los animales
SELECT animal.Nombre, vacunas.Nombre FROM animal, vacunas WHERE
animal.IdAnimal=vacunas.Id_Animal ORDER BY animal.Nombre;
Este comando nos muestra los nombres de animales en mayúscula y sus vacunas aplicadas en
minúsculas:
SELECT UPPER(animal.Nombre), LOWER(vacunas.Nombre) FROM animal, vacunas WHERE
animal.IdAnimal=vacunas.Id_Animal;
Sí de desea utilizar condiciones para conseguir resultados personalizados usted podría aplicar la
siguiente instrucción:
SELECT Nombre, IF(edad <= 2, 'Joven', 'Adulto') as Tipo FROM animal ORDER BY edad;
Si se desea agregar un campo a la tabla “vacunas”, que registre la fecha cuando se aplicó la vacuna,
sería del siguiente modo:
ALTER TABLE vacunas ADD fecha DATE; (anexo IV para ver más ejemplos)
ALTER TABLE tabla ADD COLUMN valor INT;
Para eliminar la columna agregada:
ALTER TABLE tabla DROP COLUMN valor;
Sí se desea cambiar el nombre de una tabla, podría aplicar:
ALTER TABLE animal RENAME TO animales;
mysql> show tables;
+-------------------------+
| Tables_in_granja |
+-------------------------+
| animales |
| vacunas |
+-------------------------+
2 rows in set (0.00 sec)
Si se desea agregar fechas (Considere que el formato de las fechas en MYSQL de año/mes/día)se
tendría que realizar lo siguiente:
UPDATE vacunas SET fecha = „2012/01/01‟ WHERE IdVacuna = „1‟;
UPDATE vacunas SET fecha = „2012/02/01‟ WHERE IdVacuna = „2‟;
UPDATE vacunas SET fecha = „2012/03/25‟ WHERE IdVacuna = „3‟;
UPDATE vacunas SET fecha = „2012/04/10‟ WHERE IdVacuna = „4‟;
C:\wamp\bin\mysql\mysql5.1.36\bin>
Sí la base de datos no esta creada se la debe crear, para ello Ud. Debe ingresar a la consola y crearla:
C:\wamp\bin\mysql\mysql5.1.36\bin>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.36-community-log MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database granja;
PRÁCTICA Nº 2
La Facultad de Ciencias Veterinarias necesita una base de datos que permita registrar los datos de
los animales (canes) y las vacunas aplicadas a los mismos, necesita generar usuarios con limitaciones
para evitar problemas de seguridad:
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Usted puede notar que no muestra el contenido real de las bases de datos, sí intenta trabajar con una
base de datos, MySQL le mostrará:
MySQL le negará acceder a una base de datos, y si intenta cambiar los privilegios le mostrará el
siguiente mensaje:
Para hacer uso de la administración de usuarios es necesario entrar con el usuario que tiene todos los
privilegios:
mysql> quit;
C:\wamp\bin\mysql\mysql5.1.36\bin>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.1.36-community-log MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>_
Para crear privilegios de vistas sobre la base de datos „granja‟ y la tabla „animal‟ al usuario octavo se
debe realizar lo siguiente:
mysql> GRANT SELECT ON granja.animal TO octavo;
Volvemos a salir del usuario root, para entrar con el usuario octavo
mysql>\q;
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Si usted intenta ver el contenido de una tabla que no tiene permisos se mostrará el siguiente mensaje:
mysql> SELECT * FROM vacunas;
ERROR 1142 (42000): SELECT command denied to user 'octavo'@'localhost' for table
'vacunas'
Para que el usuario octavo pueda ver el contenido de la tabla vacunas debe ejecutar el siguiente
comando:
mysql> GRANT SELECT ON granja.* TO octavo;
mysql>\q;
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Para permitir que el usuario „octavo‟ pueda realizar procesos de actualización incluido el agregado de
nuevos registros se puede realizar lo siguiente (Considere que el usuario debe ser „root‟):
Una vez ingresado como usuario „octavo‟ usted no tendrá impedimento para realizar lo siguiente:
mysql> use granja;
Database changed
mysql> SELECT IdAnimal, animal.Nombre, vacunas.Nombre, Edad FROM animal, vacunas WHERE
animal.IdAnimal=vacunas.Id_Animal ORDER BY animal.Nombre;
+-------------+----------+---------------------+-------+
| IdAnimal | Nombre | Nombre | Edad |
+------------+-----------+---------------------+-------+
| 3 | Mechón | AntimoquilloA | 5|
| 4 | Titón | Anti rabia | 1|
| 1 | Yoyito | Antiparasitaria | 1 |
| 1 | Yoyito | AntiMoquilloB | 1 |
+------------+-----------+---------------------+-------+
4 rows in set (0.00 sec)
También se puede quitar los privilegios del usuario „octavo‟, para controlar su administración (es necesario ingresar
como usuario root para poder modificar los permisos del usuario):
mysql>\q;
C:\wamp\bin\mysql\mysql5.1.36\bin>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.1.36-community-log MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>\q;
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Para finalizar la práctica se eliminará al usuario „octavo‟, es importante que antes de eliminar a un usuario, se debe
eliminar primero sus privilegios, para realizar este proceso se debe ingresar a la consola como root:
mysql>\q;
C:\wamp\bin\mysql\mysql5.1.36\bin>mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.1.36-community-log MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Ha….! Si desea que el usuario „octavo‟ tenga todos los privilegios se tendría que realizar lo siguiente:
mysql> GRANT all ON granja.* to octavo identified by '123' with GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
PRÁCTICA Nº 3
Para poder hacer uso de los store procedures debemos contar con la versión 5.0 de MySQL. Hagamos
una pequeña demostración de ellos a continuación:
Antes que nada debemos revisar que contamos con la versión 5.0 de MySQL como mínimo, podemos
usar cualquiera de las siguientes dos formas.
Observe que el ejemplo aplica alias (AS) para especificar un nombre al resultado. Al ejecutar el
procedimiento almacenado se obtiene:
mysql> call Total_Animales();
+-------+
| Total |
+-------+
| 5 |
+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
El siguiente ejemplo, crea un procedimiento almacenado que guarda un registro en la tabla animal,
para ello se pasan 4 parámetros p_nombre, p_edad, p_raza, p_precio, no se antepone la referencia IN
ya que su aplicación es por defecto. Delimiter es utilizado para evitar problemas por el uso del punto
y coma (;) en el procedimiento almacenado.
mysql> delimiter //
mysql> CREATE PROCEDURE Agrega_Animal (p_nombre tinytext, p_edad int(2), p_raza
varchar(20), p_precio int(7))
BEGIN
Insert into animal(Nombre,Edad,Raza,Precio)values(p_nombre, p_edad, p_raza, p_precio);
END
//
Query OK, 0 rows affected (0.08 sec)
mysql> delimiter ;
También se puede aplicar un procedimiento almacenado que mezcle varias instrucciones sql y
obtener varios resultados, como por ejemplo agregar un registro y mostrar un resultado:
mysql> delimiter //
mysql> CREATE PROCEDURE Agrega_Animal_contador (p_nombre tinytext, p_edad int(2),
p_raza varchar(20), p_precio int(7))
BEGIN
DECLARE Total INT;
Insert into animal(Nombre,Edad,Raza,Precio)values(p_nombre, p_edad, p_raza, p_precio);
SELECT COUNT(*) as Total_Ingresados FROM Animal INTO Total;
SELECT Total;
END
//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter;
Sí observa la primera instrucción SELECT, notará que al final, incluye el resultado a la variable
Total, el resultado es mostrado por una segunda instrucción Select.
END
//
DELIMITER ;
En la aplicación de este procedimiento almacenado, busca todos los animales cuyo nombre empieza
con la letra “c”, además se utiliza la variable @candidad para extraer el total de nombres que
empiezan con “C”
CALL Busca_Amimal('c%', @cantidad);
+----------+-----------+------+----------------+--------+
| IdAnimal | Nombre | Edad | Raza | Precio |
+----------+-----------+------+----------------+--------+
| 6 | Chiquita | 2 | Lova Siveriana | 800 |
| 7 | Chilito | 3 | Chiguagua | 500 |
| 8 | Chocolate | 3 | Chiguagua | 500 |
+----------+-----------+------+----------------+--------+
3 rows in set (0.03 sec)
APLICACIÓN DE FUNCIONES:
Suponiendo que usted desea mostrar la lista de animales y las fechas de las vacunas aplicadas con el
formato “dia/mes/año”:
Primero se creará la función:
delimiter //
CREATE FUNCTION fecha_db(fech DATETIME) RETURNS char(14)
BEGIN
RETURN date_format(fech,‟%d/%m/%Y‟);
END
//
delimiter ;
Después aplica la instrucción SQL utilizando la función:
SELECT IdAnimal, animal.Nombre, vacunas.Nombre As Vacuna, fecha_db(vacunas.fecha) FROM animal, vacunas
WHERE animal.IdAnimal=vacunas.Id_Animal ORDER BY animal.Nombre;
+------------+----------+-------------------+-------------------------------+
| IdAnimal | Nombre | Vacuna | fecha_db(vacunas.fecha) |
+------------+----------+-------------------+------------------------------+
| 9 | KuKy | retroviral | 12/05/2012 |
| 3 | Mechón | AntimoquilloA | 01/02/2012 |
| 5 | Sombra | retroviral | 12/05/2012 |
| 5 | Sombra | Antirabica | 12/05/2012 |
| 4 | Titón | Anti rabia | 10/04/2012 |
| 4 | Titón | Antirabica | 12/05/2012 |
| 1 | Yoyito | Antiparasitaria | 01/01/2012 |
| 1 | Yoyito | AntiMoquilloB | 25/03/2012 |
+------------+--------+-----------------------+----------------------------+
Sí se desea realizar algo más especializado, con detalles como nombre del mes y nombres de días de
semana, entonces podríamos realizar algo así:
DELIMITER //
CREATE FUNCTION Fechadetalle(fecha DATETIME) RETURNS varchar(150)
BEGIN
DECLARE dia INT;
DECLARE mes INT;
DECLARE dia_s VARCHAR(20);
DECLARE mes_s VARCHAR(20);
DECLARE fecha_f VARCHAR(150);
SET dia = DAYOFWEEK(fecha);
delimiter;
Ejemplo Nº1 de uso de cursores en mysql, se trata de un procedimiento almacenado que almacena los datos de la tabla
VACUNAS aplicados a los canes registrados en la tabla ANIMAL, para eso se pasa el nombre del animal y se busca
su “IdAnimal” en la tabla ANIMAL para almacenarlo en la tabla VACUNAS, este cursor utiliza SQLSTATE para
controlar el recorrido del cursor:
delimiter //
CREATE PROCEDURE RegistraVacuna(pNombreAnimal tinytext, pNombreVacuna tinytext, pfecha date)
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE id integer;
DECLARE nomb tinytext;
DECLARE c1 cursor for SELECT idanimal, nombre from animal ORDER BY idanimal ASC;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
open c1;
c1_loop: LOOP
FETCH c1 INTO id, nomb;
IF done THEN LEAVE c1_loop; END IF;
IF strcmp(nomb,pNombreAnimal) = 0 THEN
INSERT INTO vacunas (Nombre,Id_Animal,fecha) VALUES (pNombreVacuna, id , pfecha);
END IF;
END LOOP c1_loop;
close c1;
END //
delimiter ;
Ejemplo Nº 2 de uso de cursores en mysql, se trata de un procedimiento almacenado que almacena los datos de la tabla
VACUNAS aplicados a los canes registrados en la tabla ANIMAL, para eso se pasa el nombre del animal y se busca
su “IdAnimal” en la tabla ANIMAL para almacenarlo en la tabla VACUNAS, este cursor utiliza FOR NOT FOUND
para controlar el recorrido del cursor:
delimiter //
CREATE PROCEDURE RegistraVacuna2(pNombreAnimal tinytext, pNombreVacuna tinytext, pfecha date)
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE id integer;
DECLARE nomb tinytext;
DECLARE c1 cursor for SELECT idanimal, nombre From animal ORDER BY idanimal ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open c1;
c1_loop: LOOP
FETCH c1 INTO id,nomb;
IF done THEN LEAVE c1_loop; END IF;
if strcmp(nomb,pNombreAnimal) = 0 then
INSERT INTO vacunas (Nombre, Id_Animal, fecha) VALUES (pNombreVacuna, id, pfecha);
end if;
END LOOP c1_loop;
close c1;
END //
delimiter ;
Ejemplo Nº 3
delimiter //
CREATE PROCEDURE RegistraVacuna3(pNombreAnimal tinytext, pNombreVacuna tinytext, pfecha date)
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE id integer;
DECLARE nomb tinytext;
DECLARE c1 cursor for SELECT idanimal, nombre from animal ORDER BY idanimal ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open c1;
REPEAT
FETCH c1 INTO id,nomb;
if strcmp(nomb,pNombreAnimal)=0 then
INSERT INTO vacunas (Nombre,Id_Animal,fecha) VALUES (pNombreVacuna, id, pfecha);
end if;
UNTIL done END REPEAT;
close c1;
END //
delimiter ;
ANEXO I
TIPOS DE DATOS DE MYSQL
Después de la fase de diseño de una base de datos, en necesario crear las tablas correspondientes
dentro de la base de datos. Para cada campo de cada una de las tablas, es necesario determinar el tipo
de datos que contiene, para de esa forma ajustar el diseño de la base de datos, y conseguir un
almacenamiento óptimo con la menor utilización de espacio. El presente artículo describe cada uno
de los tipos de datos que puede tener un campo en Mysql.
Los tipos de datos que puede haber en un campo, se pueden agrupar en tres grandes grupos:
Existen tipos de datos numéricos, que se pueden dividir en dos grandes grupos, los que están en coma
flotante (con decimales) y los que no.
TinyInt: es un número entero con o sin signo. Con signo el rango de valores válidos va desde -128 a
127. Sin signo, el rango de valores es de 0 a 255
Bit ó Bool: un número entero que puede ser 0 ó 1
SmallInt: número entero con o sin signo. Con signo el rango de valores va desde -32768 a 32767.
Sin signo, el rango de valores es de 0 a 65535.
MediumInt: número entero con o sin signo. Con signo el rango de valores va desde -8.388.608 a
8.388.607. Sin signo el rango va desde 0 a16777215.
Integer, Int: número entero con o sin signo. Con signo el rango de valores va desde -2147483648 a
2147483647. Sin signo el rango va desde 0 a 429.4967.295
BigInt: número entero con o sin signo. Con signo el rango de valores va desde -
9.223.372.036.854.775.808 a 9.223.372.036.854.775.807. Sin signo el rango va desde 0 a
18.446.744.073.709.551.615.
Float: número pequeño en coma flotante de precisión simple. Los valores válidos van desde -
3.402823466E+38 a -1.175494351E-38, 0 y desde 1.175494351E-38 a 3.402823466E+38.
xReal, Double: número en coma flotante de precisión doble. Los valores permitidos van desde -
1.7976931348623157E+308 a -2.2250738585072014E-308, 0 y desde 2.2250738585072014E-308 a
1.7976931348623157E+308
Decimal, Dec, Numeric: Número en coma flotante desempaquetado. El número se almacena como
una cadena
Tamaño de
Tipo de Campo
Almacenamiento
TINYINT 1 byte
SMALLINT 2 bytes
MEDIUMINT 3 bytes
INT 4 bytes
INTEGER 4 bytes
BIGINT 8 bytes
FLOAT(X) 4 ú 8 bytes
FLOAT 4 bytes
DOUBLE 8 bytes
DOUBLE
8 bytes
PRECISION
REAL 8 bytes
M+2 bytes sí D > 0, M+1
DECIMAL(M,D
bytes sí D = 0
M+2 bytes if D > 0, M+1
NUMERIC(M,D)
bytes if D = 0
A la hora de almacenar fechas, hay que tener en cuenta que Mysql no comprueba de una manera
estricta si una fecha es válida o no. Simplemente comprueba que el mes esta comprendido entre 0 y
12 y que el día esta comprendido entre 0 y 31.
Date: tipo fecha, almacena una fecha. El rango de valores va desde el 1 de enero del 1001 al 31 de
diciembre de 9999. El formato de almacenamiento es de año-mes-dia
DateTime: Combinación de fecha y hora. El rango de valores va desde el 1 de enero del 1001 a las 0
horas, 0 minutos y 0 segundos al 31 de diciembre del 9999 a las 23 horas, 59 minutos y 59 segundos.
El formato de almacenamiento es de año-mes-dia horas:minutos:segundos
TimeStamp: Combinación de fecha y hora. El rango va desde el 1 de enero de 1970 al año 2037. El
formato de almacenamiento depende del tamaño del campo:
Tamaño Formato
AñoMesDiaHoraMinutoSegundo
14
aaaammddhhmmss
AñoMesDiaHoraMinutoSegundo
12
aammddhhmmss
8 ñoMesDia aaaammdd
6 AñoMesDia aammdd
4 AñoMes aamm
2 Año aa
Time: almacena una hora. El rango de horas va desde -838 horas, 59 minutos y 59 segundos a 838,
59 minutos y 59 segundos. El formato de almacenamiento es de 'HH:MM:SS'
Year: almacena un año. El rango de valores permitidos va desde el año 1901 al año 2155. El campo
puede tener tamaño dos o tamaño 4 dependiendo de si queremos almacenar el año con dos o cuatro
dígitos.
Tamaño de
Tipo de Campo
Almacenamiento
DATE 3 bytes
DATETIME 8 bytes
TIMESTAMP 4 bytes
TIME 3 bytes
YEAR 1 byte
Char(n): almacena una cadena de longitud fija. La cadena podrá contener desde 0 a 255 caracteres.
VarChar(n): almacena una cadena de longitud variable. La cadena podrá contener desde 0 a 255
caracteres.
Dentro de los tipos de cadena se pueden distinguir otros dos subtipos, los tipo Test y los tipo BLOB
(Binary large Object)
La diferencia entre un tipo y otro es el tratamiento que reciben a la hora de realizar ordenamientos y
comparaciones. Mientras que el tipo test se ordena sin tener en cuenta las Mayúsculas y las
minúsculas, el tipo BLOB se ordena teniéndolas en cuenta.
Los tipos BLOB se utilizan para almacenar datos binarios como pueden ser ficheros.
LongBlob y LongText: un texto con un máximo de caracteres 4.294.967.295. Hay que tener en
cuenta que debido a los protocolos de comunicación los paquetes pueden tener un máximo de 16 Mb.
Enum: campo que puede tener un único valor de una lista que se especifica. El tipo Enum acepta
hasta 65535 valores distintos
Set: un campo que puede contener ninguno, uno ó varios valores de una lista. La lista puede tener un
máximo de 64 valores.
Almace Almace
Valor CHAR(4) VARCHAR(4)
namiento namiento
'' '' 4 bytes " 1 byte
'ab' 'ab ' 4 bytes 'ab' 3 bytes
'abcd' 'abcd' 4 bytes 'abcd'
'abcdefgh' 'abcd' 4 bytes 'abcd' 5 bytes
ANEXO II
DESDE LA CONSOLA MYSQL
Operaciones básicas
Operación Comando
Entrar a la consola de MySQL mysql
Entrar a la consola de MySQL mysql -u usuario -p
como el usuario usuario
Salir de la consola de MySQL \q
Ayuda de la consola (hay que estar \help o \h
en ella)
Operación Comando
Crear base de datos create database basededatos ;
Eliminar base de datos drop database basededatos ;
Mostrar las bases de datos show databases ;
disponibles
Trabajar sobre con una base de use basededatos ;
datos
Operación Comando
Mostrar tablas de la BD show tables from basededatos ;
Muestra los campos de la tabla show columns from tabla ; o describe tabla ;
Crear tabla create table nombretabla (columna1 tipodato, columna2
tipodato...) ;
Crear tabla temporal create temporary table nombretabla (columna1 tipodato);
Crear tabla verificando que no create table inf not exists nombretabla (columna1 tipodato,
existe columna2 tipodato...) ;
Eliminar tabla drop table nombretabla ;
Editar tabla alter table nombretabla operacion ;
Cambiar nombre a tabla alter table nombretablaviejo rename nombretablanuevo;
Bloquea tabla lock nombretabla1, nombretabla2... ;
Desbloquea tabla unlock nombretabla1 READ|WRITE, nombretabla2
READ|WRITE... ;
- -
Operación Comando
Añadir columna alter table nombretabla ADD nombrecolumna tipodato;
Cambia el tipo de dato de la alter table nombretabla change nombrecolumna nombrecolumna
columna nuevotipodato;
Cambiar el nombre de la alter table nombretabla change nombrecolumnaviejo
columna nombrecolumnanuevo tipodato;
Operación Comando
Insertar nuevo dato en tabla insert into nombretabla values
(valorcampo1,'valorcampo2',valorcampo3...);
Importar archivo de datos a tabla load data infile 'archivo.txt' into table nombretabla;
Seleccionar datos de una tabla select nombrecampo1, nombrecampo2... from nombretabla
where condición
Borrar todos los datos de una tabla delete from nombretabla;
(conserva la tabla con sus campos)
Actualizar un dato del campo1 update nombretabla SET nombrecampo1='nuevovalorcampo'
WHERE nombrecampo2='valorcampo2';
Contar registros que cumplen un select count(campos) from nombretabla;
criterio
Operación Comando
Crear índice create index nombreindice on
nombretabla(listanombrescolumnas);
Elimina índice drop index indexname on tablename; o alter table nombretabla
drop index nombreindice;
Mostrar claves show keys from nombretabla ; o show index from
nombretabla;
ANEXO III
Podemos instalar MySQL como origen de datos de sistema ODBC para, por ejemplo, conectar a las
bases de datos de manera remota.
Para ello necesitamos añadir esa base de datos al DSN del sistema.
ANEXO IV
REFERENCIA DE USO DE 'ALTER TABLE' EN MYSQL
SOBRE LA TABLA
ANEXO IV
FUNCIONES
Si consideramos que MySQL es rico en lo que respecta a operadores, en lo que se refiere a
funciones, podemos considerarlo millonario. MySQL dispone de multitud de funciones.
Pero no las explicaremos aquí, ya que este curso incluye una referencia completa. Tan sólo las
agruparemos por tipos, e incluiremos los enlaces correspondientes a la documentación de cada una.
FUNCIONES MATEMÁTICAS
FUNCIONES DE CADENAS
Además de los operadores que vimos para la comparación de cadenas, existe una función:
FUNCIONES DE FECHA
DE BÚSQUEDA DE TEXTO
MATCH
MISCELANEA
Funciones generales:
DE GRUPOS
Funciones de grupos:
ANEXO V
EJEMPLOS DE USO DE mysqldump
Respaldo de una sola base de datos completa
mysqldump clientes > clientes.sql
Respaldamos la base de datos clientes pero ignoramos las tablas 'temporal' y 'basura' (Obligatorio
indicar base.tabla)
mysqldump clientes --ignore-table=clientes.temporal --ignore-table=clientes.basura > respaldo_clientes_2011.sql
Si se tiene contraseña (como debe ser) se indica usuario y que pregunte por el password
mysqldump -u root -p --all-databases > respaldo_full_sep_2011.sql
No muy buena idea, pero se puede indicar el password directamente, además nos aseguramos que se
indiquen las opciones por defecto más comunes
mysqldump -u root -psecreto --all-databases --opt > respaldo_full_sep_2011.sql
Respaldo de una base de datos transaccional tipo InnoDB o BDB asegurando su consistencia
mysqldump -u root -p --single-transaction --quick ventas > respaldo_ventas_2011.sql
Todas las bases de datos del host 192.168.0.100 y agregamos los procedemientos almacenados que
sean respaldados también.
mysqldump -h 192.168.1.100 -u root -p --routines --all-databases > respaldo_ventas_2011.sql
Para descomprimir lo anterior y dejar el archivo listo para la restauración en si utiliza gunzip
gunzip respaldo_2011.sql.gz
RESTAURANDO EL RESPALDO
Hay varias maneras de lograr la restauración del respaldo. Con el comando mysql:
mysql -u root -p < respaldo.sql
Si se utilizó gzip para comprimir el respaldo, se puede descomprimir y restaurar en una sola línea:
gunzip < respaldo.sql.gz | mysql -u root -p
Si el respaldo contiene una sola base de datos y no contiene sentencias 'drop database' y 'create
database', se puede entonces indicar la base de datos donde se debe realizar la restauración:
mysql -u root -p clientes < respaldo_clientes.sql
Lo anterior (cuando ya existe la base de datos) también se puede lograr con el comando mysqlimport
mysqlimport -u root -p clientes respaldo_clientes.sql
Es posible también utilizar la opción "-e" (execute) de mysql, que permite ejecutar un archivo con
sentencias SQL, y un respaldo es exactamente eso, un largo script con sentencias SQL para recrear
esquema y datos:
mysql -u root -p -e "source /ruta/a/respaldo.sql"
Anexo VI
SQLSTATE vs códigos de error MySQL
En teoría es mejor utilizar codigos SQLSTATE porque son independientes de la plataforma y hacen a
nuestro código más portable. Sin embargo, hay algunas razones para utilizar el código de error de
MySQL, específicamente en la escritura de Stored Procedures.
Código de
Código
error Mensaje de error
SQLSTATE
MySQL
1011 HY000 Error on delete of „%s‟ (errno: %d)
Disk full (%s); waiting for someone to free some space
1021 HY000
...
1022 23000 Can‟t write; duplicate key in table „%s‟
1027 HY000 „%s‟ is locked against change
1036 HY000 Table „%s‟ is read only
1048 23000 Column „%s‟ cannot be null
1062 23000 Duplicate entry „%s‟ for key %d
Table „%s‟ was locked with a READ lock and can‟t be
1099 HY000
updated
1100 HY000 Table „%s‟ was not locked with LOCK TABLES
The SELECT would examine more than
MAX_JOIN_SIZE rows; check your WHERE and use
SET SQL_BIG_SELECTS=1 or SET
1104 42000
SQL_MAX_JOIN_WHERE and use SET
SQL_BIG_SELECTS=1 or SET
SQL_MAX_JOIN_SIZE=# if the SELECT is okay
1106 42000 Incorrect parameters to procedure „%s‟
1114 HY000 The table „%s‟ is full
Delayed insert thread couldn‟t get requested lock for
1150 HY000
table %s
INSERT DELAYEDcan‟t be used with table „%s‟
1165 HY000
because it is locked withLOCK TABLES
1242 21000 Subquery returns more than 1 row
ANEXO VII
Posibilidades de utilizar los permisos de usuarios en MySQL
Permiso Significado
CREATE TEMPORARY
Permite el uso de CREATE TEMPORARY TABLE
TABLES
Permite el uso de CREATE USER, DROP USER, RENAME USER, y REVOKE ALL
CREATE USER
PRIVILEGES.
FILE Permite el uso de SELECT ... INTO OUTFILE y LOAD DATA INFILE
LOCK TABLES Permite el uso de LOCK TABLES en tablas para las que tenga el permiso SELECT
REFERENCES No implementado
REPLICATION
Permite al usuario preguntar dónde están los servidores maestro o esclavo
CLIENT
REPLICATION Necesario para los esclavos de replicación (para leer eventos del log binario desde el
SLAVE maestro)
Permite el uso de comandos CHANGE MASTER, KILL, PURGE MASTER LOGS, and SET
SUPER GLOBAL , el comando mysqladmin debug le permite conectar (una vez) incluso si se
llega a max_connections
Es recomendable renombrar la cuenta del administrador de MySQL (root). De esta forma estaremos
disminuyendo la posibilidad de éxito de un ataque de fuerza bruta contra la contraseña del administrador.
Para ello deberemos ejecutar: