There are no primary or candidate keys in the referenced table error - sql

I have a problem with combining foreign keys to different tables. For example I made a table Customers and a Table invoices. I want a foreign key from Customers to invoices so I can get the name and everything of the Customer:
Create table code of Customers:
Create Table Customers
(
customerID int IDENTITY(100,1) NOT NULL,
customer_email varchar(30) NOT NULL,
username varchar(255) NOT NULL,
password varchar(50) NOT NULL,
firstname varchar(255) NOT NULL,
lastname varchar(255) NOT NULL,
insertion varchar(10) NULL,
phonenumber int NULL,
streetname varchar(20) NOT NULL,
number int NOT NULL,
zipcode varchar(10) NOT NULL,
city varchar(255) NOT NULL,
Constraint pk_Customers
PRIMARY KEY (customerID, customer_email, username)
)
Create table code of Invoices:
Create Table Invoices
(
invoiceID int IDENTITY(1000,1) NOT NULL,
customer_email varchar(30) NOT NULL,
customerID int NOT NULL,
creationdate datetime NOT NULL DEFAULT GETDATE(),
totalAmount decimal(5,2) NOT NULL,
Constraint pk_Invoices
PRIMARY KEY (invoiceID, customer_email,creationdate)
)
The foreign key code that I want to use:
ALTER Table Invoices
ADD Constraint fk_Customers_Invoices
FOREIGN KEY (customerID) REFERENCES Customers (customerID)
ON UPDATE CASCADE
ON DELETE NO ACTION
It throws the following error:
There are no primary or candidate keys in the referenced table 'Customers' that match the referencing column list in the foreign key 'fk_Customers_Invoices'.
How can I add my foreign key?

I think it's because your primary key is a composite key:
customerID, customer_email, username
This suggests that it is only the combination of these three fields that will uniquely identify a customer, and the foreign key would need to reference all three fields.
If customerID is unique, then it should be the primary key for the table and your foreign keys would be able to use it as a reference.
For what purpose are the other fields included in the primary key?

Since your Customers table defines this primary key:
Constraint pk_Customers
PRIMARY KEY (customerID, customer_email, username)
any table that wants to reference Customers must provide all three columns of that primary key. That's the way FK constraints work.
So from your Invoices tables, you must provide all 3 columns that make up the primary key of Customers - not just one. You can never refernce only part of a primary key - it's the whole key or nothing....
ALTER Table Invoices
ADD Constraint fk_Customers_Invoices
FOREIGN KEY (customerID) REFERENCES Customers (customerID)
ON UPDATE CASCADE
ON DELETE NO ACTION
You can either:
change the PK for Customers to be just CustomerID which would make a whole lot more sense since it's an identity column
or you could add the other two columns in the Customers PK to yoru table Invoices

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.

SQL: Foreign key references a composite primary key

I'm new to SQL and there are a lot of things going on that I still don't seem to quite understand. I have the following table
CREATE TABLE Person
(
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
PRIMARY KEY (First_Name, Name, Address)
);
I know want to create another table that has the primary key from the table Person as foreign key and also as primary key:
CREATE TABLE Purchase
(
No_Installments int,
Rate int,
Person varchar(50) NOT NULL PRIMARY KEY,
CONSTRAINT PFK
FOREIGN KEY (Person) REFERENCES Person (First_Name, Name, Address)
);
For some reason this doesn't work and I get an error every time. I've already looked up the other threads here on stackoverflow, but they don't really seem to help me. What am I doing wrong?
If you have a compound PK made up from three columns, then any child table that wants to establish a foreign key relationship must ALSO have all those 3 columns and use all 3 columns to establish the FK relationship.
FK-PK relationship is an all or nothing proposal - you cannot reference only parts of a primary key - either you reference all columns - or you don't reference.
CREATE TABLE Purchase
(
No_Installments int,
Rate int,
Person varchar(50) NOT NULL PRIMARY KEY,
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
CONSTRAINT PFK
FOREIGN KEY (First_Name, Name, Address)
REFERENCES Person (First_Name, Name, Address)
);
Have an integer primary key, using identity, auto_increment, serial or whatever for your database:
CREATE TABLE Person (
PersonId int identity PRIMARY KEY
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
CONSTRAINT unq_person_3 UNIQUE (First_Name, Name, Address)
);
Then use the identity column for the reference:
CREATE TABLE Purchase (
PurchaseId int identity PRIMARY KEY,
No_Installments int,
Rate int,
PersonId int,
CONSTRAINT PFK
FOREIGN KEY (PersonId) REFERENCES Person (PersonId)
);
Notes:
You really don't want to have to deal with a composite primary key. Have you thought about what the joins will look like?
You don't want a primary key where the values are subject to change. What happens when someone changes his/her name? When someone moves?
Person should not be the primary key in Purchases. Are you only allowing someone to make one purchase?
As noted initially, how you generate such a column varies by database; identity happens to be the way that SQL Server does this.
You probably want to assign a unique ID to each person, not relying on their name to be unique or for an address to be required. That ID will be your Primary key and foreign key. Your purchase table should also have its own id for its primary key -- otherwise because primary keys must be unique, each person can only have one purchase.
CREATE TABLE Person (
id serial NOT NULL,
First_Name varchar(20) NOT NULL,
Name varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
PRIMARY KEY (id));
CREATE TABLE Purchase (
id serial NOT NULL,
No_Installments int,
Rate int,
Person int NOT NULL,
FOREIGN KEY (Person) REFERENCES Person (id),
PRIMARY KEY (id));

error: there is no unique constraint matching given keys for referenced table "incident"

I know that this question has been already answered a million of times, but I couldn't find any solution. Well I have these three tables on postgres sql.
CREATE TABLE user_account (
id SERIAL not null,
firstName VARCHAR(60) not null,
lastName VARCHAR(60) not null,
password VARCHAR(150) not null,
email VARCHAR(40) not null UNIQUE,
isVolunteer BOOLEAN,
complete BOOLEAN,
CONSTRAINT pk_user PRIMARY KEY (id));
CREATE TABLE incident (
id SERIAL not null,
patientId INTEGER not null,
incidentTime VARCHAR(10) not null,
latitude NUMERIC not null,
longitude NUMERIC not null,
city VARCHAR(60) not null,
state VARCHAR(60),
country VARCHAR(60),
complete BOOLEAN,
CONSTRAINT pk_incident PRIMARY KEY (id, patientId),
CONSTRAINT fk_incident FOREIGN KEY (patientId)
REFERENCES user_account (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE);
CREATE TABLE incident_has_volunteer (
incidentId INTEGER not null,
volunteerId INTEGER not null,
incidentTime VARCHAR(10) not null,
complete BOOLEAN,
CONSTRAINT pk_incident_has_volunteer PRIMARY KEY (incidentId, volunteerId),
CONSTRAINT fk_volunteer FOREIGN KEY (volunteerId)
REFERENCES user_account (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_incident FOREIGN KEY (incidentId)
REFERENCES incident (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE);
When I try to create the table incident_has_volunteer it throws the error there is no unique constraint matching given keys for referenced table "incident".
I tried to add on the third table and the patientId as a foreign key from table incident table but with no luck. I can't understand why it throws this error even if I have already set the primary keys on the incident table.
I'm not an expert in postgres, but I believe that the problem is while fk_incident is referencing incident.id, incident's primary key is made of id + patientId. Since incident.id is guaranteed to be unique only in combination with patientId, there's no way to ensure referential integrity.
I believe that if you add a unique constraint to incident.id (I'm assuming that it would be unique), your foreign key will be legal.
Very simply - one table of primary key acts as a foreign key for another table, so you must ensure that both key is referenced or not.
Simply you will not assign foreign key to the column of another table which does not have primary key. this is called as RDBMS.
Thanks

(SQL) integrity constraint violated - parent key not found

I did look up for solutions for this problem but i still get the same error..
I'm trying to insert values into PART and MANUFACTURER tables. Initially, i inserted values into MANUFACTURER without knowing the fact i need to deal with the parent table i.e. PART. So, i did the PART then the MANUFACTURER but still not working :(.
These are the tables:
PART(PNum, PName, PUnitPrice, ComponentOf)
primary key (PNum)
foreign key (ComponentOf) references PART(PNum)
MANUFACTURER(MName, MAddress, MPhone)
primary key (MName)
candidate key (MPhone)
candidate key (MAddress)
PART-MANUFACTURED(MDate, PNum, MName, Quantity)
primary key (MName, PNum, MDate)
foreign key (PNum) references PART(PNum)
foreign key (MName) references MANUFACTURER(MName)
CUSTOMER(CNum, CName, CType)
primary key (CNum)
domain constraint ctype in ('INDIVIDUAL', 'INSTITUTION')
ORDERS(CNum, PNum, OrderDate, OrderQuantity)
primary key (CNum, PNum, OrderDate)
foreign key (CNum) references CUSTOMER(CNum)
foreign key (PNum) references PART(PNum)
Create statements:
CREATE TABLE PART(PNum VARCHAR(25) NOT NULL, PName VARCHAR(75) NOT NULL, PUnitPrice NUMBER(7,2) NOT NULL, ComponentOf VARCHAR(25), PRIMARY KEY(PNum), FOREIGN KEY(ComponentOf) REFERENCES PART(PNum));
Table created.
SQL> CREATE TABLE MANUFACTURER(MName VARCHAR(50) NOT NULL, MAddress VARCHAR(100) NOT NULL, MPhone VARCHAR(25) NOT NULL, PRIMARY KEY(MName), CONSTRAINT UK_MADDRESS Unique(MAddress), CONSTRAINT UK_MPHONE UNIQUE(MPhone));
Table created.
SQL> CREATE TABLE PARTMANUFACTURED(MDate DATE NOT NULL, PNum VARCHAR(25) NOT NULL, MName VARCHAR(50) NOT NULL, QUANTITY NUMBER(10) NOT NULL, PRIMARY KEY(MName, PNum, MDate), FOREIGN KEY(PNum) REFERENCES PART(PNum), FOREIGN KEY(MName) REFERENCES MANUFACTURER(MName));
Table created.
SQL> CREATE TABLE CUSTOMER(CNum VARCHAR(25) NOT NULL, CName VARCHAR(75) NOT NULL, CType VARCHAR(20) NOT NULL, PRIMARY KEY(CNum), CHECK(Ctype in('INDIVIDUAL','INSTITUTION')));
Table created.
SQL> CREATE TABLE ORDERS(CNum VARCHAR(25) NOT NULL, PNum VARCHAR(25) NOT NULL, OrderDate DATE NOT NULL, OrderQuantity NUMBER(7,2) NOT NULL, PRIMARY KEY(CNum, PNum, OrderDate), FOREIGN KEY(CNum) REFERENCES CUSTOMER(CNum), FOREIGN KEY(PNum) REFERENCES PART(PNum));
Isn't the PNum already the primary or parent key? and PART table is the parent table? since, other tables have the PNum as foreign key.. i really don't get it..
anyone knows and can help me with it, is greatly appreciated. thanks :)
The error with your insert statement INSERT INTO PART VALUES('S001', 'System-economy', 1100, 'Null') is that you are trying to insert a string 'NULL' rather than an actual NULL for the column ComponentOf in the PART table.
The problem with the string 'NULL' is that you have a FOREIGN KEY constraint on ComponentOf that references the column PNum, which means that all the values in the column ComponentOf must also be in PNum. However, there is no value 'NULL' in PNum so that's why it threw the error. An actual NULL works since it means that it is not referencing anything.
The value inserted for ComponentOf has to match an existing PNum in the PARTS table. Your key is their to ensure you don't have any "orphaned" components.
If you try to insert 'Null' (a string value as mentioned in the comments) then it can't find the "parent". However, null is allowed since it means that particular part is not a component of any other part, i.e. it doesn't have a "parent".

How to insert multiple rows into an Order table?

So I set up a simple database and I am at the point where I am trying to test that it is working correctly. I am trying to figure out how I get multiple entries into an Order table. I need to have an order# and be able to order multiple items and use multiple shippers and such. I just can't seem to figure out a way to get the data into my DB properly.
Below is how I have my DB set up. Could someone please explain to me how to get the my test data into the DB.
Here are the reference tables:
CREATE TABLE Product_Table (
ProductID INT NOT NULL,
Product_Name char(50) NOT NULL,
Product_Cost number(9,2) NOT NULL,
Product_In_Stock INT NOT NULL,
CONSTRAINT Products_PK PRIMARY KEY (ProductID)
);
CREATE TABLE Payment_Terms_Table (
PayTermNum INT NOT NULL,
Payment_Time_Frame CHAR(20) NOT NULL,
CONSTRAINT Payment_Terms_PK PRIMARY KEY (PayTermNum)
);
CREATE TABLE Shipper_Table (
ShipperNum INT NOT NULL,
Shipper_Name CHAR(50) NOT NULL,
Shipper_Phone CHAR(22) NULL,
CONSTRAINT ShipperNum_PK PRIMARY KEY (ShipperNum)
);
CREATE TABLE Supplier_Table (
SupplierID INT NOT NULL,
Supplier_Name CHAR(50) NOT NULL,
Sup_Address CHAR(50) NOT NULL,
Sup_City CHAR(20) NOT NULL,
Sup_State CHAR(20) NOT NULL,
Sup_Zip CHAR(9) NOT NULL,
Sup_Phone CHAR(22) NULL,
ShipperNum INT NOT NULL,
PayTermNum INT NOT NULL,
CONSTRAINT Supplier_PK PRIMARY KEY (SupplierID),
CONSTRAINT ShipperNum_Relationship FOREIGN KEY (ShipperNum)
REFERENCES Shipper_Table (ShipperNum),
CONSTRAINT PayTermNum_Relationship FOREIGN KEY (PayTermNum)
REFERENCES Payment_Terms_Table (PayTermNum)
);
Here is my Order table:
CREATE TABLE Order_Table (
OrderID INT NOT NULL,
ProductID INT NOT NULL,
SupplierID INT NOT NULL,
Wholesale_Price NUMBER (9,2) NOT NULL,
Units_Ordered INT NOT NULL,
Order_Date DATE DEFAULT SYSDATE NOT NULL,
Order_Received DATE NULL,
CONSTRAINT Order_PK PRIMARY KEY (OrderID),
CONSTRAINT ProductID_Relationship FOREIGN KEY (ProductID)
REFERENCES Product_Table (ProductID),
CONSTRAINT SupplierID_Relationship FOREIGN KEY (SupplierID)
REFERENCES Supplier_Table (SupplierID)
);
Your problem is that you have a defined one table to hold Orders, so you can have only one Item per Order. Normally we handle this scenario by having two tables: a Header with the information for the whole Order and a Line table for each ordered Item.
CREATE TABLE Order_Header (
OrderID INT NOT NULL,
Order_Date DATE DEFAULT SYSDATE NOT NULL,
Order_Received DATE NULL,
CONSTRAINT Order_PK PRIMARY KEY (OrderID)
)
/
CREATE TABLE Order_Line (
OrderID INT NOT NULL,
LineNo INT NOT NULL,
ProductID INT NOT NULL,
SupplierID INT NOT NULL,
Wholesale_Price NUMBER (9,2) NOT NULL,
Units_Ordered INT NOT NULL,
CONSTRAINT Order_Line_PK PRIMARY KEY (OrderID, LineNo),
CONSTRAINT Order_Line_Header_FK FOREIGN KEY (OrderID)
REFERENCES Order_Header (OrderID)
CONSTRAINT ProductID_Relationship FOREIGN KEY (ProductID)
REFERENCES Product_Table (ProductID),
CONSTRAINT SupplierID_Relationship FOREIGN KEY (SupplierID)
REFERENCES Supplier_Table (SupplierID)
)
/
I have declared a composite primary key because it is easier to understand what's happening.
Now that you have two tables you can easily create orders with more than one line.
On the subject of normal practice, an Order should have a CUSTOMER. That would be an attribute of ORDER_HEADER. Also you have a SHIPPER table but don't use it. Again that would probably be an attribute of ORDER_HEADER.
Also your naming convention is ugly. There's no need to include _TABLE: just name the objects for teh things they represent. Likewise your foreign key needs are opaque; it doesn't matter so much in this toy example but in a real database you will find it helpful to specify the child and parent tables in the FK names.