como reemplazo un registro en una db?

Iniciado por Cergath, 24 Noviembre 2009, 01:49 AM

0 Miembros y 1 Visitante están viendo este tema.

Cergath

pues tengo un registro, que se replica en muuuchas partes de la base de datos, miles de veces.... deseo cambiar ese registro en todas las tablas y demás... como lo podría hacer?... no veo que con phpmyadmin pueda...

^Tifa^

Es el unico registro que se miles de veces en ese mismo campo? o hay mas que se repiten en ese mismo campo????

Si es 1 registro que se repite miles de veces en ese mismo campo, algo como esto podria servirte:

Código (sql) [Seleccionar]


mysql> select * from Respuesta;
+------------+--------+--------------------------------------+
| id_usuario | id_res | respuesta                            |
+------------+--------+--------------------------------------+
|          1 |      1 | Es blanco por su iluminacion interna |
|          1 |      1 | Entonces porque cambia a amarillo    |
|          1 |      1 | por efecto de alejacion              |
|          2 |      2 | por la gravedad                      |
|          2 |      2 | Por la densidad                      |
+------------+--------+--------------------------------------+
5 rows in set (0.00 sec)   

mysql> update Respuesta set id_usuario = 22 where id_usuario < 2;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> select * from Respuesta;
+------------+--------+--------------------------------------+
| id_usuario | id_res | respuesta                            |
+------------+--------+--------------------------------------+
|         22 |      1 | Es blanco por su iluminacion interna |
|         22 |      1 | Entonces porque cambia a amarillo    |
|         22 |      1 | por efecto de alejacion              |
|          2 |      2 | por la gravedad                      |
|          2 |      2 | Por la densidad                      |
+------------+--------+--------------------------------------+
5 rows in set (0.00 sec)



Resumido : UPDATE TABLA SET CAMPO = VALOR WHERE CAMPO < 2;

Asi todos los registros de ese campo que se repitan mas de 2 veces hacia adelante seran todos sustituidos por el valor nuevo que le asignes.

Cergath

:( el problema es que el valor que quiero cambiar puede estar en cualquier parte, no solo en "id_usuario" por ejemplo.. ¿como podría hacer para que busque en todas partes ese valor?

^Tifa^

#3
vaya...

El problemita aca entonces Cergath es que para buscar en una tabla cualquier registro, siempre debes anteponer un predicado especificando el campo donde haras esa busquedad. Por ejemplo, no es posible hacer una consulta de este estilo en el SQL general:

Código (sql) [Seleccionar]
    SELECT * FROM TABLE WHERE * = VALOR   

En respuesta a tu pregunta, quieres buscar un valor en toda una tabla? tendras que asignar dicho valor a buscar a cada uno de los campos de la tabla o tablas en la cual estas realizando la busquedad.

Mas o menos asi:

Código (sql) [Seleccionar]
mysql> select * from Respuesta where id_usuario = 22 and id_res = 22;
 


Para que busque campo por campo donde exista ese valor, por ejemplo:

Código (sql) [Seleccionar]


mysql> select * from Respuesta;
+------------+--------+--------------------------------------+
| id_usuario | id_res | respuesta                            |
+------------+--------+--------------------------------------+
|         22 |      1 | Es blanco por su iluminacion interna |
|         22 |      1 | Entonces porque cambia a amarillo    |
|         22 |      1 | por efecto de alejacion              |
|          2 |      2 | por la gravedad                      |
|          2 |      2 | Por la densidad                      |
|          3 |      2 | bla bla                              |
|          3 |      2 | bla bla                              |
|          3 |      2 | bla bla                              |
|          3 |      2 | bla bla                              |
+------------+--------+--------------------------------------+
9 rows in set (0.00 sec)

mysql> select * from Respuesta where id_usuario = 3 and id_res = 2 having(id_usuario) > 2;
+------------+--------+-----------+
| id_usuario | id_res | respuesta |
+------------+--------+-----------+
|          3 |      2 | bla bla   |
|          3 |      2 | bla bla   |
|          3 |      2 | bla bla   |
|          3 |      2 | bla bla   |
+------------+--------+-----------+
4 rows in set (0.00 sec)



Ahora suponiendo que el valor 2 se repite en otra tabla ademas de la ante expuesta, serian 1 join de 2 tablas, donde id_usuario se repitiese mas de 2 veces.

Código (sql) [Seleccionar]


mysql> select * from Libro;
+----------+--------------------+---------------------------------+
| id_libro | titulo             | pregunta                        |
+----------+--------------------+---------------------------------+
|        1 | Como es el Sol?    | Quisiera saber porque es blanco |
|        2 | Como es la lluvia? | Porque es transparente          |
|        3 | Juego Favorito     | Cual me recomiendan             |
+----------+--------------------+---------------------------------+
3 rows in set (0.00 sec)

mysql> select * from Respuesta inner join Libro where id_usuario = 3 and id_res = 2 and id_libro = id_res having(id_usuario) > 2;
+------------+--------+-----------+----------+--------------------+------------------------+
| id_usuario | id_res | respuesta | id_libro | titulo             | pregunta               |
+------------+--------+-----------+----------+--------------------+------------------------+
|          3 |      2 | bla bla   |        2 | Como es la lluvia? | Porque es transparente |
|          3 |      2 | bla bla   |        2 | Como es la lluvia? | Porque es transparente |
|          3 |      2 | bla bla   |        2 | Como es la lluvia? | Porque es transparente |
|          3 |      2 | bla bla   |        2 | Como es la lluvia? | Porque es transparente |
+------------+--------+-----------+----------+--------------------+------------------------+
4 rows in set (0.00 sec)



En caso de que quieras actualizar el valor '2' de las 2 tablas expuestas anteriormente (Libro y Respuestas) Mas o menos se haria asi:

Código (sql) [Seleccionar]

mysql> update Respuesta, Libro set Respuesta.id_res = 60, Libro.id_libro = 60 where Respuesta.id_usuario > 2 and Respuesta.id_res = 2;

mysql> select * from Respuesta;
+------------+--------+--------------------------------------+
| id_usuario | id_res | respuesta                            |
+------------+--------+--------------------------------------+
|         22 |      1 | Es blanco por su iluminacion interna |
|         22 |      1 | Entonces porque cambia a amarillo    |
|         22 |      1 | por efecto de alejacion              |
|          2 |      2 | por la gravedad                      |
|          2 |      2 | Por la densidad                      |
|         55 |     60 | bla bla                              |
|         55 |     60 | bla bla                              |
|         55 |     60 | bla bla                              |
|         55 |     60 | bla bla                              |
+------------+--------+--------------------------------------+
9 rows in set (0.00 sec)

mysql> select * from Libro;
+----------+--------------------+---------------------------------+
| id_libro | titulo             | pregunta                        |
+----------+--------------------+---------------------------------+
|       60 | Como es el Sol?    | Quisiera saber porque es blanco |
|        2 | Como es la lluvia? | Porque es transparente          |
|        3 | Juego Favorito     | Cual me recomiendan             |
+----------+--------------------+---------------------------------+
3 rows in set (0.00 sec)



Resultara un poco incomodo, pero no hay una llave magica que busque 1 valor especifico en todos los campos de una o mas tablas a la vez (Al menos yo particularmente no conozco la manera si otr@ la conoce bienvenida sea) Puedes en su lugar idear algo ya sea a traves de lenguaje de programacion en un bucle ir comparando el dato buscado con todos los campos de una tabla o algo asi, o hacer una consulta SQL un poco larga pero que te permita buscar un dato en todos los campos de una o mas tablas.

MazarD

#4
Como ya comentaba ^TiFa^ no puedes substituir un valor en toda la base de datos así por las buenas, además resulta bastante extraño y a la vez peligroso necesitar hacer eso, pero en fin, una buena solucion es utilizar un stored procedure de mysql (a partir de la version 5), consultar information_schema.columns para saber todas las columnas de cada tabla en la base de datos y construir un update dinámicamente para substituir los valores.

Dejo un ejemplo, hay que testearlo porque seguro tiene 20 errores ya que lo programo al vuelo, pero para entender la idea ya sirve:

Código (sql) [Seleccionar]
CREATE PROCEDURE substitucion(IN viejo varchar(128), IN nuevo varchar(128))
BEGIN
DECLARE ctabla CURSOR FOR
SELECT table_name, column_name
FROM information_schema.columns;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET fin = 1;
OPEN ctabla;
REPEAT FETCH ctabla INTO tabla, columna;
SET @sql := CONCAT('update ', tabla, ' set ',columna,' = ',nuevo, ' where ', columna,' = ', viejo);
PREPARE stmt FROM @sql;
EXECUTE stmt;
UNTIL fin = 1
END REPEAT;
CLOSE ctabla;
END;

-Learn as if you were to live forever, live as if you were to die tomorrow-

http://www.mazard.info
http://twitter.com/MazarD
irc://irc.freenode.org/elhacker.net

Filibustero de bolsillo

Hola,

Es posible buscar algo en la DB y reemplazar el registro, sin embargo, en caso de hacer eso con un script por ejemplo, si modificas un valor importante, podrías dañar la caché, luego de eso tendrías que reconstruirla. Es por eso que muchos scripts traen herramientas/tools para bajar de sus webs que se encargan de eso.

Este script en PHP te permitirá conectarte a la base de datos y modificar un valor dentro de ella, hará todo global, mucho cuidado, haz un backup porque podrías dañar la base de datos.

http://www.whitesystem.net/assets_permanent/reemplazar.zip

Espero que pueda ser de utilidad.
Un saludo.

Absence makes the heart grow fonder.

^Tifa^

#6
Aunque no he visto dicho script php, espero que no sea muy cruel o danino, el usuario que inicio el post quiere algo automatico para buscar un mismo registro repetido en una, dos, tres o mas tablas en todos sus campos.... eso hasta lo que se de la forma tan automatica como el lo quiere no es posible. Los scripts pueden ayudar (sabiendo lo que se hace) igual como un procedimiento almacenado (sabiendo tambien lo que se hace) o opcionalmente puede hacerlo en una consulta SQL como le mostre, decision personal de el cual le quede mejor.

Citarsi modificas un valor importante, podrías dañar la caché, luego de eso tendrías que reconstruirla.

Este punto no me aclaro, si hablamos de MySQL (que no sabemos bajo que motor de DB el chico esta trabajando) pero si hicieramos referencia a MySQL, y si el realmente tiene activa la cache del motor se reseteara siempre que haga un insert, update o delete.... por ende estara constantemente defragmentando la cache y eso causa sobrecarga de I/O en disco, la cache es buena tenerla activa si hacemos referencia a una datawarehouse o similar, de lo contrario para un hosting lo mejor es desabilitarla o en su lugar usar una herramienta de terceros como memcache como API en php o funciones memcached dentro de MySQL como una funcion UDF entre varios servidores para compartir la carga (funcionamiento similar a MySQL cluster). Pero eso ya es otro tema independiente al peticionado por el...

Filibustero de bolsillo

#7
Los dos métodos son prácticos y el script busca y reemplaza, cumple las funciones de comando, puedes analizar los ficheros para que veas como es su funcionamiento.


Tienes razón.
Perdona no leer todo tu segundo párrafo, hablaré en pro de scripts como IPBoard que luego de una alteración severa en la base de datos necesitará un rebuild del script, con medios externos porque hasta las aplicaciones internas se "dañan", este es un ejemplo del error que daría IPBoard en caso de cambiar simplemente el nombre del sitio de manera global (replicandose post por post)

Código (php) [Seleccionar]

/**
* Set up settings
*
* @return void
* @author MattMecham
* @access protected
*/
protected function setUpSettings()
{
$settings_cache = self::$handles['caches']->getCache('settings');

if ( ! is_array( $settings_cache ) OR ! count( $settings_cache ) )
{
throw new Exception( "Could not initiate the registry, the settings cache is empty or missing" );
}

foreach( $settings_cache as $k => $v )
{
ipsRegistry::$settings[$k] = $v;
}


Respuesta a TiFa en la última entrada
Hola TiFa, así cómo tu dices, "no hay que desvirtuar el tema", prefiero ceder a tener que iniciar una discución (discución no implica una pelea, sino dualismo) y tener que dar otro camino al tema, arreglemos esto en privado  >:( >:( jaja es broma ... nos vemos a la salida

Cergath, confía en que cualquiera de los métodos funcionará, tu usa el que te te quede más accesible y/o práctico.

Absence makes the heart grow fonder.

^Tifa^

#8
Hola Danfe, espero no desvirtuar mucho este tema. El codigo que pegaste obtiene los valores desde la cache de MySQL??? y los cambia segun los valores encontrados dentro de la cache de MySQL?????. No entiendo mucho php , pero si este codigo trabaja en base a la cache de MySQL no indica que sea siempre efectivo.

Por ejemplo, no siempre la cache en MySQL esta activa (se puede iniciar con esta desabilitada) suponiendo que si, que esta activa mira un ejemplo de mi cache en MySQL y lo que te digo:

Código (sql) [Seleccionar]


mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16768408 |
| Qcache_hits             | 0        |
| Qcache_inserts          | 0        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 4        |
[b]| Qcache_queries_in_cache | 0        |[/b]
| Qcache_total_blocks     | 1        |
+-------------------------+----------+
8 rows in set (0.00 sec)               

mysql> select * from Libro;

mysql> select * from Respuesta;
mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16765336 |
| Qcache_hits             | 0        |
| Qcache_inserts          | 2        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 6        |
[b]| Qcache_queries_in_cache | 2        |[/b]
| Qcache_total_blocks     | 7        |
+-------------------------+----------+
8 rows in set (0.00 sec)


| Qcache_queries_in_cache | 0        |
| Qcache_queries_in_cache | 2        |

Hago referencia al resultado en negrita obtenida de la cache (La cache en MySQL va guardando peticiones en memoria siempre que se use SELECT pero se resetea completamente al usar otra clausula (digase INSERT, DELETE, UPDATE)

Código (sql) [Seleccionar]


mysql> insert into Libro values(5,'no se', 'nananana');
Query OK, 1 row affected (0.00 sec)

mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 2        |
| Qcache_free_memory      | 16766872 |
| Qcache_hits             | 0        |
| Qcache_inserts          | 2        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 8        |
[b]| Qcache_queries_in_cache | 1        |[/b]
| Qcache_total_blocks     | 5        |
+-------------------------+----------+
8 rows in set (0.00 sec)


| Qcache_queries_in_cache | 1        |


Nuevamente recalco en la negrita, vez como elimino 1 registro del cache (que tenia 2 valores) al yo utilizar INSERT? si utilizo otra clausula como UPDATE o DELETE ese ultimo registro que queda tambien sera eliminado de cache, y al retornar a hacer un SELECT este nuevo dato volvera a guardarse en cache, y luego al usar insert, delete o update voila... a eliminar..

No es recomendable en situaciones donde haya mucha solicitud de escritura o actualizacion de una DB (Al menos MySQL) activar la cache del motor, es preferible tenerla en estos casos desactivada. Asi te evitas lecturas constantes de disco (tanto en escritura como lectura y eliminacion).