views:

75

answers:

2

Hello friends I am getting the following error while making the foreign key

'tbl_course' table saved successfully 'tbl_students' table - Unable to create relationship 'FK_tbl_students_tbl_course'.
Introducing FOREIGN KEY constraint 'FK_tbl_students_tbl_course' on table 'tbl_students' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors.

I have the following tables College table, Branch table, Course table and Student table

Course has a foreign key college_id, Branch has a foreign key course_id and I want to make college_id, course_id, branch_id as foreign keys to my Student table but while making course_id and branch_id as foreign key in Student table it generate the error mentioned above...please help me to resolve the above problem.....thanks

+2  A: 

According to MS

You receive this error message because in SQL Server, a table cannot appear more than one time in a list of all the cascading referential actions that are started by either a DELETE or an UPDATE statement. For example, the tree of cascading referential actions must only have one path to a particular table on the cascading referential actions tree.

http://support.microsoft.com/kb/321843

Can you live without the cascading deletes? Keep the referential ingegrity but not the referenctial actions (cascades). You could resort to a trigger as a work around if needed.

EDIT:

CREATE TRIGGER [dbo].[tr_College_Delete] ON [dbo].[College] 
FOR  DELETE 
AS 
BEGIN 
    DELETE  FROM student 
    where collegeid in (select collegeid from deleted) 

END 

not tested.

Gratzy
yes if i dont set cascading then it works, but it's of no avail without that....
NoviceToDotNet
Well I'm afraid sql server won't let you. You can use a trigger if you really need the cascading functionality at the database level.
Gratzy
Gratzy ..trigger u frightened me..i never used this can u suggest me how use it to rid of from this problem...
NoviceToDotNet
is trigger necessary...we cant work without trigger ...i am not getting whats happening wrong when every thing is fine..
NoviceToDotNet
Well a trigger is a work around for your issue. You could handle it at the application level as well. Sorry but I don't understand "...i am not getting whats happening wrong when every thing is fine." Apparently its not.
Gratzy
Gratzy it i am using your trigger but it's giving some syntctical error can u correct it..it has some error Msg 156, Level 15, State 1, Procedure tr_Course_Delete, Line 6 Incorrect syntax near the keyword 'INNER'.
NoviceToDotNet
CREATE TRIGGER [dbo].[tr_Course_Delete] ON [dbo].[tbl_course]FOR DELETEASBEGIN DELETE FROM tbl_students INNER JOIN deleted on deleted.course_id = students.course_idENDdoes for delete work in sql server
NoviceToDotNet
I updated it try that.
Gratzy
Gratzy:-> thanks a lot u resolved my problem ...
NoviceToDotNet
NO they haven't resolved your problem, they have masked your problem. Your problem is you have a poor underlying design or you wouldn't need the work-around. It doesn't allow cacading deletes for good reason when you have circular refernces becasue a good datamodel does not have them ever under any circumstances. Working around that issue is a mistake. You need to redesign so that you don;t need a circular reference.
HLGEM
@HLGEM I believe my first suggestion was to drop the cascading deletes
Gratzy
+1  A: 

Why would you add anything but branch_id to the student? From there, you should be able to determine which course the branch belongs to and which college the course belongs to.

If you have

College
College1
College2
College3

Course
Course1, College1
Course2, College1
Course3, College2

Branch
Branch1, Course1
Branch2, Course1
Branch3, Course2

Student
Student1,College3,Course3,Branch1

This is valid from the database standpoint, but makes no sense since the student record should be attached to College1 based on the Branch it's attached to. You know logically that if the student is in a branch with ID Branch1 (or whatever primary key you use, but I use this for illustraion purposes) then they must be in Course1 and College1. By adding the additional information to the Student record, you not only create circular references in the code but put yourself in a position to create a "corrupt" record in the database. Of course you can code around this, but why go to the extra effort when you can simplify the student record to simply (Student1,Branch1) without losing any data?

This is known as database normalization, and it's something that's very important to at least consider when you're building a data model.

Kendrick
Kendrick...student table has student information which contains student_id as primary key it also has colleg_id branch_id and course_id ....i want if collge_id is deleted then all corrosponding record to that college from student table must be deleted same for course and branch id...
NoviceToDotNet
If you have students who have taken classes at a particular branch, you most definitely do NOT want to delete the college, you want to mark it as inactive or you will lose your history and I'd be pretty mad at you if I took a course at branch A and then it wasn't in my transcript and I couldn't graduate because you deleted my course attendance when you closed the branch.
HLGEM
comment contnuedThis is like deleting the part from an order that was filled in the past when the part is no longer available for purchase. It was still purchased in the past. Using cascading deletes (or a trigger) for a feature like this is dangerous. You are completely destroying any data integrity you had. Historical records should never be deleted if the entity they used is no longer in existance.
HLGEM
HLGEM yes, u are true but in my project client doesnt want want to sore history ....so it's ok with deleting students record who dont have belong to existing branch or course or college or company, but trigger worked for me ........a very thanks to u as well for your guidance to correct me on database design.....
NoviceToDotNet
@rupeshmalviya, although I 100% agree with HLGEM, if you want the deletes to cascade then that will still work the way I suggested. If you're using cascade deletes, when you delete the college it will delete the course, which will delete the branch, which will delete the student. Databases should be simple and have no duplicate data or circular references, and ideally have constraints to prevent incorrect data.
Kendrick