2011-01-04 11 views
9

Como siempre, habrá una explicación razonable para mi sorpresa, pero hasta entonces ....SQL Server Management Studio 2008 no comprueba la sintaxis de mi consulta

tengo esta consulta

delete from Photo where hs_id in (select hs_id from HotelSupplier where id = 142) 

que se ejecuta bien (más tarde descubrí que toda la tabla de fotos estaba vacía)

pero lo extraño: no hay campo hs_id en HotelSupplier, se llama hs_key!

Así que cuando ejecuto la última parte

select hs_id from HotelSupplier where id = 142 

separado (seleccionar esa parte de la consulta con el ratón y pulsa F5), me sale un error, pero cuando lo uso en la cláusula in, se no!

Me pregunto si esto es comportamiento normal?

Respuesta

20

Toma el valor de hs_id de la consulta externa.

Las referencias de columna no calificadas se resuelven desde el alcance más cercano hacia afuera por lo que esto solo se trata como una sub consulta correlacionada.

El resultado de esta consulta será eliminar todas las filas de Photo donde hs_id no es nulo mientras HotelSupplier tiene al menos una fila donde id = 142 (y así retorna la subconsulta al menos una fila)

podría ser un poco más claro si se tiene en cuenta lo que el efecto de esto es

delete from Photo where Photo.hs_id in (select Photo.hs_id) 

esto es, por supuesto, equivalente a

delete from Photo where Photo.hs_id = Photo.hs_id 

Por cierto, este es de lejos el "error" más común que personalmente he visto erróneamente informado en Microsoft Connect. Erland Sommarskog lo incluye en su wishlist para SET STRICT_CHECKS ON

+5

+1 - Solo quería señalar explícitamente una buena práctica en su ejemplo, incluidos los nombres de tabla para cada una de las columnas (dos partes identificadores) a lo largo de su consulta. ¡Buena práctica en general, práctica invaluable en las declaraciones de eliminación! –

+1

Gracias, no lo sabía. Aunque es extraño, eso (en tu versión simplificada también) el notn-existing 'select Photo.hs_id' no genera un error – Michel

+2

@Michel - No es inexistente. Se trata como una subconsulta correlacionada y se evalúa para cada fila utilizando el valor transferido desde la consulta externa. –

1

Es un fuerte argumento para mantener los nombres de columnas consistentes entre las tablas. Como dice @Martin, la sintaxis de SQL permite que los nombres de columna se resuelvan desde la consulta externa, cuando no hay coincidencia en la consulta interna. Esto es una bendición cuando se escriben subconsultas correlacionadas, pero puede ocasionalmente tropezarle (como aquí)

+0

sí, estoy totalmente de acuerdo, la constancia en este db está muy lejos. textkey, textid, text_key, text_id, hsid, hs_id etc. brrrrr – Michel

+0

Por supuesto, eso no ayuda si escribe el nombre incorrecto de la tabla que no tiene ningún derecho – Kevin

Cuestiones relacionadas