12
Los accidentes suelen ocurrir, pero para un DBA, que se te borren todos los campos de una tabla de 1 millón de registros cuando querías borrar solo 100 mil, es un accidente que no se puede dar el lujo de cometer.
No se si en otros DBMS sucede esto, pero en Postgres 8.1 no veo la razón por la que sucede, pero de cualquier forma, aquí les dejo el tip para que no les pase.
Si tenemos una la tabla deletemasivo con la siguiente estructura:
Column | Type --------+--------- id | integer nombre | text
y con bastantes datos, y nosotros quisieramos todos los datos cuyo id este en otra tabla. Por ejemplo:
Column | Type --------+--------- id2 | integer nombre | text
Probablemente lo que haríamos sería:
delete from deletemasivo where id in (select id2 from otratabla);
El problema es que puede que nos equivoquemos y pongamos algo como:
delete from deletemasivo where id in (select id from otratabla);
Nótese que id no existe en otratabla, y que si se intenta ejecutar nos daría como resultado.
tipsdeaweb=# select id from otratabla; ERROR: column "id" does not exist
Pero si lo ejecutamos dentro del “delete from deletemasivo where id in (select id from otratabla);” si lo deja ejecutar y borra todo cuanto haya en la tabla deletemasivo.
El resultado es:
tipsdeaweb=# delete from deletemasivo where id in (select id from otratabla); DELETE 38
Y taráaan!!… Se perdieron todos los datos de esa tabla (que en este caso son 38).
Lo mejor sería hacer el delete de la siguiente manera. Pues da el resultado esperado.
tipsdeaweb=# delete from deletemasivo using otratabla where deletemasivo.id = otratabla.id2; DELETE 9
Así que hagan backup de sus Bases de Datos seguido y traten de no cometer errores como estos, por lo menos, no en Postgres 8.1.
Como siempre les dejo los scripts para no cometer un Delete masivo por error.
Saludos.
Gracias por el dato, generalmente yo utilizo mysql y no he tenido la necesidad por el momento, de borrar datos de esta forma, sin embargo voy a tomarlo en cuenta y haré algunas pruebas antes.
Saludos, gracias por los Tips
Ves Rene porque te decia: “Siempre que vas a hacer un DDL acostumbrate a usar BEGIN… SAVEPOINT… COMMIT/ROLLBACK”? Al parecer el comportamiento de PostgreSQL no es algo estandar, de hecho la documentación dice que no es estandar para nada en cuanto al delete. Realmente lo que sucede es que en sentencias DELETE PostgreSQL trata de hacer un join entre las dos tablas (en tu caso deletemasivo y otratabla) e id es una columna valida en el resultado del join (o sea, la union de otratabla y deletemasivo). Segun la documentacion de PostgreSQL se debe preferir la sentencia USING ante la IN (quizás porque estas explicitamente refiriendote al USING), No tengo un PgSQL instalado actualmente, así que no podría enviarte un pedazo de codigo extraño para probarlo, pero creo que ese es la razón inmediata. De todos modos ya hay una buena razón más para usar transacciones
(tomando en cuenta que operaciones de borrado son más rápidas dentro de una transacción), a menos claro que estes usando una triste MySQL 