INSERT Consultas
Objetivo
Configuración
INSERTAR Consulta
Para ver cómo funciona esto, comenzaremos en PHPMyAdmin.
Inicie sesión y abra la tabla 'héroes' en la base de datos 'webdev'.
Abra la pestaña 'Insertar'.
Observe que cada uno de los campos de nuestra tabla está representado por una fila.
Elija un héroe/villano de la siguiente lista y agréguelo a la tabla. Si estás trabajando en una clase, cada uno elige un personaje diferente.
alias | identity | hero_villain | first_appeared | power |
Thor | Thor Odinson | Hero | 1962 | Magic |
Red Skull | Johan Schmidt | Villain | 1941 | Biological |
Bucky Barnes | Winter Soldier | Villain | 1941 | Tech |
Clint Barton | Hawkeye | Hero | 1969 | Skill |
Odin | Odin | Hero | 1962 | Magic |
Nick Fury | Nick Fury | Hero | 1963 | Skill |
Phil Coulson | Agent Coulson | Hero | 2008 | Skill |
Peter Quill | Starlord | Hero | 1976 | Tech |
Gamora | Gamora | Hero | 1975 | Skill |
Pepper Potts | Rescue | Hero | 1963 | Tech |
Ingrese la información de su héroe en los campos apropiados en la columna 'Valor' y presione 'Ir'.
Vea la consulta utilizada para agregar los datos justo debajo de la fila amarilla en la parte superior de la página.
INSERT INTO `heroes` (`alias`, `identity`, `hero_villain`, `first_appeared`, `power`) VALUES ('Bucky Barnes', 'Winter Soldier', 'Villain', '1941', 'Tech');
Este es el formato que debemos usar para nuestra consulta de inserción en 'process_form.php'.
Una consulta INSERT siempre comienza con 'INSERT INTO' y el nombre de la tabla que usaremos, luego una lista de los campos que queremos agregar.
Esto es seguido por 'VALORES' y una lista de los valores a ser insertados.
Declaración de 'Switch'
Recuerde que en realidad tenemos dos formularios enviados a esta página mediante dos botones de envío.
Podemos identificar qué formulario procesar por el valor de '$_POST['submit']'.
Podríamos hacer esto con una declaración 'si', como esta.
switch ($variable) {
case 'value':
# code...
break;
default:
# code...
break;
}
Esto funcionaría, pero hay una mejor manera.
Una 'sentencia switch' no es tan flexible como una 'sentencia if', que permite condiciones completamente nuevas en cada línea, pero es más potente a su manera.
Abra 'process_form.php' en Visual Studio Code.
Al final del primer bloque de PHP, escriba 'cambiar' y seleccione la segunda opción. Agregará el siguiente código automáticamente.
switch ($edad) {
case 1:
case 17:
case 43:
# code...
break;
case 22:
case 39:
# code...
break;
}
Queremos ejecutar una consulta diferente dependiendo del valor de $_POST['submit'], así que reemplace '$variable' con $_POST['submit']
.
Ahora configure un caso para 'Agregar héroe' y 'Agregar apariencia'.
switch ($_POST['submit']) {
case 'Agregar Héroe':
break;
case 'Agregar apariencia':
break;
default:
break;
}
$query = "";
$args = array();
$rslt = $pdo->prepare($query);
$rslt->execute($args)
Ahora podemos copiar nuestra consulta de PHPMyAdmin a la cadena de consulta.
Debido a que los piratas informáticos pueden realizar una “inyección SQL” para obtener información sobre su base de datos o incluso para agregarse como un usuario administrador agregando código SQL como datos, vamos a eliminar los datos de nuestra consulta.
Reemplace cada valor con ? luego agregue la entrada de usuario respectiva como elementos en la matriz '$args'.
$query = "INSERT INTO `heroes` (`alias`, `identity`, `hero_villain`, `first_appeared`, `power`) VALUES (?,?,?,?,?)";
$args = array($_POST['alias'], $_POST['identity'], $_POST['alias'], $_POST['side'], $_POST['year'], $_POST['power']);
Este código funcionará a menos que haya un problema para acceder a la base de datos o una entrada de usuario no válida.
Como queremos saber si hay un problema y decirle al usuario, agreguemos una verificación.
Cambie $rslt->execute($args)
a lo siguiente.
if ($rslt->execute($args)) {
} else {
}
if ($rslt->execute($args)) {
$message = "{$_POST['name']} was inserted successfully.";
} else {
$message = "There was a problem inserting {$_POST['name']}.";
}
Insertos Múltiples
El formulario Agregar apariencias permite al usuario agregar varias películas, pero cada una es su propia línea en la tabla de la base de datos.
Podríamos crear una consulta separada para cada película, pero también es posible agregar varias líneas en la misma consulta haciendo algo como esto.
INSERT INTO appearances (character_name, movie) VALUES ('Thor Odinson', 'Thor: Dark World'), ('Thor Odinson', 'Avengers: Age of Ultron')
Empuje de Matriz
Dejemos la consulta para el final porque necesitaremos filtrar las apariencias ya existentes.
Primero, construyamos nuestro conjunto de argumentos: un par para cada película.
Cada par de argumentos es el nombre de nuestro héroe y el nombre de la película, lo que podemos hacer en 'foreach' bucle.
foreach($_POST['movie'] as $movie) {
}
array_push($args, $_POST['hero'], $movie);
El primer parámetro de esta función debe ser una matriz, y los valores posteriores se agregan al final de la matriz.
Por supuesto, primero debemos crear la matriz, y no queremos que se vuelva a crear cada vez que hacemos un bucle, por lo que debemos crearla antes foreach
.
$args = array();
foreach($_POST['movie'] as $movie) {
array_push($args, $_POST['hero'], $movie);
}
// check if it exists already
$mquery = "SELECT * FROM appearances WHERE character_name=? AND movie=?";
$margs = array($_POST['hero'], $movie);
$rslt = $pdo->prepare($mquery);
$rslt->execute($margs);
if (!$row = $rslt->fetch()) {
array_push($args, $_POST['hero'], $movie);
}
¿Puedes leer este código por ti mismo?
$mquery es la consulta que pregunta si el par héroe/película ya existe.
$margs es la matriz de parámetros para la consulta.
Luego ejecutamos la consulta y, si no existe (if (!$row = $rslt->fetch())
), la agregamos a la lista de argumentos.
¿Y si es una nueva película? No queremos agregar la palabra 'nuevo' como título de la película. Tenemos que cambiarlo a $_POST['new_movie']
su lugar.
Verifiquemos usando una 'sentencia if'.
if ($movie == 'new') {
array_push($args, $_POST['hero'], $_POST['new_movie']);
} else {
// check if it exists already
$mquery = "SELECT * FROM appearances WHERE character_name=? AND movie=?";
$margs = array($_POST['hero'], $movie);
$rslt = $pdo->prepare($mquery);
if (!$rslt->execute($margs)) {
array_push($args, $_POST['hero'], $movie);
}
}
Contar
Podríamos haber creado la consulta primero y agregado piezas en el bucle, pero hay una forma más elegante.
Si sabemos cuántas películas se han agregado, simplemente podemos agregar el número correcto (?,?)
al final de la consulta.
Podemos obtener el número de elementos en la $args
matriz usando count
y luego reducirlo a la mitad.
count
es como .length
en Javascript, contando el número de elementos en una matriz.
Agregue el siguiente código después del foreach
bucle.
$movies = count($args)/2;
Cadena Repetitiva
Luego, debemos agregar exactamente esa cantidad de copias de (?,?)
al final de la consulta, pero deben estar separadas por un ,
.
$values = str_repeat('(?,?), ', $movies-1) . '(?,?)';
Esta técnica utiliza una función llamada str_repeat
para repetir una cadena establecida varias veces. Si repetimos '(?,?),' el número correcto de veces, tendríamos un colgante ,
al final que provocaría un error. En cambio, agregamos uno menos que la cantidad requerida ( count($movies) -1
), luego agregamos (?,?)
al final.
Ahora, nuestra consulta es:
$query = "INSERT INTO heroes ('alias', 'movie') VALUES $values";
Antes de ejecutar nuestra consulta, debemos verificar que el código funcione, que tanto la consulta como los argumentos se vean como deberían.
Agregue lo siguiente antes de break
.
error_log("MURRAY: $query\n" . print_r($args, 1);
Guarde y cargue el código, luego abra 'form.php' en su navegador.
Elija un héroe y seleccione una serie de películas, incluida la nueva. Ingrese una película que aún no esté en nuestra lista en ningún lugar y haga clic en 'Agregar apariencia'.
Ahora verifique los registros de errores en Putty.
Si la matriz de consultas y argumentos se ve bien, es hora de enviarlos a la base de datos.
$rslt = $pdo->prepare($query);
if ($rslt->execute($args)) {
$message = "$movies appearances were inserted successfully.";
} else {
$message = "There was a problem inserting $movies appearances.";
}
Este código también incluye la verificación para ver si la consulta fue exitosa y agrega un mensaje apropiado en cualquier caso.
Guarde y cargue su código, luego abra 'form.php' y envíe algunas apariencias nuevas para verificar que todo funcione.
El único problema que aún tenemos es que si el usuario solo agrega películas que ya están en la base de datos, estamos creando una consulta e intentando enviarla sin valores.
Arreglemos eso deteniéndonos si no hay nuevas películas para agregar.
if ($movies > 0) {
$values = str_repeat('(?,?), ', $movies-1) . '(?,?)';
$query = "INSERT INTO appearances (alias, movie) VALUES $values";
error_log("MURRAY: $query " . print_r($args, 1));
$rslt = $pdo->prepare($query);
if ($rslt->execute($args)) {
$message = "$movies appearances were inserted successfully.";
} else {
$message = "There was a problem inserting $movies appearances.";
}
} else {
$checked = count($_POST['movie']);
$message = "All $checked appearances are already in the database.";
}
En lugar de referirme a $movies, que será 0 en este caso, cambié el mensaje para que se refiera al número original de películas enviadas e indique que ya estaban todas en la base de datos.
Esta ha sido una gran actividad, pero hay más que hacer en la próxima actividad.
Codigo Final