Relacja wiele do wielu

0

Witam,

W mojej bazie danych posiadam 3 tabele powiązane ze sobą relacją wiele do wielu.

  1. Classrooms
  2. Subjects
  3. SubjectsInClassrooms

Z jednej strony relacji ustawiłem opcje oncascade Delete aby podczas osunięcia przedmiotu usunęło się powiązanie z nim,
jednak problem występuje podczas gdy tą opcje chce ustawić z drugiej strony relacji bez tego w momencie usunięcia rekordy z classrooms a rekord jest powiązany z obiektem subject otrzymuję wyjątek, jak to ominąć?

0

Na pewno twój problem rozwiązuje trigger (usuwający powiązania z SubjectsInClassrooms) wyzwalany przed usunięciem rekordów z Classrooms, ale jak rozwiniesz bardziej kolejność operacji jakie chcesz zrobić to pewnie znajdzie się bardziej eleganckie rozwiązanie.

0

No ok ale jak powinien wyglądać taki trigger?
Jak go ustawić aby działał przed usunięciem rekordu z tabeli classrooms (rozumiem że to musi zadziałać przed wykonaniem funkcji delete)?
Jak pobrać informacje do trigger'a który rekord ma być usunięty i dzięki temu usunąć powiązania w tabeli SubjectsInClassrooms?

0

a wujek google to gryzie?

Trigger, before delete, dostepny w nim bedzie obiekt ":old"(PL/SQL) bedacy rekordem ktory zostal oznaczony do usuniecia z danej tabeli. Mozna sobie zrobic selecta i dane wyciagnac i pousuwac reszte.

0

@jawka7 tylko pamiętaj, że obiekt "old" może zawierać więcej niż jeden element bo tak naprawdę to lista rekordów, które mają być usunięte, a co w niej będzie w danej chwili zależy od optymalizatora sql server. Nawet jak z poziomu kodu usuwasz rekordy pojedynczo to tutaj usunięcie może być buforowane w partiach po kilka. Kolejna prawa to aspekt wydajnościowy, trigger założony na jakaś operacje bez znaczenia czy przed czy po zwiększa ogólny czas wykonania tej operacji, więc jeśli byś pisał aplikację, w której dane z tej tabeli byłby często modyfikowane w dużych ilościach to prawdopodobnie należałoby się zastanowić nad jakimś innym rozwiązaniem problemu.

PS. Jak piszesz ten soft zespołowo, to umieść gdzieś informacje o tym, że w tym i tym miejscu jest trigger, bo ktoś kiedyś może spędzić kawałek czasu szukając dlaczego coś mu się usuwa ;)

0
Krycho napisał(a):

a wujek google to gryzie?

No właśnie problem tkwi w tym że nie mogę znaleźć żadnego porządnego artykułu dotyczącego wyzwalaczy i a te które znalazłem nic nie mówią o BEFORE dlatego chciałem napisać post aby dowiedzieć się czy to BEFORE w ogóle istnieje ponieważ w jednym z artykułów dostępne opcje to jedynie { FOR | AFTER | INSTEAD OF }.
Wychodzi na to że opcja FOR działa przed wykonaniem np. DELETE?

0

Tak FOR działa przed DELETE,
Jak przeczytasz pomału wszystko co jest tutaj: http://technet.microsoft.com/pl-pl/library/ms189799.aspx
To powinno Ci starczyć.

edit: a tu już masz w ogóle twój przypadek: http://stackoverflow.com/questions/10443829/how-to-create-a-before-delete-trigger-in-sql-server

0

Właśnie ten artykuł też czytałem i to FOR zamęciło mi w głowie teraz już wiem, dzięki wielkie ;)

P.S

W stawiłem swój trigger jednak podczas usunięcia Classrooms nadal otrzymuję wyjątek

CREATE TRIGGER DeleteClassrooms
ON Classrooms
FOR DELETE
AS
BEGIN
     DELETE FROM SubjectsInClassrooms
	 WHERE Classroom_Id IN (SELECT Classroom_Id FROM DELETED)
END
GO
The DELETE statement conflicted with the REFERENCE constraint "FK_SubjectsInClassrooms_Classrooms". The conflict occurred in database "zaplanuj.eu", table "dbo.SubjectsInClassrooms", column 'Classroom_Id'.

1 użytkowników online, w tym zalogowanych: 0, gości: 1