Jak korzystać z usuwania kaskadowego w programie SQL Server?

332

Mam 2 tabele: T1 i T2, są to tabele z danymi. Mamy relację jeden do wielu między T1 i T2. Jak zmienić definicje tabeli, aby wykonać kaskadowe usuwanie w programie SQL Server po usunięciu rekordu z T1, wszystkie powiązane rekordy w T2 również zostaną usunięte.

Między nimi istnieje obce ograniczenie. Nie chcę upuszczać tabel ani tworzyć wyzwalacza, aby usunąć T2. Na przykład, kiedy usuwam pracownika, wszystkie zapisy recenzji również powinny zniknąć.

T1 - pracownik,

Employee ID      
Name
Status

T2 - Oceny wydajności,

Employee ID - 2009 Review
Employee ID - 2010 Review
Bichvan Nguyen
źródło

Odpowiedzi:

362

Będziesz musiał,

  • Usuń istniejące ograniczenie klucza obcego,
  • Dodaj nowy z ON DELETE CASCADEwłączonym ustawieniem.

Coś jak:

ALTER TABLE dbo.T2
   DROP CONSTRAINT FK_T1_T2   -- or whatever it's called

ALTER TABLE dbo.T2
   ADD CONSTRAINT FK_T1_T2_Cascade
   FOREIGN KEY (EmployeeID) REFERENCES dbo.T1(EmployeeID) ON DELETE CASCADE
marc_s
źródło
3
Mój zespół i ja właśnie to zrobiliśmy. Musieliśmy USUNĄĆ nasze ograniczenia i ponownie je dodać. To działało dla nas.
Daniel L. VanDenBosch
2
Jak to jest na korzyść twardego usuwania? Miękkie usuwanie nigdy nie miałoby problemu z ograniczeniem. Wydaje mi się wręcz przeciwnie.
Maxx
2
@ Maxx W przypadku twardego usuwania usuwasz jeden rekord i nie musisz się martwić o osierocone rejestry, natomiast w przypadku miękkiego usuwania musisz to zrobić ręcznie.
Ronaldo Araújo Alves
319

Aby dodać „Kaskadowe usuwanie” do istniejącego klucza obcego w SQL Server Management Studio:

Najpierw wybierz swój klucz obcy i otwórz „DROP and Create To ..” w nowym oknie zapytania.

wprowadź opis zdjęcia tutaj

Następnie po prostu dodaj ON DELETE CASCADEdo ADD CONSTRAINTpolecenia:

n I naciśnij przycisk „Wykonaj”, aby uruchomić to zapytanie.

Nawiasem mówiąc, aby uzyskać listę swoich kluczy obcych i zobaczyć, które z nich mają włączoną funkcję „Usuń kaskadę”, możesz uruchomić ten skrypt:

SELECT 
   OBJECT_NAME(f.parent_object_id) AS 'Table name',
   COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Field name',
   delete_referential_action_desc AS 'On Delete'
FROM sys.foreign_keys AS f,
     sys.foreign_key_columns AS fc,
     sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
ORDER BY 1

A jeśli kiedykolwiek okaże się, że nie możesz DROPokreślonej tabeli z powodu ograniczenia klucza obcego, ale nie możesz ustalić, który FK powoduje problem, możesz uruchomić to polecenie:

sp_help 'TableName'

SQL w tym artykule zawiera listę wszystkich FK, które odwołują się do określonej tabeli.

Mam nadzieję, że to wszystko pomoże.

Przepraszam za długi palec. Chciałem tylko coś powiedzieć.

Mike Gledhill
źródło
163

Możesz to zrobić za pomocą SQL Server Management Studio.

→ Kliknij prawym przyciskiem myszy projekt tabeli i przejdź do Relacje i wybierz klucz obcy w panelu po lewej stronie, aw panelu po prawej stronie rozwiń menu „WSTAWIANIE i AKTUALIZACJA” i wybierz „Kaskada” jako regułę usuwania.

SQL Server Management Studio

Palanikumar
źródło
cześć, jaka jest różnica między 4, czy włączenie kaskady ułatwia usunięcie wszystkich danych z tabeli. Jak mogę wyświetlić wszystkie klucze zależności / fk w tej tabeli, a nie z tej tabeli. Nawet po usunięciu wszystkich FK nadal
pojawia
@aggie - Możesz sprawdzić zależności, klikając: - Kliknij tabelę prawym przyciskiem myszy -> „Wyświetl zależności”. Również serwer SQL wyświetli szczegółowy błąd z nazwą tabeli i nazwą kolumny, taką jak ta: „Instrukcja DELETE jest w konflikcie z ograniczeniem REFERENCE„ FK_Child1_Parent1 ”. Konflikt wystąpił w bazie danych „TESTDB”, tabeli „dbo.Child1”, kolumnie „Parent1ID”. ”
Palanikumar,
@aggie - Również czwarty przypadek „Ustaw domyślne” to: Musisz ustawić domyślne ograniczenie w kolumnie Klucz obcy, kiedy usuwamy element nadrzędny, wówczas domyślna wartość zostanie zastąpiona w tabelach podrzędnych. (Uwaga: wartość domyślna musi być zgodna z tabelą nadrzędną.) Aby uzyskać więcej informacji, odwiedź stronę mssqltips.com/sqlservertip/2365/…
Palanikumar
To jest bardzo pomocne. Zastanawiam się, dlaczego nie ma reguły wstawiania? Innymi słowy, kiedy dodam wiersz do T1, chcę, aby odpowiedni wpis w T2 był tworzony automatycznie.
Robert M.
@RobertM. Ponieważ to nie ma sensu. Skąd miałby wiedzieć, jakie wartości INSERT? Możesz użyć wyzwalaczy INSERT do wygenerowania wierszy podrzędnych, spróbuj to sprawdzić.
Dan Bechard
47

Użyj czegoś takiego

ALTER TABLE T2
ADD CONSTRAINT fk_employee
FOREIGN KEY (employeeID)
REFERENCES T1 (employeeID)
ON DELETE CASCADE;

Wpisz poprawne nazwy kolumn i powinieneś być ustawiony. Jak poprawnie zaznaczono mark_s, jeśli masz już ograniczenie klucza obcego, być może najpierw musisz usunąć stary, a następnie utworzyć nowy.

Hyperboreus
źródło
41
@marc_s - w rzeczywistości możesz dodać drugi klucz obcy do dokładnie tych samych kolumn po obu stronach i będzie działał poprawnie. Jeśli pracujesz w środowisku produkcyjnym bez przestojów, może być wskazane wprowadzenie nowego FK z kaskadą, a następnie upuszczenie starszego FK, zamiast pozostawienia okna na stole, gdy nie ma na nim FK. (Właśnie przetestowany na SQL 2008)
Damien_The_Unbeliever
To jest poprawne. Próbowałem tego i działa. Nie ma potrzeby usuwania pierwszych ograniczeń klucza obcego. Dziękuję za odpowiedź.
Bichvan Nguyen
15

Najpierw włącz właściwość ONCascade:

1. Zlikwiduj istniejące ograniczenie klucza obcego

2. dodaj nowy z włączonym ustawieniem ON DELETE CASCADE

Dawny:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 

ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

Second To Disable ONCascade właściwość:

1. Zlikwiduj istniejące ograniczenie klucza obcego

2. Dodaj nowy z włączonym ustawieniem WŁĄCZ USUŃ BEZ AKCJI

Dawny:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 
ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE NO ACTION 
END
ravula sandeep
źródło
15

ON DELETE CASCADE
Określa, że ​​dane podrzędne są usuwane po usunięciu danych nadrzędnych.

CREATE TABLE products
( product_id INT PRIMARY KEY,
  product_name VARCHAR(50) NOT NULL,
  category VARCHAR(25)
);

CREATE TABLE inventory
( inventory_id INT PRIMARY KEY,
  product_id INT NOT NULL,
  quantity INT,
  min_level INT,
  max_level INT,
  CONSTRAINT fk_inv_product_id
    FOREIGN KEY (product_id)
    REFERENCES products (product_id)
    ON DELETE CASCADE
);

Dla tego klucza obcego określiliśmy ON DELETE CASCADEklauzulę, która nakazuje SQL Serverowi usunięcie odpowiednich rekordów w tabeli potomnej, gdy dane w tabeli nadrzędnej zostaną usunięte. Zatem w tym przykładzie, jeśli wartość id_produktu zostanie usunięta z tabeli produktów, odpowiednie rekordy w tabeli inwentarza, które używają tego identyfikatora produktu, również zostaną usunięte.

Md Shahriar
źródło
-2

Jeśli relacja jeden do wielu jest z T1 do T2, to nie reprezentuje funkcji i dlatego nie może być użyta do dedukcji lub wnioskowania o funkcji odwrotnej, która gwarantuje, że wynikowa wartość T2 nie pomija krotek T1 łączących T2, które są dedukcyjnie ważne , ponieważ nie ma ważnej dedukcyjnie funkcji odwrotnej. (reprezentowanie funkcji było celem kluczy podstawowych.) Odpowiedź w myśleniu SQL brzmi: tak, możesz to zrobić. Odpowiedź w myśleniu relacyjnym brzmi: nie, nie możesz tego zrobić. Zobacz punkty niejednoznaczności w Codd 1970. Relacja musiałaby być wiele do jednego od T1 do T2.

Frank e
źródło
-10

Myślę, że nie można po prostu usunąć właściwości tabel, a jeśli są to rzeczywiste dane produkcyjne, wystarczy usunąć zawartość, która nie wpływa na schemat tabeli.

Miłośnik Apple
źródło