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>

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