No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

15 Días
4 Hrs
16 Min
2 Seg

Prepared statements

29/34
Recursos

Aportes 14

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Hice un pequeño tutorial de la clase, si es que estas iniciando con las bases de datos te puede ser muy util, este es el tutorial.

Dos formas de hacerlo usando Store Procedure

Leyendo los comentarios e investigando encontré que concatenar los Prepared Statement puede ser arriesgado pues nuestro código se vuelve vulnerable a la inyección de código malicioso, para ello se recomienda usar marcadores de posición.

Los marcadores de posición son símbolos o variables temporales que representan valores que se asignarán después.

Como en mi caso usé “?” en vez de concatenar ‘line_id’, y utilicé la declaración USING en la instrucción EXECUTE stmt para usar ‘line_id’ como argumento.

<
USE metro_cdmx;

DELIMITER //
CREATE PROCEDURE stations_for_line (
    IN line_name VARCHAR(20)
)
BEGIN
    DECLARE line_id BIGINT(20);

    SELECT `id` 
    INTO line_id
    FROM `lines`
    WHERE `name` = line_name
    COLLATE utf8mb4_unicode_ci;

    SET @sql = "
        SELECT
            `l_s`.`id` AS id_relation,
            `l`.`name` AS line_name,
            `s`.`name` AS stations_name
        FROM `lines_stations` AS l_s
        INNER JOIN `stations` AS s
        ON `s`.`id` = `l_s`.`station_id`
        INNER JOIN `lines` AS l
        ON `l`.`id` = `l_s`.`line_id`
        WHERE `l_s`.`line_id`=?";

    PREPARE stmt FROM @sql;
    EXECUTE stmt USING line_id;
    DEALLOCATE PREPARE stmt;

END //

DELIMITER ;


Yo los prepares statements lo conocía de esta forma y es al momento de recibir el line name, lo utlizo directamente en la consulta, estaría bien? de igual forma me devuelve el listado.

DELIMITER //
CREATE PROCEDURE get_line_station(
    IN line_name VARCHAR(15)
)
BEGIN

    
        SELECT
            `lines_stations`.`id` AS relation_id,
            `lines`.`name` AS line_name,
            `stations`.`name` AS station_name
        FROM `lines_stations`
        INNER JOIN `stations`
        ON `stations`.`id` = `lines_stations`.`station_id`
        INNER JOIN `lines`
        ON `lines`.`id` = `lines_stations`.`line_id`
        WHERE `lines`.`name`=line_name; 


END //

DELIMITER ; 

🚇 Stored Procedure para Calcular Distancias entre Estaciones del Metro CDMX 🚇

Basado en los conceptos aprendidos en clase, he realizado una modificación al Stored Procedure. En lugar de buscar manualmente el código de cada localización para calcular la distancia de una estación a otra, he implementado que las estaciones puedan buscarse solo colocando el nombre de la estación.
El codigo 👇

![](https://static.platzi.com/media/user_upload/image-25b76c61-ac39-4d29-a24d-dcfd6b0d5faa.jpg)buenas tardes, hice el seguimiento pero al momento me sigue dando el error de que no es compatible el utf8mb4\_unicode\_ci, segui los pasos del profe al pie de la letra
USE metro_cdmx;

DELIMITER //

-- GET ALL STATIONS BELONGING TO A LINE
CREATE PROCEDURE get_line_stations(
    IN line_name VARCHAR(15)
)
BEGIN
    DECLARE line_id BIGINT(20);

    SELECT id
    INTO line_id
    FROM `lines`
    WHERE name = line_name
    COLLATE utf8mb4_unicode_ci;

    SET @sql = CONCAT("
        SELECT
            `lines_stations`.`id` AS relation_id,
            `lines`.`name` AS line_name,
            `stations`.`name` AS station_name
        FROM `lines_stations`
        INNER JOIN `lines` ON `lines_stations`.`line_id` = `lines`.`id`
        INNER JOIN `stations` ON `lines_stations`.`station_id` = `stations`.`id`
        WHERE `lines_stations`.`line_id` = ", line_id);

    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

END //
DELIMITER ;

Estos procedimientos almacenados permiten dar versatilidad a nuestras búsquedas y permite también enviar operaciones que son habituales en nuestros proyectos. Esto ahorra tiempo y esfuerzo a la hora de consultar nuestra base de datos.

Muy buena esta clase!!
Asi quedo mi Store Procedure de la clase anterior. ```js USE metro_cdmx; DELIMITER // CREATE PROCEDURE Calculate_distance_between_station( IN station_one VARCHAR(60), IN station_two VARCHAR(60), IN meters BOOLEAN ) Begin IF meters THEN SELECT ST_DISTANCE_SPHERE( (SELECT locations.location FROM locations INNER JOIN stations ON stations.station_id = locations.station_id WHERE stations.`name` = station_one), (SELECT locations.location FROM locations INNER JOIN stations ON stations.station_id = locations.station_id WHERE stations.`name` = station_two) ) AS distancia_km; ELSE SELECT ST_DISTANCE_SPHERE( (SELECT locations.location FROM locations INNER JOIN stations ON stations.station_id = locations.station_id WHERE stations.`name` = station_one), (SELECT locations.location FROM locations INNER JOIN stations ON stations.station_id = locations.station_id WHERE stations.`name` = station_two) )/ 1000 AS distancia_km; END IF; END // DELIMITER ; ```
Como aporte me gustaría decir que yo en lo personal no he estado usando las `` a los lados de los nombres de las tablas al momento de hacer mis consultas, pero cuando intenté hacer la consulta con la tabla lines, no pude, porque al parecer lines es un comando reservado para SQL. Es decir, este código no funcionaría: `USE metro_cdmx;` `DELIMITER //CREATE PROCEDURE get_line_stations(    IN line_name VARCHAR(15))BEGIN    DECLARE line_id BIGINT(20);` `    SELECT id    INTO line_id    FROM lines    WHERE name = line_name    COLLATE utf8mb4_unicode_ci;` `    SET @sql = CONCAT("        SELECT            lines_stations.id AS relation_id,            lines.name AS line_name,            stations.name AS station_name        FROM lines_stations        INNER JOIN stations        ON stations.id = lines_stations.station_id        INNER JOIN lines        ON lines.id = lines_stations.line_id        WHERE lines_stations.line_id = ", line_id);        PREPARE stmt FROM @sql;    EXECUTE stmt;    DEALLOCATE PREPARE stmt;` `END //DELIMITER ;` Pero este sí: `USE metro_cdmx;` `DELIMITER //CREATE PROCEDURE get_line_stations(    IN line_name VARCHAR(15))BEGIN    DECLARE line_id BIGINT(20);` ``    SELECT id    INTO line_id    FROM `lines`    WHERE name = line_name    COLLATE utf8mb4_unicode_ci;`` ``    SET @sql = CONCAT("        SELECT            lines_stations.id AS relation_id,            `lines`.name AS line_name,            stations.name AS station_name        FROM lines_stations        INNER JOIN stations        ON stations.id = lines_stations.station_id        INNER JOIN `lines`        ON `lines`.id = lines_stations.line_id        WHERE lines_stations.line_id = ", line_id);        PREPARE stmt FROM @sql;    EXECUTE stmt;    DEALLOCATE PREPARE stmt;`` `END //DELIMITER ;` La diferencia es que en el primero lines no tiene las ``, pero en el segundo sí lo declaramos como ``lines``, espero que esto sirva :)

Me parece recordar que concatenar parámetros de entrada es una mala práctica en los prepared statement, debido a que facilitan el sql injection. Reemplazaría la concatenación con el uso de parámetros.

Me puse a jugar con la tabla creada en esta clase, quite , puse modifique y aplique lo de la primera consulta en la segunda y viceversa, y note lo siguiente:

  1. Si declaramos un SET @variable en la primera consulta, no reconocerá el campo line_name creado en la cabecera para obtener el id de nuestra consulta a partir del nombre.
  2. Las prepared statements son consultas almacenadas en una variable con estructura de texto.
    Esto es importante recalcarlo, imaginemos que en nuestro procedimiento necesitamos hace uso de múltiples consultas y que estén relacionadas unas con otras.
    Bueno pues es aquí donde juegan un papel importante ya que es mas sencillo hacerlo a través de una variable con una consulta almacenada.

Les agradecería mucho que me diesen retroalimentación si esto funciona así .

Esta forma de obtener consultas me parece genial, una alternativa a estar copiando y pegando consultas muy grandes