Tag: T-SQL

[T-SQL] Korzystaj z aliasów bo…

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.


[T-SQL] Odnajdywanie obiektów stystemowych

SQLServer Wpis z cyklu „ku pamięci”. Ostatnio szukałem metody odnajdywania w bazie danych wszystkich obiektów systemowych (procedur, widoków, funkcji itp). W przypadku table problem ten jest wręcz trywialny wystarczy wykonać następujące zapytanie: (continue reading…)


[T-SQL] Sklejanie stringów z zapytania

SQLServerPonieważ ostatnio często w moim otoczeniu pojawiało się pytanie „Jak skleić wartości z jednej kolumny w ciąg znaków oddzielonych przecinkami” postanowiłem przedstawić jedną z najszybszych metod na zrealizowanie tego zadania (oczywiście nie jest ona pozbawiona wad): (continue reading…)


Copyright © 1996-2010 [ko{pro}wski]. All rights reserved.
iDream theme by Templates Next | Powered by WordPress