Categoría: BD
Insertar cliente
Hay que hacer varios pasos
$server = "localhost"; $user = "root"; $password = ""; $db = "sakila"; try { $conn = new PDO("mysql:host=$server;dbname=$db;charset=UTF8", $user, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Los datos que tengo que insertar $pais = 'ArgentinaJarll'; $ciudad = "La plata"; $direccion = "Agla 6"; $nombre = "Juan"; $apellidos = "Pi"; //Compruebo si existe el país consultando a la base de datos si hay //algún país que se llame como el que me han pasado $sql = "select * from country where country=:country"; $parametros = [ 'country' => $pais ]; $st = $conn->prepare($sql); $st->execute($parametros); $country = $st->fetch(); //Si no existe lo inserto if (empty($country)) { $sql = "insert into country(country) values(:country)"; $st = $conn->prepare($sql); $st->execute($parametros); $country_id = $conn->lastInsertId(); } else { $country_id = $country['country_id']; } //Aquí ya tengo el país echo $country_id . "<br/>"; //Hago la misma comprobación para la ciudad pero ojo, de ese país $sql = "select * from city where city=:city and country_id=:country_id"; $parametros = [ 'city' => $ciudad, 'country_id' => $country_id ]; $st = $conn->prepare($sql); $st->execute($parametros); $city = $st->fetch(); //Si no existe la ciudad la inserto if (empty($city)) { $sql = "insert into city(city,country_id) values(:city,:country_id)"; $st = $conn->prepare($sql); $st->execute($parametros); $city_id = $conn->lastInsertId(); } else { $city_id = $city['city_id']; } //Aquí ya tengo el id de la ciudad echo $city_id . "<br>"; //A partir de aquí no compruebo más. Inserto la dirección con esa ciudad $sql = "insert into address (city_id,address) values (:city_id,:address)"; $parametros = [ 'city_id' => $city_id, 'address' => $direccion ]; $st = $conn->prepare($sql); $st->execute($parametros); //Recupero el id de de esa dirección $address_id = $conn->lastInsertId(); //Inserto el cliente con el id de la dirección y en store_id pongo un 1 directamente $sql = "insert into customer (address_id,first_name,last_name,store_id)" . " values (:address_id,:first_name,:last_name,1)"; $parametros = [ 'address_id' => $address_id, 'first_name' => $nombre, 'last_name' => $apellidos ]; $st = $conn->prepare($sql); $st->execute($parametros); echo "insertado el cliente con id ".$conn->lastInsertId(); } catch (Exception $e) { echo "Connection failed: " . $e->getMessage(); }
Ejemplos prepare
$sql="insert into actor (first_name,last_name) values (:first_name,:last_name)"; $parametros=[ 'first_name'=>'Perico', 'last_name'=>'De los palotes' ]; $st=$conn->prepare($sql); $st->execute($parametros);
$sql="SELECT city FROM country join city using(country_id) where country=:country"; $parametros=[ 'country'=>'Argentina' ]; $st=$conn->prepare($sql); $st->execute($parametros); $ciudades=$st->fetchAll(); print_r($ciudades);
$sql="SELECT country FROM country where country like :country"; $parametros=[ 'country'=>'%ar%' ]; $st=$conn->prepare($sql); $st->execute($parametros); $paises=$st->fetchAll(); print_r($paises);
$sql = "SELECT * FROM customer join address using(address_id) where email=:email and phone=:phone"; $parametros=[ 'email'=>'mary.smith@sakilacustomer.org', 'phone'=>'28303384290' ]; $st=$conn->prepare($sql); $st->execute($parametros); $cliente=$st->fetch(); if (empty($cliente)){ echo "No sé quién eres"; } else{ echo "hola ".$cliente['first_name']; }
$sql="update film set replacement_cost=replacement_cost*:descuento where rating=:rating"; $parametros=[ 'descuento'=>0.9, 'rating'=>'R' ]; $st=$conn->prepare($sql); $st->execute($parametros);
CRUD actores sakila
actores.php
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <?php $server = "localhost"; $user = "root"; $password = ""; $db = "sakila"; ?> <form method="post"> <p>Nombre<input type="text" name="first_name"></p> <p>Apellidos<input type="text" name="last_name"></p> <input type="submit"> </form> <table> <tr><td>Id</td><td>Nombre</td><td>Apellido</td><td>Acciones</td> </tr> <?php try { $conn = new PDO("mysql:host=$server;dbname=$db;charset=UTF8", $user, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Insertar el actor SI me lo mandas //Recuperar los datos de POST $first_name = filter_input(INPUT_POST, "first_name", FILTER_SANITIZE_MAGIC_QUOTES); $last_name = filter_input(INPUT_POST, "last_name", FILTER_SANITIZE_MAGIC_QUOTES); $actor_id = filter_input(INPUT_POST, "actor_id", FILTER_SANITIZE_NUMBER_INT); //Comprobar que me han mandado datos if (!empty($first_name) && !empty($last_name)) { //Si me han mandado crear el SQL para insertar o actualizar if (empty($actor_id)) { $sql = "insert into actor(first_name,last_name) values ('$first_name','$last_name')"; } else { $sql = "update actor set first_name='$first_name', last_name='$last_name'" . " where actor_id=$actor_id"; } //Ejecutarlo if ($conn->exec($sql) > 0) { echo "Insertado el actor $first_name $last_name"; } } $borrar = filter_input(INPUT_GET, "borrar", FILTER_SANITIZE_NUMBER_INT); if (!empty($borrar)) { $sql = "delete from actor where actor_id=$borrar"; if ($conn->exec($sql) > 0) { echo "Borrado el actor $borrar"; } } //Muestra los actores $sql = "select * from actor"; $q = $conn->query($sql); while ($row = $q->fetch()) { ?> <tr><td><?= $row['actor_id'] ?></td> <td><?= $row['first_name'] ?></td> <td><?= $row['last_name'] ?></td> <td><a href="actor_editar.php?actor_id=<?= $row['actor_id'] ?>">Editar</a> <a href="?borrar=<?= $row['actor_id'] ?>">Borrar</a></td> </tr> <?php } } catch (Exception $e) { echo "Connection failed: " . $e->getMessage(); } ?> </table> </body> </html>
actor_editar.php
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <?php $server = "localhost"; $user = "root"; $password = ""; $db = "sakila"; try { $conn = new PDO("mysql:host=$server;dbname=$db;charset=UTF8", $user, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $actor_id= filter_input(INPUT_GET, "actor_id",FILTER_SANITIZE_NUMBER_INT); $sql="select * from actor where actor_id=$actor_id"; $q=$conn->query($sql); $actor=$q->fetch(); //print_r($actor); ?> <h2>Editar actor</h2> <form action="actores.php" method="post"> <p>Id: <input readonly type="text" name="actor_id" value="<?=$actor['actor_id']?>"></p> <p>Nombre: <input type="text" name="first_name" value="<?=$actor['first_name']?>"></p> <p>Apellido: <input type="text" name="last_name" value="<?=$actor['last_name']?>"></p> <input type="submit"> </form> <?php } catch (Exception $e) { echo "Connection failed: " . $e->getMessage(); } ?> </body> </html>
Examen BD 2019
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')
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
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