środa, 18 stycznia 2012

Usuń tabelę z tabel systemowych

Chciałem dalej kontynuować poprzedni wątek dotyczący blokowania zasobów. Wszystko jednak diabli wzięli. Otóż musiałem interweniować dzisiaj po tym jak do systemu wdarła się poprawka powodująca, że główna funkcjonalność systemu przestała działać. Tak więc dzisiaj będzie o tym jak nie usuwać danych z bazy.
Załóżmy, że mamy następujace dane
   1: CREATE TABLE SYSTEM_TABLES (
   2:     TABLE_NAME VARCHAR(126)
   3: )
   4:  
   5: CREATE TABLE SYSTEM_SETTINGS (
   6:     NAME VARCHAR(100),
   7:     VALUE NVARCHAR(20)
   8: )
   9:  
  10: CREATE TABLE INTEREST_RATES (
  11:     NAME VARCHAR(20),
  12:     VALUE DECIMAL(4,2)
  13: )
  14:  
  15: INSERT INTO SYSTEM_TABLES VALUES('SYSTEM_SETTINGS')
  16: INSERT INTO SYSTEM_TABLES VALUES('INTEREST_RATES')

  17: INSERT INTO SYSTEM_SETTINGS
  18: SELECT 'Language', 'English' UNION
  19: SELECT 'AnonymousUsers', '0' UNION
  20: SELECT 'StrongPassword', '1' UNION
  21: SELECT 'PasswordHistory', '3' 
  22:  
  23: INSERT INTO INTEREST_RATES
  24: SELECT 'Reference', 4.5 UNION
  25: SELECT 'Lombard', 6.0 UNION
  26: SELECT 'Deposit', 3.0 UNION
  27: SELECT 'Rediscount', 4.75

Tabela SYSTEM_TABLES przechowuje nazwy tabel istotnych dla funkcjonowania systemu. Z różnych powodów jedną z tych tabel (INTEREST_RATES) trzeba było usunąć z SYSTEM_TABLES.

Banalne z pozoru zapytanie, a wykonane niepoprawnie spowodowało, że system przestał działać.

DELETE z iloczynem kartezjańskim

Mały quiz teraz. Jaki będzie rezultat poniższego zapytania
   1: DELETE INTEREST_RATES FROM SYSTEM_TABLES
Możliwe odpowiedzi:
  1. Błąd składni
  2. Zapytanie się wykona ale nic nie zostanie usunięte
  3. Rekord INTEREST_RATES zostanie usunięy z SYSTEM_TABLES
  4. Cała zawartość tabeli INTEREST_RATES zostanie usunięta
Zachęcam do komentowania, bez uprzedniego testowania zapytania

No, dobra odpowiem sam na to pytanie. Otóż poprawna odpowiedź to ta oznaczona nr 4.

Składnia zapytania jest jak najbardziej poprawna. Jeżeli byłoby to zapytanie SELECT to jego postać byłaby następująca.
   1: SELECT * FROM INTEREST_RATES, SYSTEM_TABLES

Jest to nic innego jak iloczyn kartezjański.

Z tym, że założenie było takie aby usunąć tylko jeden rekord z SYSTEM_TABLES w następujący sposób
   1: DELETE SYSTEM_TABLES WHERE TABLE_NAME = 'INTEREST_RATES'

Tutaj aż się prosi aby dołączyć referencje do mojego pierwszego postu dotyczącego podstaw SQL. Prawdę mówiąc nie myślałem, że tak szybko będę musiał powracać to tego tematu.

I na koniec jeszcze jedna ciekawostka. W języku angielskim polecenie mogłoby przybrać następującą postać:

You must DELETE INTEREST_RATES FROM SYSTEM_TABLES to make this feature working

Język programowania i naturalny maja dużo ze sobą wspólnego. Tylko, że czasami rezultat może być inny od oczekiwanego.

Prześlij komentarz