Yes, you can do this with a COMPUTED
column, It's a workaround really as the column has to be PERSISTED
to be used for the foreign key constraint so it consumes storage space:
CREATE TABLE dbo.OtherTable (
ID INT PRIMARY KEY IDENTITY(1,1),
Blah VARCHAR(100),
FieldName AS CAST('This' AS VARCHAR(100)) PERSISTED NOT NULL
) ;
ALTER TABLE dbo.OtherTable WITH CHECK
ADD CONSTRAINT [FK__OtherTable__Blah]
FOREIGN KEY (FieldName, Blah)
REFERENCES Lookup (FieldName, Value) ;
Tested at SQL-Fiddle.
The table can then be used as if the FieldName
does not exist. You could even define a view that does not include this column and make your applications use that view: SQL-Fiddle-2
The syntax you hoped for, although looking pretty, has not been implemented in any DBMS I know of:
ALTER TABLE dbo.OtherTable WITH CHECK
ADD CONSTRAINT [FK__OtherTable__Blah]
FOREIGN KEY('This', Blah)
REFERENCES Lookup (FieldName, Value) ;
Note however that the workaround with the computed columns would be 100% equivalent to this syntax, if only SQL-Server removed in the future the restriction of using only persisted columns. You could add a Connect item with your request.
For the question whether there is any other DBMS that allows this, no, there isn't. Check also a related question:
Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
If you really don't want to use this method (because of the additional storage requirements, alternative paths would be to enforce the constraint via procedures or triggers (Note that you would have to write procedures or triggers for both tables involved.)
Thanks to ypercube,
I had to drop the parent table "department", recreate it and then use ALTER TABLE employee ADD CONSTRAINT fk_manager_unique FOREIGN KEY (manager_id) REFERENCES department (manager_id)
; everything worked just fine and the foreign key reference to the unique manager_id key were finally created. Note that I had to change the name of the constraint "manager_unique" in the second table because of duplication issues.
Thanks again!
Best Answer
There are two possibilities here:
1) is that it is a case of 2 fields in the same table being
FOREIGN KEY
s pointing to the same field in the parent table.2) is that this is an example of an Associative Entity. These are also called joining, linking or many-to-many tables.
1. Double
FOREIGN KEY
.This is quite simple to resolve.
You have two tables -
department
anddept_transit
(see fiddle):A few things to notice:
my solution uses
long_variable_names
! Many years of experience have taught me that you are far better off making your variable names (table_names, field_names andPK
s,FK
s &c.) as long and as meaningful as necessary. This makes life much easier for debugging and more than outweighs the trouble of the extra typing! Also, note the singular name fordepartment
! YMMV :-)I always try to keep fieldnames unique within a schema (e.g.
new_dept_id
,dt_new_dept_id
) - this helps greatly with logic when joining tables. I make exceptions forNATURAL KEY
s, but not surrogate ones as is the case here.My own personal preference is for SQL keywords to be in upper-case and for the variables (tables, fields &c.) to be in
lower_snake-case
. This allows the eye to readily pick out different elements when debugging &c. If you look up SQL coding standards on the web, you will find lots of debate about this (i.e. here). The main thing is to pick a standard (for yourself, company, whatever) and STICK TO IT.Not entirely sure of requirements, but I think that (for MySQL) a
TRIGGER
will be required for any requirement thatoriginal_dept_id
andnew_dept_id
be different (which makes sense - I think). Unfortunately, MySQL still (Amazingly) doesn't allow forCHECK CONSTRAINT
s. See the MUCH nicer solution possible with PostgreSQL here. A good reason to switch to the far superior PostgreSQL if you're not too invested in MySQL! :-)2. Joining Table.
If this is the case, I would do something like the following (fiddle here):
PRIMARY KEY
of the joining table is a natural one, make up of thePK
s of both of the entities that comprise it.