Resumen BD

1.- Modelo E/R ¿Cómo? Pensando y en papel o papel digital

https://trifulcas.com/introduccion-bd-relacionales/

Modelo Entidad relación

Conceptualizar datos del mundo real

Entidades: Son aquellos objetos de los que necesitamos almacenar alguna información. Ejemplo: Cliente, venta, alumno, empresa…
¿Cómo identificamos las entidades? El que pide la BD nos tiene que dar esta información. Los datos ya existen.

Relaciones entre las entidades.
1) Si hay o no hay relación
2) Tipo de relación

1)
Saber si hay o no relación tenemos que pensar si entre dos entidades hay una relación directa o por el contrario hay una relación pero a través de otra entidad.
Alumnos — Cursos — Profesores
¿Alumnos — Profesores? NO

2) 1-1, 1-n, n-n ¿Cómo lo sabemos? Preguntando.
¿De cuantos se puede matricular un alumno? N
¿De cuantos alumnos de compone un curso? N
Alumnos (N)—(N) Cursos
¿Cuantos cursos puede dar un profesor? N
¿Un curso cuantos profesores lo imparten? 1
Cursos (N) —(1) Profesores

Atributos de cada entidad: La información necesaria de cada una de las entidades. Ojo porque hay atributos que no están en la entidad sino en la relación.
Ej: Nota de alumno no está ni en el alumno ni en el curso, está en la relación.

Todo esto me devuelve un modelo de datos en papel o dibujo digital o incluso en un texto
Alumnos (N)–(N) Cursos (N)–(1) Profesores

Alumno: Nombre, dni, email, dirección
Curso: Nombre, créditos, precio
Profesor: Nombre, DNI, dirección
Alumno-Curso: Nota

2.- Pasar el modelo ER al modelo lógico
Teníamos unas reglas:https://trifulcas.com/reglas-para-la-transformacion-del-modelo-e-r-al-modelo-logico/

3.- Tipos de datos: varchar tamaño, tipos numéricos, ojo con los decimales. Cuidado con los campos que parecen números y no lo son…

https://trifulcas.com/tipos-de-datos-en-mysql/

4.- Implementar la base de datos.
a) Workbench
b) PHPMyAdmin
c) DDL (create table….)

5.- Implementar las foreignkeys para asegurar la integridad referencial. Si queremos añadir algún índice también. Recordad que toda foreign key debería tener un índice.

https://trifulcas.com/enlaces-sobre-indices/

6.- CRUD
INSERT, UPDATE y DELETE Cuidadito con esto. UPDATE y DELETE siempre con WHERE

https://trifulcas.com/sql-sentencias-creacion-de-datos-ddl/

7.- SELECT: WHERE condiciones para la selección de registros. AND OR y NOT
Operadores: <,>,=,<>, !=, LIKE, BETWEEN, IN

https://www.w3schools.com/sql/sql_like.asp

not
and
or

condicion1 and condicion2 or condicion3
1.- Evalua condicion1 and condicion2
2.- El resultado se evalua or condicion3

cond1 cond2 cond3 res
true true true true
true true false true
true false true true
true false false false
false true true true
false true false false
false false true true
false false false false

https://www.mysqltutorial.org/mysql-where/

https://es.wikipedia.org/wiki/Tabla_de_verdad

8.- JOIN Si nuestra BD es relacional, debemos relacionar las tablas. Utilizamos JOIN ¿Cómo? Miro que información me piden, busco las tablas que la contengan y creo el camino con JOIN desde una tabla a otra. OJO las claves.

9.- LEFT y RIGHT JOIN cuando necesito datos que no tienen registros relacionados. Siempre apuntando a la tabla de la que quiero todos los registros.

10.- Consultas agrupadas: GROUP BY. Nos permite utilizar funciones de agregado por los valores de un campo. COUNT, SUM, AVG, MIN, MAX. No nos olvidemos agrupar por el campo ‘id’ y no por valores como ‘nombre’ que pueden repetirse.

https://trifulcas.com/ejemplos-subconsultas/

11.- Mysql tiene funciones para manipular los datos de los campos tanto para verlos como para utilizarson en una condición. Matemáticas, de cadena, de fecha,….

https://trifulcas.com/ejemplos-funciones-mysql/

12. Subconsultas

utilizar consultas dentro de la condición de una consulta.

https://trifulcas.com/subconsultas/

Ejercicio datos geográficos

Con la colección que se adjunta al final, realizar las siguientes operaciones:

Encontrar la ciudad que tiene una población (‘pop’) mayor de 40000
Encontrar las ciudades que tienen en ‘loc’ un valor entre 37 y 42. Puede ser cualquier valor pero ese valor tiene que cumplir las dos condiciones
Encontrar las ciudades de ‘LA’ con una población menor de 10000 habitantes
Encontrar las ciudades con una población menor de 1000 habitantes pero sólo mostrar la ciudad y el estado
Modificar la ciudad ‘CUSHMAN’ y ponerle una población de 37231 habitantes.
Modificar las ciudades de ‘LA’ con menos de 1000 habitantes y ponerles en el estado ‘##’
Eliminar las ciudades con menos de 500 habitantes.

db.ciudades.insertMany([{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" },
{ "_id" : "01005", "city" : "BARRE", "loc" : [ -72.10835400000001, 42.409698 ], "pop" : 4546, "state" : "MA" },
{ "_id" : "01007", "city" : "BELCHERTOWN", "loc" : [ -72.41095300000001, 42.275103 ], "pop" : 10579, "state" : "MA" },
{ "_id" : "01008", "city" : "BLANDFORD", "loc" : [ -72.936114, 42.182949 ], "pop" : 1240, "state" : "MA" },
{ "_id" : "01010", "city" : "BRIMFIELD", "loc" : [ -72.188455, 42.116543 ], "pop" : 3706, "state" : "MA" },
{ "_id" : "01011", "city" : "CHESTER", "loc" : [ -72.988761, 42.279421 ], "pop" : 1688, "state" : "MA" },
{ "_id" : "01012", "city" : "CHESTERFIELD", "loc" : [ -72.833309, 42.38167 ], "pop" : 177, "state" : "MA" },
{ "_id" : "01013", "city" : "CHICOPEE", "loc" : [ -72.607962, 42.162046 ], "pop" : 23396, "state" : "MA" },
{ "_id" : "29372", "city" : "PACOLET", "loc" : [ -81.758703, 34.901708 ], "pop" : 4129, "state" : "SC" },
{ "_id" : "29374", "city" : "GLENN SPRINGS", "loc" : [ -81.85785300000001, 34.774808 ], "pop" : 4588, "state" : "SC" },
{ "_id" : "29376", "city" : "ROEBUCK", "loc" : [ -81.95255, 34.8688 ], "pop" : 5009, "state" : "SC" },
{ "_id" : "29379", "city" : "UNION", "loc" : [ -81.62023499999999, 34.726855 ], "pop" : 22553, "state" : "SC" },
{ "_id" : "29384", "city" : "WATERLOO", "loc" : [ -82.087968, 34.33673 ], "pop" : 2992, "state" : "SC" },
{ "_id" : "29385", "city" : "WELLFORD", "loc" : [ -82.09270600000001, 34.951394 ], "pop" : 6637, "state" : "SC" },
{ "_id" : "29388", "city" : "WOODRUFF", "loc" : [ -82.044658, 34.757864 ], "pop" : 10206, "state" : "SC" },
{ "_id" : "29401", "city" : "CHARLESTON", "loc" : [ -79.93706899999999, 32.779506 ], "pop" : 12475, "state" : "SC" },
{ "_id" : "29403", "city" : "CHARLESTON", "loc" : [ -79.94928299999999, 32.797575 ], "pop" : 24620, "state" : "SC" },
{ "_id" : "29404", "city" : "CHARLESTON", "loc" : [ -80.06768700000001, 32.895816 ], "pop" : 5420, "state" : "SC" },
{ "_id" : "29405", "city" : "CHARLESTON", "loc" : [ -79.97644200000001, 32.851206 ], "pop" : 30621, "state" : "SC" },
{ "_id" : "30136", "city" : "DULUTH", "loc" : [ -84.15793600000001, 33.98619 ], "pop" : 30932, "state" : "GA" },
{ "_id" : "30137", "city" : "EMERSON", "loc" : [ -84.75704500000001, 34.119969 ], "pop" : 1353, "state" : "GA" },
{ "_id" : "30139", "city" : "FAIRMOUNT", "loc" : [ -84.76687800000001, 34.465241 ], "pop" : 3405, "state" : "GA" },
{ "_id" : "30140", "city" : "FELTON", "loc" : [ -85.220781, 33.887066 ], "pop" : 489, "state" : "GA" },
{ "_id" : "30141", "city" : "HIRAM", "loc" : [ -84.769875, 33.867286 ], "pop" : 6613, "state" : "GA" },
{ "_id" : "30143", "city" : "JASPER", "loc" : [ -84.475881, 34.461965 ], "pop" : 8256, "state" : "GA" },
{ "_id" : "30144", "city" : "KENNESAW", "loc" : [ -84.60466, 34.028656 ], "pop" : 37120, "state" : "GA" },
{ "_id" : "30145", "city" : "KINGSTON", "loc" : [ -84.997299, 34.250053 ], "pop" : 2534, "state" : "GA" },
{ "_id" : "35089", "city" : "KELLYTON", "loc" : [ -86.04839699999999, 32.979068 ], "pop" : 1584, "state" : "AL" },
{ "_id" : "35091", "city" : "KIMBERLY", "loc" : [ -86.80841700000001, 33.768355 ], "pop" : 1045, "state" : "AL" },
{ "_id" : "35094", "city" : "LEEDS", "loc" : [ -86.57482400000001, 33.528333 ], "pop" : 10421, "state" : "AL" },
{ "_id" : "35096", "city" : "LINCOLN", "loc" : [ -86.111152, 33.605913 ], "pop" : 5033, "state" : "AL" },
{ "_id" : "35098", "city" : "LOGAN", "loc" : [ -87.038115, 34.184079 ], "pop" : 2379, "state" : "AL" },
{ "_id" : "35111", "city" : "MC CALLA", "loc" : [ -87.102379, 33.284546 ], "pop" : 8147, "state" : "AL" },
{ "_id" : "35114", "city" : "MAYLENE", "loc" : [ -86.87274499999999, 33.231694 ], "pop" : 3727, "state" : "AL" },
{ "_id" : "47124", "city" : "GREENVILLE", "loc" : [ -86.00829899999999, 38.353533 ], "pop" : 1162, "state" : "IN" },
{ "_id" : "47125", "city" : "HARDINSBURG", "loc" : [ -86.317983, 38.462599 ], "pop" : 2496, "state" : "IN" },
{ "_id" : "47126", "city" : "HENRYVILLE", "loc" : [ -85.773403, 38.539829 ], "pop" : 2648, "state" : "IN" },
{ "_id" : "47129", "city" : "CLARKSVILLE", "loc" : [ -85.524438, 38.537273 ], "pop" : 379, "state" : "IN" },
{ "_id" : "47130", "city" : "JEFFERSONVILLE", "loc" : [ -85.735885, 38.307767 ], "pop" : 56543, "state" : "IN" },
{ "_id" : "71060", "city" : "MOORINGSPORT", "loc" : [ -93.973018, 32.66258 ], "pop" : 2838, "state" : "LA" },
{ "_id" : "71061", "city" : "OIL CITY", "loc" : [ -93.983844, 32.745107 ], "pop" : 1874, "state" : "LA" },
{ "_id" : "71063", "city" : "PELICAN", "loc" : [ -93.563361, 31.896563 ], "pop" : 998, "state" : "LA" },
{ "_id" : "71064", "city" : "PLAIN DEALING", "loc" : [ -93.690534, 32.907419 ], "pop" : 4904, "state" : "LA" },
{ "_id" : "71065", "city" : "PLEASANT HILL", "loc" : [ -93.513594, 31.808577 ], "pop" : 1338, "state" : "LA" },
{ "_id" : "71862", "city" : "WASHINGTON", "loc" : [ -93.673529, 33.754596 ], "pop" : 821, "state" : "AR" },
{ "_id" : "71864", "city" : "WILLISVILLE", "loc" : [ -93.31211999999999, 33.484731 ], "pop" : 888, "state" : "AR" },
{ "_id" : "71865", "city" : "WILTON", "loc" : [ -94.135746, 33.734794 ], "pop" : 983, "state" : "AR" },
{ "_id" : "71866", "city" : "WINTHROP", "loc" : [ -94.395174, 33.858321 ], "pop" : 950, "state" : "AR" },
{ "_id" : "71901", "city" : "LAKE CATHERINE", "loc" : [ -93.02602400000001, 34.501475 ], "pop" : 27402, "state" : "AR" },
{ "_id" : "71909", "city" : "HOT SPRINGS VILL", "loc" : [ -93.00638600000001, 34.65862 ], "pop" : 8268, "state" : "AR" }])

Ejercicios sobre teléfonos

Buscar los que tengan un ‘rating’ mayor de 10
Buscar los que tengan la propiedad color
Buscar los que sean para (‘for’) ‘ac3’
Buscar los que en la propiedad ‘n’ de ‘data’ de ‘limits’ sea ‘unlimited’

Modificar el teléfono “”AC3 Case Black” y ponerle un ‘price’ de 15
Modificar los teléfonos que tengan ‘term_year’ a 1 y ponerle un monthly_price de 80
Eliminar los teléfonos que tengan un rating menor de dos

Mini ejercicio

Con los datos del mongodb:

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);

Buscar los documentos que tengan en dim_cm un valor entre 10 y 15

Ejercicio MongoDB

Vamos a crear una base de datos llamada tienda.

Y dentro de la tienda vamos a crear una colección teléfonos.

Insertaremos los siguientes datos:


[{"name" : "AC3 Phone", "brand" : "ACME", "type" : "phone", "price" : 200, "rating" : 3.8,"warranty_years" : 1, "available" : true },
{  "name" : "AC7 Phone", "brand" : "ACME", "type" : "phone", "price" : 320, "rating" : 4,"warranty_years" : 1, "available" : false },
{  "name" : "AC3 Series Charger", "type" : [ "accessory", "charger" ], "price" : 19, "rating" : 2.8,"warranty_years" : 0.25, "for" : [ "ac3", "ac7", "ac9" ] },
{  "name" : "AC3 Case Green", "type" : [ "accessory", "case" ], "color" : "green", "price" : 12, "rating" : 1,"warranty_years" : 0 },
{  "name" : "Phone Extended Warranty", "type" : "warranty", "price" : 38, "rating" : 5,"warranty_years" : 2, "for" : [ "ac3", "ac7", "ac9", "qp7", "qp8", "qp9" ] },
{  "name" : "AC3 Case Black", "type" : [ "accessory", "case" ], "color" : "black", "price" : 12.5, "rating" : 2,"warranty_years" : 0.25, "available" : false, "for" : "ac3" },
{  "name" : "AC3 Case Red", "type" : [ "accessory", "case" ], "color" : "red", "price" : 12, "rating" : 4,"warranty_years" : 0.25, "available" : true, "for" : "ac3" },
{ "name" : "Phone Service Basic Plan", "type" : "service", "monthly_price" : 40,"rating" : 3, "limits" : { "voice" : { "units" : "minutes", "n" : 400, "over_rate" : 0.05 }, "data" : { "units" : "gigabytes", "n" : 20, "over_rate" : 1 }, "sms" : { "units" : "texts sent", "n" : 100, "over_rate" : 0.001 } }, "term_years" : 2 },
{  "name" : "Phone Service Core Plan", "type" : "service", "monthly_price" : 60, "rating" : 3, "limits" : { "voice" : { "units" : "minutes", "n" : 1000, "over_rate" : 0.05 }, "data" : { "n" : "unlimited", "over_rate" : 0 }, "sms" : { "n" : "unlimited", "over_rate" : 0 } }, "term_years" : 1 },
{ "name" : "Phone Service Family Plan", "type" : "service", "monthly_price" : 90,"rating" : 4, "limits" : { "voice" : { "units" : "minutes", "n" : 1200, "over_rate" : 0.05 }, "data" : { "n" : "unlimited", "over_rate" : 0 }, "sms" : { "n" : "unlimited", "over_rate" : 0 } }, "sales_tax" : true, "term_years" : 2 }]

Después crearemos las siguientes búsquedas:

Elementos cuyo ‘type’ sea ‘service’.
Elementos cuyo ‘type’ sea ‘service’ y el precio mensual > 50
Elementos cuyo ‘type’ sea ‘service’ O el precio mensual > 50

MongoDB Consultas

https://docs.mongodb.com/manual/tutorial/query-documents/

https://docs.mongodb.com/manual/reference/operator/query/#query-selectors

Si yo en sql quiero aquellos registros cuya qty > 50

where qty>50

Si yo en MongoDB quiero lo mismo tengo que ponerlo así:

qty:{$gt:50}

campo:{operador:valor}


-- Buscar todos

db.inventory.find();

-- Buscar por igualdad. El campo debe valor lo mismo que lo que le pongo

db.inventory.find( { status: "D" } )

-- Buscar usando un operador. Ojo porque la sintaxis es un poco extraña

db.inventory.find( { qty: {$gt:50} } )

-- Operador in

db.inventory.find({status:{$in:["A","D"]}});

-- Por defecto, si tenemos varias condiciones, se entiende que se tienen que cumplir todas (AND)

db.inventory.find( { status: "A", qty: { $lt: 30 } } )

db.inventory.find({
$or: [
	{status:"D"},
	{qty:{
		$lt:50
		}
	}
]
})

db.inventory.find({$or: [{status:"D"},{qty:{$lt:50}}]})

-- esto

db.inventory.find( {
     status: "A",
     $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )

-- sería equivalente a: SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")

db.inventory.find({qty:{$gte:40,$lte:60}})

-- En búsquedas anidadas por defecto se entiende la igualdad abosulta en valores y orden:

db.inventory.find( { size: { w: 21,h: 14,  uom: "cm" } } ) -- esto no lo encuentra

db.inventory.find({size:{h:14}}) -- Esto tampoco

db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } ) -- Esto sí

-- Para buscar por un valor concreto independientemente de optras propiedades usamos el . (punto)

db.inventory.find({"size.h":8.5})

-- Podemos usar varias condiciones tanto de propiedades anidadas como de propiedades normales

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

-- Al buscar en array la igualdad es como en los anidades: mismos valores en mismo orden
-- Las dos consultas siguientes nos devuelven diferentes resultados

db.inventory.find( { tags: [ "blank","red"] } )

db.inventory.find( { tags: ["red", "blank"] } )

-- Si yo omito los corchetes y uso un valor (o un operador) se busan los elementos que contengan el valor o que cumplan la condición:

db.inventory.find({tags:"red"}) -- Busca los que tengan 'red' en el array

db.inventory.find({tags:{$in:["red","blue"]}}) -- Que tengan "red" o "blue" en alguna parte del array

db.inventory.find( { dim_cm: { $gt: 25 } } ) -- Algún elemento del array sea mayor de 25

-- Las dos condiciones se tienen que cumplir pero lo pueden cumplir elementos diferentes del array
-- Es decir, una condición la puede cumplir un elemento y la otra otro.

db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )

-- Las dos condiciones las tiene que cumplir juntas al menos un elemento del array

db.inventory.find( { dim_cm: { $elemMatch: { $gt: 15, $lt: 20 } } } )

-- Busco en un array en una posición concreta (índice de base 0)

db.inventory.find( { "dim_cm.1": { $gt: 25 } } )

-- Buscar los documentos cuyo array tiene una longitud determinada

db.inventory.find( { "tags": { $size: 3 } } )

-- Buscar los documentos en cuyo array haya un elemento que cumpla esa condición:

db.inventory.find( { "instock.warehouse": "C" } )

db.inventory.find( { "instock.qty": {$gte:40}} )

-- Que me muestre sólo los campos 'item' y 'status'. El id se ve siempre por defecto

db.inventory.find( { status: "A" }, { item: 1, status: 1 } )

-- Que me muestre sólo los campos 'item' y 'status'. El id lo oculto

db.inventory.find( { status: "A" }, { item: 1, status: 1, _id:0 } )

-- Que se muestren todos los campos menos 'size' e 'instock'

db.inventory.find( { status: "A" }, { size:0,instock:0 } )

-- Podemos usar $slice para obtener en la proyección subconjuntos de un array, y permite valores negativos

db.inventory.find( { status: "A" }, { item: 1, status: 1, instock: { $slice: -1 } } )

-- Busca los documentos que no tengan la propiedad o que valga nulo

db.inventory.find( { item: null } )

-- Busca los documentos que no tengan la propiedad, si la tienen y vale nulo no los encuentra

db.inventory.find( { item : { $exists: false } } )

-- Busca los documentos que SI tengan la propiedad aunque valga nulo

db.inventory.find( { item : { $exists: true } } )


MongoDB insert

https://docs.mongodb.com/manual/tutorial/insert-documents/

db.collection.insertOne() Inserts a single document into a collection.
db.collection.insertMany() db.collection.insertMany() inserts multiple documents into a collection.
db.collection.insert() db.collection.insert() inserts a single document or multiple documents into a collection.

SIEMPRE empezamos con db, NO nuestra base de datos.

Si nuestra colección no existe se crea. Así que ojo con poner el nombre bien.

Ejemplo:

db.actor.insertOne({nombre:"Ana",apellidos:"Pi"});

db.actor.insertMany([{
nombre:"Eva",
apellido:"Pou",
intereses:["drama","comedia"]
},
{
nombre:"Ana",
apellido:"Ros",
pelicula:{
	titulo:"Drama en la cumbre",
	anyo:2020
	}
},
{
nombre:"Ana",
apellido:"Ros",
pelicula:{
	titulo:"Drama en la cumbro",
	anyo:2020
	}
}
])

db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

Mini ejercicio funciones

Crear una función que le pasemos el id de una película y nos deuelva lo siguiente:

‘Para adultos’ Si el rating es ‘R’
‘Para todas las edades’ si no lo es

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `tipo_pelicula`
(p_film_id int) RETURNS varchar(50) CHARSET latin1
BEGIN
declare v_rating varchar(5);

select rating into v_rating from film 
where film_id=p_film_id;

if v_rating='R' then
	return 'Para adultos';
else
	return 'Para todos los públicos';
end if;

END$$

DELIMITER ;

Ejemplos de funciones en Mysql


DELIMITER $$
CREATE DEFINER=`root`@`localhost` 
FUNCTION `doble`(numero int) RETURNS int(11)
BEGIN

RETURN numero*2;
END$$

DELIMITER ;

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `tipo_pelicula`
(p_film_id int) RETURNS varchar(50) CHARSET latin1
BEGIN
declare v_length int;
select length into v_length from film 
where film_id=p_film_id;

if v_length<=140 then
return 'CORTA';
else
RETURN 'LARGA';
end if;

END$$

DELIMITER ;

DELIMITER $$
USE `sakila`$$
CREATE DEFINER=`root`@`localhost` FUNCTION `factorial`(p_numero int) RETURNS int(11)
BEGIN
declare total,cont int default 1;

while cont<=p_numero do
 set total=total*cont;
 set cont=cont+1;
end while;
RETURN total;
END$$

DELIMITER ;

Uso:


select doble(8);

select title,length,tipo_pelicula(film_id) from film;

select factorial(5);

Procedimiento almacenado alta clientes

delimiter $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `alta_cliente2` (in p_country varchar(50),
in p_city varchar(50),
in p_address varchar(50),
in p_first_name varchar(50),
in p_last_name varchar(50),
out p_customer_id int)
BEGIN

declare v_country_id int;
declare v_city_id int;
declare v_address_id int;
declare v_customer_id int;

select country_id into v_country_id from country
where country=p_country;

IF v_country_id is null then
 insert into country(country) values (p_country);
 select last_insert_id() into v_country_id;
END IF;

select city_id into v_city_id from city
where city=p_city and country_id=v_country_id;

IF v_city_id is null then
 insert into city(city,country_id)
 values (p_city,v_country_id);
 select last_insert_id() into v_city_id;
END IF;

select address_id into v_address_id from address
where address=p_address and city_id=v_city_id;

IF v_address_id is null then
 insert into address(address,city_id)
 values (p_address,v_city_id);
 select last_insert_id() into v_address_id;
END IF;

select customer_id into v_customer_id from customer
where first_name=p_first_name and last_name=p_last_name and address_id=v_address_id;

IF v_customer_id is null then
 insert into customer(first_name,last_name,address_id,store_id)
 values (p_first_name,p_last_name, v_address_id,1);
 select last_insert_id() into v_customer_id;
END IF;

select v_customer_id into p_customer_id;

END$$
delimiter ;

Uso:

call alta_cliente('Spain','Logroño','Laurel, 4','Juan','Pi',@id);
select @id;