2012-10-11 84 views
5

Tengo un fragmento de SQL que (se podría pensar) no compilaría, pero que en su lugar borrará todas las filas de la tabla de destino.SQL Delete borra la tabla en lugar de error

Considere esta configuración:

create table TableA (ColumnA varchar(200)); 
create table TableB (ColumnB varchar(200)); 

insert TableA values ('A'),('B'),('C'); 
insert TableB values ('A'); 

A continuación, el siguiente SQL:

--Returns all rows from TableA 
select * from TableA; 

--Does not error (ColumnA does not exist on TableB) 
delete TableA where ColumnA in (select ColumnA from TableB) 

--No Rows are returned 
select * from TableA; 

La instrucción de eliminación anterior hace que todas las filas sean retirados de TableA, en lugar de erroring que ColumnA no existe en TableB

Hay un SQL Fiddle demostrando esto aquí: http://www.sqlfiddle.com/#!3/9d883/6

Parece que se está recogiendo ColumnA de TableA, pero esperaba que fuera "fuera de alcance".

¿Por qué es esto?

Respuesta

4

Eso funciona como se esperaba, debido a la correlación entre ColumnA en la consulta interna al exterior.

Este patrón de consulta correlacionada comúnmente utilizado es válido

DELETE TableA WHERE NOT EXISTS (select * from TableB where TableB.ID=TableA.ID) 

Se elimina entradas TableA que no tienen un registro dependiente de TableB.

Muestra que puede hacer referencia a columnas TableA en una consulta correlacionada. En la consulta

delete TableA where ColumnA in (select ColumnA from TableB) 

La consulta interna está produciendo

  • una fila para cada registro en la Tabla B.
  • una columna para cada fila, cuyo valor es ColumnA de consulta externa

Entonces el DELETE pasa por

3

Mientras entiendo la confusión, se está comportando como debería. ColumnA todavía está "en el alcance". De hecho, podrías unirte a él en tu subconsulta si quisieras. Los paréntesis no limitan el alcance, pero desde el punto de vista de la legibilidad puedo ver la confusión que crea.

Este es otro ejemplo de por qué es una buena idea siempre ponerle un prefijo a sus nombres de columna con el nombre de la tabla (o alias).

+2

Definitivamente no prefijo los nombres de las columnas con los nombres de las tablas, hombre que sería un esquema feo, pero definitivamente use alias ... – emalamisura

Cuestiones relacionadas