Ejemplo de procedimientos almacenados
Parámetros entrada y salida:
CREATE PROCEDURE `test`(in id int, out p_actor varchar(100))
BEGIN
select concat_ws(' ',first_name,last_name) into p_actor from actor where actor_id=id;
END
call test(2, @actor);
CREATE DEFINER=`root`@`localhost` PROCEDURE `suma`(in a int, in b int, out suma int)
BEGIN
set suma=a+b;
END
call suma(8,9,@res);
Alta de registros con comprobación incluída:
CREATE DEFINER=`root`@`localhost` PROCEDURE `alta_actor`(in nombre varchar(100), in apellido varchar(100))
BEGIN
declare c int;
select count(*) into c from actor where first_name=nombre and last_name=apellido;
if c=0 and length(nombre)>1 and length(apellido)>1 then
insert into actor (first_name, last_name) values (nombre, apellido);
end if;
END
call alta_actor ('juan','pa');
call alta_actor ('juan','pa'); --No funcionará por repetido
call alta_actor ('juan','p'); -- no funcionará por longitud
Ejemplo de cursor:
CREATE PROCEDURE `cursor_ejemplo`(out total int) BEGIN DECLARE final int DEFAULT 0; declare nombre varchar(100); DECLARE mi_cursor CURSOR FOR SELECT first_name FROM actor; DECLARE CONTINUE HANDLER FOR NOT FOUND SET final = 1; set total=0; OPEN mi_cursor; while final=0 do fetch mi_cursor into nombre; if nombre like '%z%' then set total=total+1; end if; end while; CLOSE mi_cursor; END call cursor_ejemplo(@t);
Procedimientos almacenados
Ejemplos de procedimientos almacenados
CREATE DEFINER=`root`@`localhost` PROCEDURE film_in_stock (IN p_film_id INT, IN p_store_id INT, OUT p_film_count INT) READS SQL DATA BEGIN SELECT inventory_id FROM inventory WHERE film_id = p_film_id AND store_id = p_store_id AND inventory_in_stock(inventory_id); SELECT FOUND_ROWS() INTO p_film_count; END
call film_in_stock(123,1,@w); select @w
CREATE DEFINER=`root`@`localhost` PROCEDURE `actores_por_categoria` (in p_categoria varchar(50)) BEGIN select distinct concat(first_name,' ',last_name) actor from actor join film_actor using (actor_id) join film using (film_id) join film_category using (film_id) join category c using (category_id) where c.name=p_categoria order by actor; END
call actores_por_categoria('Animation')
Ejercicios vistas
Crear una vista que nos muestre el pais, la ciudad, la dirección y el nombre de los clientes. La podemos llamar clientes_direccion
Con esa vista creada será muy fácil mostrar los clientes de Argentina o Italia
Crear una vista que nos relacione la película con sus pagos. Que nos muestre el id de la película, el title, y todos los datos de payment.
Con esa vista sería muy fácil ver el total de pagos por película.
Creando vistas en mysql
Categorías, películas y actores:
create view pelistotal as select category_id, category.name nombrecategoria, film_id,title,actor_id, first_name,last_name from category join film_category using (category_id) join film using (film_id) join film_actor using (film_id) join actor using (actor_id)
La usamos como una tabla normal:
select name,count(actor_id) total from pelistotal group by category_id
select * from actor where actor_id not in ( SELECT actor_id FROM pelistotal where name='action');
Como hacer una consulta del tipo actores que no han trabajado en películas de acción si usar subconsultas. Primero creamos la vista en positivo:
create view actores_accion as select actor_id,first_name,last_name from category join film_category using (category_id) join film using (film_id) join film_actor using (film_id) join actor using (actor_id) where name='action'
Y después hacemos un left join y buscamos los nulos:
SELECT * FROM actor left join actores_accion using(actor_id) where actores_accion.first_name is null
Ejemplos Create view
create view peliculas_pais as select country, count(rental_id) total from country join city using (country_id) join address using(city_id) join customer using(address_id) join rental using(customer_id) group by country_id
CREATE VIEW peliculas_categoria AS select name, count(film_id) total from category join film_category using (category_id) group by category_id
El formato JPG explicado y listo para enredar
Ejercicios repaso mysql
Encontrar los clientes que hayan gastado más de 100 dólares
Mostrar los diez actores que han trabajado en más películas
Buscar las películas que se hayan alquilado más de 20 veces
Clientes de España o Argentina
Películas para niños (children) o familiares (Family)
Actores que no hayan trabajado en películas para niños o familiares
Actores que hayan trabajado en películas que no se hayan alquilado nunca
Ejercicios subconsultas
Clientes que no han alquilado películas del actor con actor_id=1
Actores que no han trabajado en películas que duren más de 180 minutos
Actores que han trabajado en películas que no duran más de 180 minutos
Categorías que no tienen películas que duren más de 180 minutos
Clientes que no han pagado más de 10 dólares por alquilar una película.
Ejercicios left/right
Número de veces que se ha alquilado una película, incluyendo las que no se han alquilado nunca
Número de actores por película, incluyendo las películas que no tengan actores
Una consulta que me muestre juntas los nombres de las ciudades y los nombres de los distritos en las direcciones.
select title, count(rental_id) total from film left join inventory using (film_id) left join rental using (inventory_id) group by film_id select title,count(actor_id) total from film left join film_actor using (film_id) left join actor using (actor_id) group by film_id select city territorio from city union select district territorio from address order by territorio