Regresar a la página ComoCrearTuWeb.com
Resultados 1 al 6 de 6

Tema: Quiero cambiar un dato de una tabla... y cambian varios

  1. #1
    Esto empieza a ser un vicio... Habitante Avatar de Lombardo
    Fecha de Ingreso
    24 jul, 11
    Ubicación
    Austria
    Mensajes
    402
    Poder de Reputación
    17

    Quiero cambiar un dato de una tabla... y cambian varios

    Veamos, gracias a la infatigable amabilidad de nuestro buen amigo Skaparate comprendí cómo se efectúa el cambio de un registro en base de datos, consulta recogida en este post.

    Cuando ya creía que el tema estaba resuelto, me encuentro que, a pesar de señalar el elemento con un parámetro irrepetible por definición, la clave (primary autoincrement), el código me cambia TODOS los elementos que tienen el mismo dato que deseo cambiar en uno de ellos. Aclarando: en el ejemplo he creado una base de datos de coches, y si selecciono uno de ellos según su clave (que es primary key) para cambiar la marca, el programa cambia la marca de ese coche... y también la de todos los coches de esa marca.
    O sea que, aunque meta en la variable $registros los datos del coche con la clave 2, por ejemplo, si le cambio la marca, Toyota por ejemplo, por otra, Porsche por ejemplo, en la tabla se cambian de marca todos los Toyota. Pongo el código:

    Archivo que busca el elemento señalado mediante input:
    Código HTML:
    <h1>Cambio de datos en una DB</h1>
    		<form method="post" action="side.php">
    			Clave: <input type="text" name="clave">
    			<input type="submit" value="Buscar">
    		</form>
    El segundo archivo, que localiza el elemento buscado:

    Código PHP:
        <?php
        $conn
    =mysql_connect('localhost''root''') or die('Fallo en el select');
        
    mysql_select_db('equipo'$conn) or die ('Fallo en seleción de DB');
        
    $registros=mysql_query("select * from coches where clave='$_REQUEST[clave]'"$conn) or die ('Error en el select: '.mysql_error());
                    
    //¡sólo puede ser un coche, el determinado por la clave que es primary!
            
    if($res=mysql_fetch_array($registros)){
            
    ?>
            <form method="post" action="side2.php">
                Nueva marca:
                <input type="text" name="marcanueva" value="<?php echo $res['marca'];?>">
                <input type="hidden" name="marcavieja" value="<?php echo $res['marca'];?>">
                <br/><input type="submit" value="Modificar">
            </form>
            <?php
            
    }
            else {
                echo 
    'No tenemos coches con esa clave';
                echo 
    '<p><a href="./">Volver</a></p>';
            }
        
    ?>
    El tercer archivo, que realiza el cambio:

    Código PHP:
        <?php
            $conec
    =mysql_connect('localhost''root''') or die('Fallo de conexión');
            
    mysql_select_db('equipo'$conec) or die ('Fallo en selección de DB');
            
    mysql_query("update coches set marca='$_REQUEST[marcanueva]' where marca='$_REQUEST[marcavieja]'"$conec) or die('Error en el select: '.mysql_error());
                echo 
    'Se ha modificado el registro';
        
    ?>
    El resultado como digo es que se modifica no sólo la marca del coche con la clave introducida en el formulario, sino todos los coches de la misma marca. ¿Dónde está el fallo?

    ¡Muchas gracias de antemano por la ayuda!

  2. #2
    Esto empieza a ser un vicio... Habitante
    Fecha de Ingreso
    02 may, 11
    Ubicación
    Santiago, Chile
    Mensajes
    2,046
    Poder de Reputación
    27
    Hola de nuevo!

    No hay fallo.

    Explicación

    Supongamos la siguiente tabla:

    Código:
    coches
    ID | marca
    ----------
    1  | Honda
    2  | Hyundai
    3  | Honda
    4  | Honda
    5  | Chevrolet
    6  | Ferrari
    Digamos que quieres modificar la marca Honda y llamarla Porsche. Inicialmente, el form quedaría así:

    Código:
    marcanueva: Honda
    marvavieja: Honda
    Modificas marcanueva, quedando con Porsche y haces clic sobre Cambiar, la consulta quería así:

    Código:
    UPDATE coches SET marca = 'Porsche' WHERE marca = 'Honda';
    Entonces, el motor de base de datos recorrerá las filas y hará algo así:

    Código:
    Primera fila (id = 1, marca = Honda): marca es igual a Honda? Sí, por ende, se cambia a Porsche.
    Segunda fila (id = 2, marca = Hyundai): marca es igual a Honda? No, así que no se hace nada.
    Tercera fila (id = 3, marca = Honda): marca es igual a Honda? Sí; se cambia a Porsche.
    Cuarta fila (id = 4, marca = Honda): marca es igual a Honda? Sí; se cambia a Porsche.
    Quinta fila (id = 5, marca = Chevrolet): marca es igual a Honda? No; no se modifica.
    Sexta fila (id = 6, marca = Ferrari): marca es igual a Honda? No; No se modifica.
    ¿Cómo cambias una única fila?

    Simple: debes asegurarte de darle parámetros únicos a la consulta.

    En la consulta anterior, hay una marca que se repite 3 veces, por ende, este campo no puede ser un identificador único. Si quisieras cambiar la marca de un coche específico debes saber algo único:

    * El ID, puesto que las PRIMARY KEY no pueden repetirse, este es un identificador único.

    Ejemplo: UPDATE coches SET marca = 'Porsche' WHERE marca = 'Honda' AND ID = 1;

    * Referirse al coche en base a un índice UNIQUE. Por ejemplo, si existiera una columna llamada Placa (no sé como se llama en tu país el identificador del vehículo en la dirección de tránsito) que se haya definido como UNIQUE.

    Ejemplo: UPDATE coches SET marca = 'Porsche' WHERE marca = 'Honda' AND placa = 'an1898';

    * Referirse al coche a través de varias columnas que formen un identificador único. Por ejemplo, filtrando el coche por el nombre del dueño y/o fecha del registro.

    Ejemplo: UPDATE coches SET marca = 'Porsche' WHERE marca = 'Honda' AND dueno = 'Lombardo' AND registrado = '20-01-1999';

    Creo que eso te debería ayudar :).

    Lo siguiente es un extra, así que, si no quieres, no lo leas :P

    Por cierto, cuando hay un dato que se puede repetir muchas veces (como te expliqué en tu último tema), deberías separarlo en una tabla aparte. Hay formas de saber cuando separar los datos.Al diseñar la base de datos, generalmente nos hacemos unas preguntas. Por ejemplo:

    * Un dueño puede tener más de un coche? Sí ¿Un coche puede pertenecer a más de una persona (puede que dependa del país)? Sí, entonces esta relación se llama muchos a muchos (n:m), por lo que deben existir tres tablas:

    Código:
    dueno
    id,
    nombre,
    etc.
    
    coche_dueno
    id_coche,
    id_dueno,
    fecha_registro,
    PRIMARY KEY (id_coche, id_dueno),
    CONSTRAINT coche_dueno__dueno_FK FOREIGN KEY id_dueno REFERENCES dueno (id),
    CONSTRAINT coche_dueno__coche_FK FOREIGN KEY id_coche REFERENCES coche (id)
    
    coche
    id,
    placa
    * Sobre la marca: un coche puede tener más de una marca? No (hasta donde sé) y una marca, ¿le puede pertenecer a más de un auto? Sí (cada marca fabrica más de un coche, así que, sí pueden haber más de un coche con la misma marca), por lo que esta relación se conoce como 1 a muchos (1:n, donde 1 sería coche y n - muchos - sería marca; Una marca a muchos autos). Se representa así:

    Código:
    marca
    id PRIMARY KEY,
    nombre
    
    ALTER TABLE coche ADD COLUMN id_marca INT(11) NOT NULL;
    ALTER TABLE coche ADD CONSTRAINT coche__marca_FK FOREIGN KEY id_marca REFERENCES marca (id);
    De esta forma puedes tener muchos coches registrador con diferentes marcas y, si deseas cambiar la marca (porque te equivocaste en una letra, por ejemplo) solo actualizas la tabla marca y no tocas ninguna otra. Si quisieras cambiar la marca a un coche, simplemente actualizas el id_marca de la marca que deseas y no tocas nada más (UPDATE coche SET id_marca = (SELECT marca.id FROM marca WHERE marca.nombre = 'nnn') WHERE coche.id = N).

    Hay otra relación llamada 1:1, donde una entidad (dueno, coche, marca, etc.) sólo puede relacionarse con un único ente, aunque esta relación es poco frecuente y no requiere separar los datos (para que crear una tabla extra si los datos no se repetirán?).

  3. #3
    Esto empieza a ser un vicio... Habitante Avatar de Lombardo
    Fecha de Ingreso
    24 jul, 11
    Ubicación
    Austria
    Mensajes
    402
    Poder de Reputación
    17
    ¡Hola maestro! Pues de nuevo no lo comprendo

    Sí veo claro que, obteniendo tales resultados, el programa debe operar como el bucle que describes.

    Pero es que NO debe haber bucle, porque antes, en el archivo previo, hemos estipulado UNA sola fila de parámetros: la que alberga la clave 1 (o el número que sea). De esa manera, según lo entiendo yo, le decimos al programa mediante la variable $registros que busque SÓLO en la fila del elemento especificado: select * from coches where clave=''$_REQUEST[clave]'. Esto limita el campo de resultados a los datos de un solo elemento, es decir, al array creado con tales datos.

    Y ahora damos instrucciones de cambiar la marca vieja por la marca nueva, sólo dentro de ese elemento según hemos indicado en el segundo archivo: el dato con name=marcavieja corresponde según $res a la hilera encontrada conforme al input del primer archivo.

    O sea, que primero indicamos un dato único mediante input: la clave, primary key.
    Seguidamente creamos un array con los datos del elemento que responde a esa clave y a ninguna otra.
    Finalmente modificamos uno de los datos contenidos en el array.

    Es lo que debería opcurrir con ese código, no comprendo en qué punto el programa "se desmanda", olvida las instrucciones concatenadas y se lanza a examinar toda la tabla de coches, en vez de limitarse al coche con la clave que hemos indicado en el input inicial.

    ¡Muchas gracias por tu ayuda!
    Última edición por Lombardo; 02/02/2014 a las 06:41

  4. #4
    Esto empieza a ser un vicio... Habitante Avatar de Lombardo
    Fecha de Ingreso
    24 jul, 11
    Ubicación
    Austria
    Mensajes
    402
    Poder de Reputación
    17
    Aaah creo que ya lo entiendo, hay un cabo suelto en el plan... y el programa como siempre cumple las instrucciones a rajatabla, como de costumbre es un fallo humano ja ja
    ¡A ver si lo arreglo yo solo!

    Muchas gracias de nuevo, maestro

    PD:
    ...no sé como se llama en tu país el identificador del vehículo en la dirección de tránsito...
    Lo llamamos matrícula. Un saludote.

  5. #5
    Esto empieza a ser un vicio... Habitante
    Fecha de Ingreso
    02 may, 11
    Ubicación
    Santiago, Chile
    Mensajes
    2,046
    Poder de Reputación
    27
    Sé que dices que lo entiendes, pero quizás tengas una confusión con lo siguiente:

    Pero es que NO debe haber bucle, porque antes, en el archivo previo, hemos estipulado UNA sola fila de parámetros: la que alberga la clave 1 (o el número que sea). De esa manera, según lo entiendo yo, le decimos al programa mediante la variable $registros que busque SÓLO en la fila del elemento especificado: select * from coches where clave=''$_REQUEST[clave]'. Esto limita el campo de resultados a los datos de un solo elemento, es decir, al array creado con tales datos.
    PHP no funciona así...

    Los datos en las variables no persisten entre una página y otra, a no ser de que la página se este anexando a la actual a través de include/require o [include|require]_once o utilizando las variables $_SESSION, $_GLOBAL o $_COOKIE.

    Si llevamos esto a tu caso, todo lo que esta disponible en el segundo paso (en el form), no estará disponible en el tercero (en el archivo que actualmente modifica los datos). Por otro lado, las consultas SQL tampoco persisten entre una y otra:

    Código:
    // Seleccionas una columna llamada "algo"; si no se guarda en ningún lado, el valor 'algo' se pierde.
    SELECT algo FROM tabla WHERE id = N;
    
    // Actualizas ese "algo"; esta es una consulta completamente nueva, que no retiene la columna de la consulta anterior.
    UPDATE tabla SET algo = 'valor' WHERE algo = 'valor antiguo';
    
    // Habrá modificado todas columnas cuyo 'algo' haya sido igual a 'valor antiguo'.
    SELECT * FROM tabla WHERE algo = 'valor';
    Si quisieras persistir un valor en SQL (sin la ayuda de un lenguaje), tendrías que crear un script SQL:

    Código:
    // Para MySQL
    // Muestras la tabla original:
    SELECT * FROM coches;
    
    // Asignas el id a una variable SQL:
    SET @coche_id = SELECT id FROM coches WHERE clave = CLAVE;
    
    // Actualizas el registro:
    UPDATE coches SET marca = 'nueva marca' WHERE clave = @coche_id;
    
    // Vuelves a mostrar los registros
    SELECT * FROM coches;

  6. #6
    Esto empieza a ser un vicio... Habitante Avatar de Lombardo
    Fecha de Ingreso
    24 jul, 11
    Ubicación
    Austria
    Mensajes
    402
    Poder de Reputación
    17
    ¡Muchas gracias! Sí, se me hizo bastante la luz cuando antes me aclaraste que el programa buscaba en toda la tabla los coches de la marca determinada por el archivo anterior, sin limitarse al array del elemento donde fue copiada esa marca

    Imagino que se me grabará todo esto mucho mejor a base de hacer y deshacer con las tablas. ¡Gracias de nuevo, un saludote!

Temas Similares

  1. No logro insertar dato en tabla desde mi página web
    Por faustoblanco en el foro Php Bases de Datos y MySQL (Nuevo!)
    Respuestas: 0
    Último Mensaje: 24/07/2019, 15:40
  2. crear tabla que avanze sin cambiar de pagina
    Por ismakpo en el foro Foro General
    Respuestas: 6
    Último Mensaje: 22/12/2013, 18:30
  3. cambiar medida de tabla..
    Por mauro en el foro Foros
    Respuestas: 10
    Último Mensaje: 14/08/2007, 12:55

Permisos de Publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •