Mam 4 stoły. W pierwszej tabeli ma appid jako klucz podstawowy, aw pozostałych trzech jego klucz obcy. Chcę usunąć dane ze wszystkich trzech w jednym zapytaniu. Próbowałem wszystkiego, ale nie udało mi się. Czy ktoś może pomóc?

5
sam 16 sierpień 2011, 14:09
To jest problem, do rozwiązania którego wymyślono działanie referencyjne ON DELETE CASCADE. W przeciwieństwie do @Tony Andrews, polecam to jako ogólną praktykę.
 – 
onedaywhen
16 sierpień 2011, 16:30

3 odpowiedzi

Najlepsza odpowiedź

Nie możesz napisać instrukcji usuwania, która odwołuje się do więcej niż jednej tabeli, musisz napisać 4 instrukcje usuwania.

Jednak w razie potrzeby można zdefiniować klucze obce w 3 tabelach podrzędnych na „ON DELETE CASCADE”. Następnie, gdy usuniesz z tabeli nadrzędnej, wszystkie powiązane wiersze z 3 tabel podrzędnych również zostaną usunięte. Czasami może to być przydatne, ale nie polecałbym tego jako ogólnej praktyki, ponieważ może być niebezpieczne i mylące dla programistów.

10
Tony Andrews 16 sierpień 2011, 14:16
Czy możesz omówić niebezpieczną i mylącą naturę kaskadowych kluczy obcych? Ponieważ jestem trochę zaskoczony tą uwagą.
 – 
Rene
16 sierpień 2011, 17:01
2
@Rene, OK, tak się składa, że ​​obecnie pracuję nad projektem, w którym ktoś ustawił wiele kluczy obcych jako ON DELETE CASCADE. Na przykład, jeśli użytkownik zrobi coś takiego jak DELETE order_status_lookup WHERE status_code = 'SHIPPED', to się powiedzie, a wszystkie zamówienia ze statusem „WYSŁANE” również zostaną usunięte. Nazywam to ale niebezpiecznym! Właściwie używam ON DELETE CASCADE, ale tylko tam, gdzie ma to sens.
 – 
Tony Andrews
16 sierpień 2011, 17:07
Mówisz więc, że jest to narzędzie, które może być bardzo przydatne, ale użyte w niewłaściwy sposób może wyrządzić szkody. Trochę jak piła łańcuchowa, prawda? Ale czy w takim razie zaleciłbyś ręczne wycinanie wszystkich tych drzew?
 – 
Rene
17 sierpień 2011, 13:13
Za żadne pieniądze nie tknąłbym piły łańcuchowej! ;-)
 – 
Tony Andrews
17 sierpień 2011, 13:24
I powiedziałem w mojej odpowiedzi „to może się czasem przydać”, nie powiedziałem „nigdy”, prawda?
 – 
Tony Andrews
17 sierpień 2011, 13:30

Nie ma możliwości usunięcia z wielu tabel za pomocą jednej instrukcji, ale lepszym pytaniem jest to, dlaczego musisz usuwać wszystkie tabele jednocześnie? Wydaje mi się, że nie do końca rozumiesz, jak działają transakcje w Oracle.

Powiedzmy, że logujesz się i usuwasz wiersz z tabeli 1, ale nie zatwierdzasz. Jeśli chodzi o wszystkie inne sesje, ten wiersz nie został usunięty. Jeśli otworzysz inne połączenie i zapytasz o wiersz, nadal tam będzie.

Następnie usuwasz kolejno tabele 2, 3, a następnie 4. Nadal nie zatwierdziłeś transakcji, więc wszystkie inne sesje w bazie danych nadal mogą zobaczyć usunięte wiersze.

Wtedy zobowiązujesz się.

W tym samym czasie inne sesje nie będą już widzieć wierszy usuniętych z 4 tabel, mimo że usunięcia zostały wykonane w 4 oddzielnych instrukcjach.

3
Stephen ODonnell 16 sierpień 2011, 14:50
4
Myślę, że jesteś trochę szorstki. Widzę zalety w składni DELETE ALL analogicznej do INSERT ALL: fajnie byłoby przełączyć wszystkie powiązane rekordy w zestawie tabel bez martwienia się o zależności i bez używania odroczonych ograniczeń. (Chociaż przyznaję, że potrzebuję tego zwykle w zarządzaniu danymi testowymi, a nie w środowiskach produkcyjnych).
 – 
APC
16 sierpień 2011, 15:17

Jeśli bazą danych jest Mysql, możesz użyć join w instrukcji DELETE. Zobacz http://dev.mysql.com/doc/refman/5.0/ pl/delete.html, aby uzyskać więcej informacji.

-2
Andrej Ludinovskov 16 sierpień 2011, 15:37
Oprócz innego komentarza (transakcja lub użycie kaskady usuwania) możesz użyć wyzwalacza do usunięcia z tabel podrzędnych.
 – 
Andrej Ludinovskov
16 sierpień 2011, 17:51