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

Hola de nuevo!

No hay fallo.

Explicación

Supongamos la siguiente tabla:

[B]coches[/B]
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í:

marcanueva: Honda
marvavieja: Honda

Modificas marcanueva, quedando con Porsche y haces clic sobre Cambiar, la consulta quería así:

UPDATE coches SET marca = 'Porsche' WHERE marca = 'Honda';

Entonces, el motor de base de datos recorrerá las filas y hará algo así:

Primera fila (id = 1, marca = Honda): [I]marca[/I] es igual a [I]Honda[/I]? Sí, por ende, se cambia a [I]Porsche[/I].
Segunda fila (id = 2, marca = Hyundai): [I]marca[/I] es igual a [I]Honda[/I]? No, así que [B]no se hace nada[/B].
Tercera fila (id = 3, marca = Honda): [I]marca[/I] es igual a [I]Honda[/I]? Sí; se cambia a [I]Porsche[/I].
Cuarta fila (id = 4, marca = Honda): [I]marca[/I] es igual a [I]Honda[/I]? Sí; se cambia a [I]Porsche[/I].
Quinta fila (id = 5, marca = Chevrolet): [I]marca[/I] es igual a [I]Honda[/I]? No; [B]no se modifica[/B].
Sexta fila (id = 6, marca = Ferrari): [I]marca[/I] es igual a [I]Honda[/I]? No; [B]No se modifica[/B].

¿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:

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í:

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?).
¡Hola maestro! Pues de nuevo no lo comprendo :confused:

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'. 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! [:)]
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.
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'. 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:

// 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:

// 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;
¡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!