I've got two tables and I've added a foreign key constraint. Kewl - works great. Now, is it possible to further constrain that relationship against some data in the parent table?
Basically, I have animals in the parent table, and for the child table wishto only contain data where the parent data are .... um .. mammals.
eg.
Animals
^^^^^^^
AnimalId INT PK NOT NULL IDENTITY
AnimalType TINYINT NOT NULL -- 1: Mammal, 2:Reptile, etc..
Name
Mammals
^^^^^^^
AnimalId INT PK FK NOT NULL
NumberOfMammaryGlads TINYINT NOT NULL
So, i wishto make sure that the AnimalId can only be of type Animals.AnimalType = 1
Is this possible??
I don't want to allow someone to try and insert some info against a reptile, in the child table...
Cheers :)
Edit:
I thought I had to use a Check Constraint (confirmed below from my first two answers - cheers!), but I wasn't sure how to (eg. the sql syntax to refer to the Animals table).
Update:
Alex has a very good post (below) that benchmarks some of the suggestions.... a very good read!
You can create a CHECK CONSTRAINT on the column.
Now you need a function fnGetAnimalType that will return the animalType of the given animalId.
Here is more info from MSDN.
Have a unique constraint on Animals(AnimalId, AnimalType) Add AnimalType to Mammals, and use a check constraint to make sure it is always 1. Have a FK refer to (AnimalId, AnimalType).
I think you want to use a Check constraint within the Mammals table.
http://msdn.microsoft.com/en-us/library/ms188258.aspx
This sounds like table inheritance - I recently asked a question (can't link because I'm too new here!) whose answer lead to finding this solution.
I'm working with monetary Transactions where a Transaction is the parent table and transaction types such as Cheque, Bank Transfer, and CC are the child tables. Using a lookup table for transaction types, foreign key constraints, and computed columns I was able to enforce the type constraint on each of the child tables.
Check out the article for implementation details.
Here is an alternative approach that builds on the technique discussed in "Enforcing Complex Constraints with Indexed Views" to enforce the
AnimalType
constraint. The advantage of this approach is that it avoids the extra column in the subtype table; however, it is slower than the composite foreign key presented in AlexKuznetsov's answer (although nowhere near as abysmally slow as the UDF approach).I ran the same series of tests as AlexKuznetsov, but increased the number of rows from 131,072 to 1,048,576. Here is a summary of the results:
Schema definitions:
Tests and results:
To give a strong guarantee, you'll need two check constraints going both ways. If you only constrain
Mammals
someone could updateAnimals.AnimalType
and get the data in an inconsistent state.