SQL Server foreign relationship on two-column primary key - sql-server

I have the following three sample tables (simplified demo for purpose of question):
CREATE TABLE Teams
(
Id int IDENTITY(1,1) NOT NULL,
Name varchar(50) NOT NULL,
PRIMARY KEY (Id)
)
CREATE TABLE TeamGroups
(
Id int NOT NULL,
TeamId int NOT NULL,
PRIMARY KEY (Id,TeamId)
)
CREATE TABLE RoomBookings
(
Id int NOT NULL,
TeamGroupId int NOT NULL,
RoomId int NOT NULL,
PRIMARY KEY (Id)
)
and I have the following foreign key already set up:
ALTER TABLE TeamGroups WITH CHECK
ADD CONSTRAINT [FK_TeamGroups_Teams]
FOREIGN KEY (TeamId) REFERENCES Teams(Id)
The idea is that each Team can be in zero or more TeamGroups, and each TeamGroup can have zero or more RoomBookings
To reflect that, I want to add a foreign key from the RoomBookings table into the TeamGroups table.
I tried using the Relationships GUI in Management Studio to create the foreign key (primary key table: TeamGroups.ID, foreign key table: RoomBookings.TeamGroupId) but I get an error:
The columns in table 'TeamGroups' do not match an existing primary key
or UNIQUE constraint
I'm assuming it's because the TeamGroups table has a two-column primary key?
I don't really want to make a foreign key constraint from the TeamGroups table (eg, the key is present in the TeamGroups table), as the table will eventually be used by other tables (such as EquipmentBookings, GroupManagers, etc).
Any help?

If your primary key is made up from more than one columns, then all foregin keys also must have all those columns - there's no way around this.
But I don't understand why you'd get this error trying to link TeamGroups to Team based on the Team.Id column.... that should work just fine.
Try using this:
ALTER TABLE TeamGroups WITH CHECK
ADD CONSTRAINT [FK_TeamGroups_Teams]
FOREIGN KEY (TeamId) REFERENCES Teams(Id);
You had Teams (which is not a valid column in TeamGroups at all), and you had REFERENCES Teams.id which is wrong - it needs to be REFERNCES Teams(Id); (column in parenthesis - not the "dot" notation)
Update: from TeamGroups to RoomBookings - yes.... either use both columns from TeamGroups in your RoomBookings table - or what would stop you from making the TeamGroups.Id column an INT IDENTITY and then have the PK on just this one column?? Any good reason for that??
CREATE TABLE TeamGroups
(
TeamGroupId int NOT NULL,
TeamId int NOT NULL,
PRIMARY KEY (TeamGroupId)
)
ALTER TABLE dbo.RoomBookings
ADD CONSTRAINT FK_RoomBookings_TeamGroup
FOREIGN KEY TeamGroupId REFERENCES TeamGroups(TeamGroupId)

Related

SQL Server why am I getting error for creating foreign key constraint for no matching key in referenced table?

I get this error from SQL Server:
Msg 1776, Level 16, State 0, Line 64
There are no primary or candidate keys in the referenced table 'Orders' that match the referencing column list in the foreign key 'FK_Cart_Orders'.
However, the OrderID column is in the Orders table, so I cannot understand why the error says there is no matching keys in the Orders table. I am obviously doing something wrong but do not know what it is.
My code is fairly short and is:
CREATE DATABASE TestMattressSite
GO
USE TestMattressSite
GO
CREATE TABLE Mattresses
(
MattressID INT IDENTITY NOT NULL,
)
GO
CREATE TABLE Customers
(
CustomerID INT IDENTITY NOT NULL,
)
GO
CREATE TABLE Orders
(
OrderID BIGINT IDENTITY NOT NULL,
CustomerID INT NOT NULL,
)
CREATE TABLE Cart
(
OrderID BIGINT NOT NULL,
MattressID INT NOT NULL,
CustomerID INT NOT NULL
)
GO
ALTER TABLE Mattresses
ADD CONSTRAINT PK_Mattresses PRIMARY KEY (MattressID)
GO
ALTER TABLE Customers
ADD CONSTRAINT PK_Customers PRIMARY KEY (CustomerID)
GO
ALTER TABLE Orders
ADD CONSTRAINT PK_Orders PRIMARY KEY (OrderID, CustomerID)
GO
ALTER TABLE Cart
ADD CONSTRAINT PK_Cart PRIMARY KEY (OrderID, MattressID)
GO
ALTER TABLE Orders
ADD CONSTRAINT FK_Orders_Customers
FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
GO
ALTER TABLE Cart
ADD CONSTRAINT FK_Cart_Mattresses
FOREIGN KEY (MattressID) REFERENCES Mattresses (MattressID),
CONSTRAINT FK_Cart_Orders
FOREIGN KEY (OrderID) REFERENCES Orders (OrderID),
CONSTRAINT FK_Cart_Customers
FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
GO
Can someone please take a look and point out my error?
Since your Orders table have primary key on two columns OrderID and CustomerID, its a composite primary key so when you want to reference this key as foreign key any table, you need to define all the column of composite primary key, like below.
ALTER TABLE Cart ADD
CONSTRAINT FK_Cart_Mattresses FOREIGN KEY (MattressID) REFERENCES Mattresses (MattressID),
CONSTRAINT FK_Cart_Orders FOREIGN KEY (OrderID, CustomerID) REFERENCES Orders (OrderID, CustomerID),
CONSTRAINT FK_Cart_Customers FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
GO
Or,
If you want your foreign key to have only one column OrderID, change your primary key like this:
ALTER TABLE Orders ADD
CONSTRAINT PK_Orders PRIMARY KEY (
OrderID
)
GO
With this, you current query will work as it is.
There already a question on this, refer this link.

Foreign key references invalid table. Could not create constraint or index

I'm trying to create a table with 3 columns. The first column should be an identity column named DescriptionsID, the second column should be a foreign key column named ProductID, and the third column should be an xml column named Description. But, I'm receiving an error:
Foreign Key 'FK_ProductDescriptions_bacb18ce3aa67348e55d' references invalid table 'Product' and "Could not create constraint or index. See previous errors."
This is what I got:
CREATE TABLE ProductDescriptions (DescriptionsID int PRIMARY KEY NOT NULL,
ProductID varchar(25) NOT NULL,
FOREIGN KEY (ProductID) REFERENCES Product(ProductID),
Description text NULL) ;
References Product(ProductID) has the error/red underlining
When you create a Referential Constraint, You Need to make sure that the Table and the Column which you are referring already exists in the Database.
Also, the Datatype of Both Referring Column and the Referred Column Should Be the Same
Column 'Product.ProductId' is not the same data type as referencing column
'ProductDescriptions.ProductID' in the foreign key
So Create Product Table First, and set the Product Id as Primary Key
CREATE TABLE Product
(
ProductId INT IDENTITY(1,1) PRIMARY KEY,
ProductName VARCHAR(50)
)
CREATE TABLE ProductDescriptions
(
DescriptionsID int PRIMARY KEY NOT NULL,
ProductID INT NOT NULL
,FOREIGN KEY (ProductID) REFERENCES Product(ProductID),
[Description] text NULL
) ;

Entity Framework appears to skip mapping a table with a multi-column primary key set through a constraint

I've created an ADO.NET model via the database first approach.
One of my tables which is listed when creating the model doesn't actually get added to it.
The table has a multi-column primary key, composed of two foreign keys.
CREATE TABLE ForumAccess
(
UserID INT FOREIGN KEY REFERENCES Users(UserID) NOT NULL,
ForumID INT FOREIGN KEY REFERENCES Forums(ForumID) NOT NULL,
CONSTRAINT ForumAccessID PRIMARY KEY (UserID, ForumID),
);
It does show up when I have to select which tables to add, but then it seems to be skipped. No class is generated for it, and it's not shown in the .edmx file.
Part of my application depends on the existence of this table. I have another table which has a multi-column primary key, and another DateTime type column. That table does get added.
That table is:
CREATE TABLE Moderators
(
UserID INT FOREIGN KEY REFERENCES Users(UserID) NOT NULL,
ForumID INT FOREIGN KEY REFERENCES Forums(ForumID) NOT NULL,
TimeOfAddition DateTime NOT NULL, -- When the mod was added as a mod.
CONSTRAINT ModeratorID PRIMARY KEY (UserID, ForumID),
);
Why does the Moderators table get added, but the ForumAccess table doesn't?
There is no error, or any warning that I can see.
What am I missing?

How to create database schema with shared primary foreign key?

My goal is to have a subtable whose primary key and foreign key both are the same column, and reference to an ID of the main table.
CREATE TABLE main_table(
id integer NOT NULL,
//some fields
)
CREATE TABLE test(
id integer NOT NULL,
name varchar,
CONSTRAINT test_pk PRIMARAY KEY (id),
CONSTRAINT test_fk FOREIGN KEY (fk_id)
REFERENCES main_table (id) MATCH SIMPLE
)
But this will create a table mapping with two columns: id[PK] and test_fk as foreign key column. How can I combine them?
You have misunderstood how the foreign key clause works. You list the names of existing columns in there. And listing the column names will create any new column. Any FK column must have already be defined in the "columns part" of the create table statement.
So your statement wouldn't work at all because the table test does not have a column named fk_id. You need to supply the name of the already defined column id there:
CREATE TABLE test(
id integer NOT NULL,
name varchar,
CONSTRAINT test_pk PRIMARAY KEY (id),
CONSTRAINT test_fk FOREIGN KEY (id) --- <<< this was wrong
REFERENCES main_table (id) MATCH SIMPLE
)

Foreign Key Relationship with one of Multiple Tables

I have a language map table that each entry has the possibility of a foreign key relationship with a few different tables. What is the best schema to deal with this configuration?
Tables: LanguageMap, TableA, TableB
These are the two possibility:
1. Lookup Column Method - No Foreign Key Constraints:
Create Table LanguageMap (
Id int not null primary key,
Language nvarchar not null,
Value nvarchar not null,
Type nvarchar not null, -- 'TableA', 'TableB', etc.
ForeignTableId int not null -- Is Foreign key to another table dependent on the type of the row.
)
2. Multiple Foreign Key Columns
create Table LanguageMap(
Id int not null primary key,
Language nvarchar not null,
Value nvarchar not null,
Type nvarchar not null, -- 'Activity', 'Verb', etc.
TableAId int null,
TableBId int null
)
alter table LanguageMap add constraint FK_LanguageMap_TableA
foreign key (TableAId) references TableA (Id)
alter table LanguageMap add constraint FK_LanguageMap_TableA
foreign key (TableBId) references TableB (Id)
alter table LanguageMap add constraint CK_LanguageMap_OneIsNotNull
check (TableAId is not null or TableBId is not null)
go
alter table LanguageMap add constraint CK_LanguageMap_OneIsNull
check (TableAId is null or TableBId is null)
go
The foreign key constraints are based on Foreign Key for either-or column?
There is another alternative, called "Shared Primary Key". You can look this up. If TableA, TableB, TableC, etc. all "inherit" their PK as a copy of the PK from some Master table, called "TableMaster" for example, then you can just use that as an FK in LanguageMap.
The correct joins will select the correct instances.
The shared primary key is often used in conjunction with a design pattern called "Class Table Inheritance". Without knowing what TableA, TableB, TableC, etc. are about, I can't say whether Class Table Inheritance is relevant to your case.
In any event, look up both "Shared Primary Key" and "Class Table Inheritance" for further reading.
There are tags with those names in this area.

Resources