Załóżmy, że posiadamy dwie tabelki posiadające te same pola. Dla uproszczenia o to kod do ich stworzenia:
CREATE TABLE #TEST1 ([ID] INT,[IDN] VARCHAR(200))
INSERT INTO #TEST1 VALUES (1,'Jeden')
INSERT INTO #TEST1 VALUES (2,'Dwa')
INSERT INTO #TEST1 VALUES (3,'Trzy')
INSERT INTO #TEST1 VALUES (4,'Cztery')
INSERT INTO #TEST1 VALUES (5,'Pięć')
INSERT INTO #TEST1 VALUES (6,'Sześć')
INSERT INTO #TEST1 VALUES (7,'Siedem')
INSERT INTO #TEST1 VALUES (8,'Osiem')
INSERT INTO #TEST1 VALUES (9,'Dziewięć')
INSERT INTO #TEST1 VALUES (10,'Dziesięć')
CREATE TABLE #TEST2 ([ID] INT,[IDN] VARCHAR(200))
INSERT INTO #TEST2 VALUES (3,'Trzy')
SELECT * FROM #TEST1
SELECT * FROM #TEST2
Powiedzmy, że teraz z tabelki #TEST1 chcemy usunąć te wartości, które znajdują się także w tabeli #TEST2. Wykonujemy więc bardzo prosty kawałek kodu:
DELETE FROM #TEST1 WHERE [IDN] IN (SELECT [IDN] FROM #TEST2)
Po usunięciu sprawdzamy co zostało nam w tabeli #TEST1:
SELECT * FROM #TEST1
Wynik jest taki jak chcieliśmy nie ma rekordu z wartością 3. Załóżmy, że jakiś nieznany osobnik skasował w naszej tabeli #TEST2 kolumnę [IDN] i ponownie dodał wartość 3 do tabeli #TEST1
ALTER TABLE #TEST2 DROP COLUMN [IDN]
INSERT INTO #TEST1 VALUES (3,'Trzy')
Ponieważ w naszej tabeli #TEST1 ponownie pojawiła się wartość 3 chcemy ją znów usunąć. Ponieważ nie wiemy, że nasz złoczyńca skasował kolumnę [IDN] wykonujemy polecenie kasujące, z którego korzystaliśmy poprzednio. Zapewne część z was spodziewa się tego, że wynikiem takiego kasowania będzie błąd ponieważ nie ma już kolumny [IDN] w tabeli #TEST2..
Jeżeli wykonaliście już kod wiecie, że niestety nic takiego się nie stanie. Zamiast tego z tabeli #TEST1 zostaną skasowane wszystkie wpisy! Jeżeli zadajecie sobie pytanie „ALE DLACZEGO !!” odpowiedź jest bardzo prosta. Ponieważ SQL Server nie znalazł w tabeli #TEST2 kolumny [IDN] założył, że należy znaleźć inną kolumnę [IDN] i znalazł ją w tabeli #TEST1 co spowodowało że zapytanie kasujące było zinterpretowane tak samo jak następujące zapytanie:
DELETE FROM #TEST1 WHERE [IDN] IN [IDN]
Co oczywiście skasuje wszystkie wpisy w tabeli #TEST1. Jak uniknąć takich sytuacji ? Korzystaj z aliasów lub pełnych nazw w takich przypadkach. Wystarczy aby nasze zapytanie kasujące było zbudowane w następujący sposób:
DELETE FROM #TEST1 WHERE [IDN] IN (SELECT T2.[IDN] FROM #TEST2 T2)
Po wywołaniu tego zapytania zamiast skasować cokolwiek w tabeli #TEST1 dostaniemy następujący błąd:
Msg 207, Level 16, State 1, Line 1
Invalid column name ‘IDN’.
Co w założonej sytuacji jest jak najbardziej poprawne.