SQL Multiple Foreign Keys as Primary Keys - sql

If I declare the table below does it implicitly imply that both the foreign keys make a unique primary key or do I need to do something more to make both attributes as a primary key?
CREATE TABLE Report_has_Items
(
ReportID int REFERENCES Report(ReportID) NOT NULL,
ItemID int REFERENCES Item(ItemID) NOT NULL
)
Essentially both attributes which are foreign keys from other tables, together would form a unique key.

No it doesn't. The above table has no primary key. If you want to use the fields as a primary key use:
CREATE TABLE Report_has_Items(
ReportID int REFERENCES Report(ReportID) NOT NULL,
ItemID int REFERENCES Item(ItemID) NOT NULL,
PRIMARY KEY (ReportID, ItemID)
)
or something similar depending on your sql dilect.

Let's name our constraints, eh?
CREATE TABLE dbo.Report_has_Items(
ReportID int NOT NULL,
CONSTRAINT [FK_RHI_Report] (ReportId) REFERENCES dbo.Report(ReportID),
ItemID int NOT NULL,
Constraint [FK_RHI_Item] (ItemId) REFERENCES dbo.Item(ItemID),
CONSTRAINT [PK_RHI] PRIMARY KEY (ReportID, ItemID)
)

I am not sure i understand your question completely but i assume you are trying to create a composite primary key (primary key with more than one attribute). You could do the following.
CREATE TABLE Report_has_Items(
ReportID int references Report(ReportID),
ItemID int references Item(ItemID),
PRIMARY KEY (ReportID , ItemID )
);
Note:The pair (ReportID , ItemID ) must then be unique for the table and neither value can be NULL.
Here is a very useful link for SQL Queries

Related

SQL table stopping me from adding foreign key

I'm creating a SQL table in VS that stores what rooms each client is, So the table has RoomId (int) and UserID (int).
Because I only want to add to the table only rooms and clients that exist they are both keys that have a foreign key to 2 tables, one that stores RoomID and Name and another that stores Client ID and Name.
Room and UserId tables:
CREATE TABLE [dbo].[UsersInRoomsTable]
(
RoomId INT NOT NULL,
UserId INT NOT NULL,
CONSTRAINT PK_RS PRIMARY KEY(RoomId, UserId),
CONSTRAINT [fk_room] FOREIGN KEY([RoomId]) REFERENCES [dbo].[RoomsTable]([RoomId]),
CONSTRAINT [fk_user] FOREIGN KEY ([UserId]) REFERENCES [dbo].[UserInfoTable] ([UserId])
);
Table that stores all the users:
CREATE TABLE [dbo].[UserInfoTable]
(
[UserName] NVARCHAR (50) NOT NULL,
[UserId] INT NOT NULL,
CONSTRAINT [PK_roomuser] PRIMARY KEY CLUSTERED ([UserName] ASC, [UserId] ASC)
);
Table that stores all the rooms
CREATE TABLE [dbo].[RoomsTable]
(
[RoomId] INT NOT NULL,
[RoomName] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([RoomId] ASC)
);
Everything works except the last line in the Rooms and users table:
CONSTRAINT [fk_user] FOREIGN KEY ([UserId]) REFERENCES [dbo].[UserInfoTable] ([UserId])
When I try to Update the table I get an error SQL71516:
SQL71516: The referenced table '[dbo].[UserInfoTable]' contains no primary or candidate keys that match the referencing column list in the foreign key.
If the referenced column is a computed column, it should be persisted
How can I solve this problem and what is causing it?
Edit: I think I know what is code is colliding: For some reason I can not have a foreign key connecting to a key that contains 2 indexes IE: fk_user is a Fk to table UserInfoTable that has 2 keys (UserID and UserName)
is there a way to pass this obstacle?
The columns of a foreign key have to match the columns they reference by number, type and order.
You have a primary key on userinfotable of (username, userid). But in usersinroomstable you are trying to let the foreign key (userid) to reference that. The number of columns doesn't match, so the foreign key cannot be added.
Presumably the username shouldn't really be part of the primary key of userinfotable and got there by accident. Remove it from the primary key constraint.
Or, if username has to be in the primary key, add such a column to the table usersinroomstable and add it to the foreign key constraint.

Error when setting foreign key in SQL Server

I have the following queries that I run to create tables in MS SQL Server:
CREATE TABLE menus
(
menu_id int NOT NULL PRIMARY KEY,
menu_name char,
other_details char
)
CREATE TABLE bookings
(
booking_Id int NOT NULL PRIMARY KEY,
date_booked DATE,
date_of_booking DATE,
other_details char,
staff_id int FOREIGN KEY REFERENCES staff(staff_id),
customer_id int FOREIGN KEY REFERENCES customers(customer_id)
)
CREATE TABLE menus_booked
(
menu_id INT NOT NULL,
booking_id INT NOT NULL,
CONSTRAINT PK_menus_booked PRIMARY KEY(menu_id,booking_id),
FOREIGN KEY (menu_id) REFERENCES menus(menu_id),
FOREIGN KEY (booking_id) REFERENCES bookings(booking_id)
)
CREATE TABLE menu_changes
(
change_id int NOT NULL PRIMARY KEY,
menu_id int NOT NULL,
booking_id int NOT NULL,
change_details char,
FOREIGN KEY (menu_id) REFERENCES menus_booked(menu_id),
FOREIGN KEY (booking_id) REFERENCES menus_booked(booking_id)
)
On running the last query I get the error:
There are no primary or candidate keys in the referenced table 'menus_booked' that match the referencing column list in the foreign key 'FK_menu_chan_menu'
I am unsure if my queries are correct and can't resolve this error.
The primary key of menus_booked is a unique combination of menu_id and booking_id. A foreign must point to that combination, not just one of its fields, which is not necessarily unique. Your query currently tries to define two foreign keys, one on each column, instead of one foreign key on the combination of the columns:
CREATE TABLE menu_changes
(
change_id int NOT NULL PRIMARY KEY,
menu_id int NOT NULL,
booking_id int NOT NULL,
change_details char,
FOREIGN KEY (menu_id, booking_id)
REFERENCES menus_booked(menu_id, booking_id) -- Here!
)
A foreign key has to reference a primary key (or unique key but here the PK is the problem), and it has to reference it in it's entirety.
FOREIGN KEY (menu_id) REFERENCES menus_booked(menu_id),
FOREIGN KEY (booking_id) REFERENCES menus_booked(booking_id)
You have two foreign key's referencing part of the primary key of menus_booked. You'll have to alter it to:
FOREIGN KEY (menu_id, booking_id) REFERENCES menus_booked(menu_id, booking_id)

Not able to create foreign key "There are no primary or candidate keys in the referenced table"

This is my table 1:
CREATE TABLE PurchasedProducts
(
Purchase_Order_No int,
Purchase_Product_ID int FOREIGN KEY REFERENCES Inventory(In_Product_ID),
Purchase_Quantity int NOT NULL,
Purchase_Status varchar(7) NOT NULL,
PRIMARY KEY(Purchase_Order_No, Purchase_Product_ID)
);
This my table 2:
CREATE TABLE PurchasedDate
(
PD_PO_No int NOT NULL PRIMARY KEY FOREIGN KEY REFERENCES PurchasedProducts(Purchase_Order_No),
PD_Date date NOT NULL
);
I executed the first table successfully, but when I execute the second table It is showing this error message:
There are no primary or candidate keys in the referenced table 'PurchasedProducts' that match the referencing column list in the foreign key 'FK__Purchased__PD_PO__0B5CAFEA'.
I don't what is the problem is. Please help me!
The primary key in your PurchasedProducts table is made up of two columns:
PRIMARY KEY(Purchase_Order_No, Purchase_Product_ID)
So any child table that wants to reference that also must have these exact two columns:
CREATE TABLE PurchasedDate
(
PD_PO_No int NOT NULL PRIMARY KEY,
Purchase_Product_ID INT NOT NULL,
PD_Date date NOT NULL
);
ALTER TABLE dbo.PurchasedDate
ADD CONSTRAINT FK_PurchaseDate_PurchasedProducts
FOREIGN KEY(PD_PO_No, Purchase_Product_ID)
REFERENCES PurchasedProducts(Purchase_Order_No, Purchase_Product_ID)
A foreign key can only reference the whole primary key of a parent table - you cannot reference only one column out of 2 from the parent table's PK.

In SQL does a Primary Key in a create table enforce uniqueness?

Im wondering if on a relational table I set the two values below as a PRIMARY KEY if that automatically makes the table know that all entries should be unique....
CREATE TABLE UserHasSecurity
(
userID int REFERENCES Users(userID) NOT NULL,
securityID int REFERENCES Security(securityID) NOT NULL,
PRIMARY KEY(userID,securityID)
)
or do I need to be more explicit like this...
CREATE TABLE UserHasSecurity
(
userID int REFERENCES Users(userID) NOT NULL,
securityID int REFERENCES Security(securityID) NOT NULL,
PRIMARY KEY(userID,securityID),
UNIQUE(userID,securityID)
)
You don't need UNIQUE here. PRIMARY KEY will make sure there is no duplicate (userID,securityID) pairs.
No, you don't need to specify UNIQUE in addition to PRIMARY KEY. A primary key by definition must be unique.
A PRIMARY KEY has to be unique, so you only need to declare as a primary key. The underlying index is unique by definition.
Creating Unique Indexes

What's the difference between these SQL syntaxes?

I was looking for info on foreign keys.... AGAIN! ... and happened to notice on webschools.com they have different examples of the same thing. for the foreign key example they have
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
)
CREATE TABLE Orders
(
O_Id int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
P_Id int FOREIGN KEY REFERENCES Persons(P_Id)
)
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
now..........
what's the difference?...
How do I know which one I'm suppose to use for my database? I have a feeling this will help resolve a lot of the confusion I'm having with SQL...
No difference in effect: They achieve exactly the same thing.
I prefer the in-line version, because it puts the fk definition as close to the column definition as possible.
There's a 3rd way - a separate alter table statement (which I think is the "official" way):
alter table orders
add contraint fk_PerOrders
foreign key p_id references persons(p_id);
You may find some databases don't support one version or the other.
All of them are doing same thing. Use the one which you feel is easy to understand.
All do same (three ways):
In first, you first defined P_Id as int then defined foreign key constraint.
In second, P_Id int FOREIGN KEY REFERENCES Persons(P_Id). P_Id is defecation and foreign key constraint defecation in same line.
In third, a foreign key constraint name is also give fk_PerOrders. that can be useful later when you wants to drop constraint. e.g.
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders
Its always good practice to give name to a constraint.