2011-01-04 1 views
9

Come sempre, ci sarà una spiegazione ragionevole per la mia sorpresa, ma fino a quel momento ....sql studio dell'amministrazione Server 2008 non controllando la sintassi della mia interrogazione

ho questa query

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

che esegue perfettamente (più tardi ho scoperto che l'intero tavolo fotografico era vuoto)

ma la cosa strana: non c'è campo hs_id in HotelSupplier, si chiama hs_key!

Così, quando eseguo l'ultima parte

select hs_id from HotelSupplier where id = 142 

separatamente (selezionare la parte della query con il mouse e premere F5), ottengo un errore, ma quando lo uso nella clausola in, si non lo fa!

Mi chiedo se questo è un comportamento normale?

risposta

20

Sta prendendo il valore di hs_id dalla query esterna.

I riferimenti di colonna non qualificati vengono risolti dall'ambito più esterno verso l'esterno, in modo che questo venga trattato come una query secondaria correlata.

Il risultato di questa ricerca sarà eliminare tutte le righe da Photo dove hs_id non è nulla finché HotelSupplier ha almeno una fila dove id = 142 (e quindi la sottoquery restituisce almeno una riga)

potrebbe essere un po 'più chiaro se si considera che l'effetto di questo è

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

questo è naturalmente equivalente a

delete from Photo where Photo.hs_id = Photo.hs_id 

Ad ogni modo questo è di gran lunga il "bug" più comune che personalmente ho visto erroneamente riportato su Microsoft Connect. Erland Sommarskog lo include nel suo wishlist per SET STRICT_CHECKS ON

+5

+1 - Volevo solo indicare esplicitamente una buona pratica nell'esempio, inclusi i nomi delle tabelle per ciascuna colonna (in due parti identificatori) nell'intera query. Buone pratiche in generale, pratica inestimabile nelle dichiarazioni di cancellazione! –

+1

Grazie, non lo sapevo. Però è strano, però, che (anche nella tua versione semplificata) il notn-esistente 'seleziona Photo.hs_id' non generi un errore – Michel

+2

@Michel - Non è inesistente. Viene trattata come una query secondaria correlata e valutata per ogni riga utilizzando il valore passato dalla query esterna. –

1

È un argomento valido per mantenere coerenti i nomi delle colonne tra le tabelle. Come dice @Martin, la sintassi SQL consente di risolvere i nomi delle colonne dalla query esterna, quando non c'è corrispondenza nella query interna. Questo è un vantaggio quando si scrivono sottoquery correlate, ma a volte si può incalzare (come qui)

+0

sì, assolutamente d'accordo, la consistenza di questo db è lontana. textkey, textid, text_key, text_id, hsid, hs_id, ecc. brrrrr – Michel

+0

Ovviamente, questo non aiuta se si digita il nome di una tabella errata che non ha il diritto – Kevin