creating table having foreign key that reference another table - sql

I am using PGAdminIII database.
I have one table named STOCKREGISTER which contains composite primary key consisting of three fields ie stockregisterId,applicationId and date.
I have to create another table STOCK which has a foreignkey field that reference the field stockregisterId of STOCKREGISTER.If I am trying to create STOCK table,an error message is shown.The error message is "there is no unique contraint matching keys for referenced table STOCKREGISTER".What another step I have to take next
this first table
CREATE TABLE stock_register
(
stock_register_id bigint NOT NULL,
application_id bigserial NOT NULL,
production_date date NOT NULL,
opening_bal bigint DEFAULT 0,
quantity_produced bigint,
total_quantity bigint
CONSTRAINT primarykey PRIMARY KEY (stock_register_id, application_id, production_date),
CONSTRAINT "foreignKey" FOREIGN KEY (application_id)
REFERENCES application (application_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
below is second table.Here I cannot make stock_register_id as a foreign key
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT "stockid" PRIMARY KEY (stock_id)
)

I guess that syntax should be:
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT "stockid"
FOREIGN KEY (stock_id)
REFERENCES stock_register (stock_register_id)
)

CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT primaryKey PRIMARY KEY (stock_id),
CONSTRAINT foreignKey FOREIGN KEY(stock_register_id)
REFERENCES stock_register (stock_register_id)
)
That should be everything you need. You'll also have to make sure the DB table engines, collations and charsets match up when using Foreign Keys.
For the unique constraint issue, there doesn't seem to be a problem with your stock_register_id PK in the stock_register table. Based on the name STOCKREGISTER in the error message I suspect it wasn't finding the table stock_register in your second Create statement.

What is a foreign key? A pointer to a specific record in another table.
How is a specific record in stock_register identified according to your DDL? By the unique combination of (stock_register_id, application_id, production_date).
Therefore stock_register_id = 1 could appear on a thousand different records so long as application_id and production_date are different.
Therefore, if all you have is a stock_register_id, there is no way to know which stock_register record it is pointing to and therefore no way for the DBMS to enforce the foreign key.
You must either add application_id and production_date to the stock table and make all three columns together the FK to the composite key on stock_register, or you must remove application_id and production_date from the PK on stock_register so the FK and PK columns match.

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.

No matching unique or primary key for this column-list in Oracle

I have created PERSON table in Oracle by this SQL syntax:
Create table person
(
p_id int not null,
personName char(5) not null );
Then I am trying to create ORDERS table with the following syntax:
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 person(p_id) );
But I am getting the following error .
No matching unique or primary key for this column-list.
What is the problem ? How can I solve this ?
Add primary key to person table:
CREATE TABLE person(
p_id int not null,
personName char(5) not null,
PRIMARY KEY (p_ID)
);
SqlFiddleDemo
Foreign keys enforce a one-to-many relationship. That is, however many records there are in the dependent table they can only reference a single record in the parent table. This means the referenced column(s) in the parent table must be constrained by a PRIMARY or UNIQUE key.
The error message is telling you that there is no such constraint on person(p_id). And lo! if we compare the two DDL statements you have posted we can see that you have created a primary key for ORDERS but not for PERSON.
The solution is simple: constrain P_ID by adding a primary key to PERSON. You can either drop and re-create the table, or you can use an alter table statement to add a primary key.
You should add primary key to person table.
try this:
ALTER TABLE Person
ADD CONSTRAINT p_id PRIMARY KEY (p_id);

How to use two columns in a foreign key constraint

I have two tables:
Article
Subscription
In the Article table I have two columns that make up the primary key: id, sl. In the Subscription table I have a foreign key 'idsl`.
I use this constraint :
constraint FK_idsl
foreign key (idsl) references CSS_SubscriptionGroup(id, sl)
But when I run the query, I getting this error:
Number of referencing columns in foreign key differs from number of referenced columns, table X
In Article Table I have two fields that are the primary key: id,sl. In the Subscription Table I have a foreign key 'idsl`
This design is broken - it is apparent that the composite primary key in Article(id, sl) has been mangled into a single compound foreign key in table Subscription. This isn't a good idea.
Instead, you will need to change the design of table Subscription to include separate columns for both id and sl, of the same type as the Article Table, and then create a composite foreign key consisting of both columns, referencing Article in the same order as the primary key, e.g:
CREATE TABLE Article
(
id INT NOT NULL,
sl VARCHAR(50) NOT NULL,
-- Other Columns
CONSTRAINT PK_Article PRIMARY KEY(id, sl) -- composite primary key
);
CREATE TABLE Subscription
(
-- Other columns
id INT NOT NULL, -- Same type as Article.id
sl VARCHAR(50) NOT NULL, -- Same type as Article.sl
CONSTRAINT FK_Subscription_Article FOREIGN KEY(id, sl)
REFERENCES Article(id, sl) -- Same order as Article PK
);
Edit
One thing to consider here is that by convention a column named table.id or table.tableid should be unique, and is the primary key for the table. However, since table Article requires an additional column sl in the primary key, it implies that id isn't unique.
correct syntax for relation:
CONSTRAINT FK_OtherTable_ParentTable
FOREIGN KEY(OrderId, CompanyId) REFERENCES dbo.ParentTable(OrderId, CompanyId)
You must try like this:
constraint FK_idsl foreign key (id,sl) references CSS_SubscriptionGroup(id,sl)

SQL Server Foreign Key

I'm trying to create this database with the following relations in SQL Server and I get this error:
Msg 1776, Level 16, State 0, Line 11
There are no primary or candidate keys in the referenced table 'Consumable' that match the referencing column list in the foreign key 'FK_Recipe_Ingredie__59FA5E80'.
Msg 1750, Level 16, State 0, Line 11
Could not create constraint. See previous errors.
What am I doing wrong?
Here's my code;
CREATE TABLE Consumable
(
c_ID int NOT NULL,
Name varchar(32) NOT NULL,
Amount int,
Unit varchar(8) NOT NULL CHECK (unit IN ('ml', 'g', 'pieces', 'unknown')),
CONSTRAINT PK_Consumable PRIMARY KEY (c_ID, Name)
)
CREATE TABLE Recipe
(
Name varchar(64) PRIMARY KEY NOT NULL,
Type varchar(32),
Description varchar(512),
IngredientsID int NOT NULL FOREIGN KEY REFERENCES Consumable(c_ID) ON DELETE CASCADE
)
CREATE TABLE Kitchen
(
K_ID int PRIMARY KEY NOT NULL IDENTITY,
IngredientsID int FOREIGN KEY REFERENCES Consumable(c_ID) ON DELETE CASCADE
)
Read the error message!
It's pretty clear: the foreign key you're trying to set up from Recipe.IngredientsID doesn't reference the primary key of your target table (Consumable - primary key is (c_ID, Name) - not just c_ID ....)
To fix this: you must reference the whole compound PK on your target table (e.g. you must have both columns of PK_Consumable in your child table in order to reference it
CREATE TABLE Recipe
(
Name varchar(64) PRIMARY KEY NOT NULL,
Type varchar(32),
Description varchar(512),
IngredientsID int NOT NULL,
IngredientsName varchar(32) NOT NULL,
CONSTRAINT FK_Recipe_Consumable
FOREIGN KEY (IngredientsID, IngredientsName)
REFERENCES Consumable(c_ID, Name) ON DELETE CASCADE
)
Any foreign key can only ever reference the WHOLE primary key of a parent table - or a unique constraint (again: all columns involved in that unique constraint). You cannot just simply refer to an arbitrary column (or set of columns) in your parent table.
Your Pk is a composite PK and so c_id is not necessarily unique and thus cannot be used in an FK relationship.
You have several choices depending that you had. If you will not have multiple of c_id in the consumables table than you can create a unique index on it and you should be able to create the Fk. BUt in that case really why are you using a compositer OK? The other choice you have in this situation is to make just the c_id the PK and then put a unique index on Name. Never use a composite PK if you don't have to.
If the C_id will into be unique in the Consumable table, then the only choice you have is to add the name column to the Other tables. You would of course have to give it a different name in Recipe since it has a different name.
Ingredients_id doesn't make sense in the recipe table as you are going to have more than one ingredient in a recipe. You should have a child table that contains recipe ingredients.
And On Delete Cascade is a poor choice as well. Very bad thing to do to a nice innocent database. Do you really want to delete the recipes you are out of an ingredient? I don't think so.

SQL Table Foreign Key that is part of a Composite Primary Key

Is it possible to have a table's foreign key be part of another table's composite primary key?
For example, if I have two tables, one contains information on all active projects of different users and another containing information on what equipment is being used by the projects:
Project Table:
Composite Primary Keys: UserId, ProjectId (neither are unique by themselves)
Equipment Table:
Composite Primary Keys: UserId, ProjectId, EquipmentId (neither are unique by themselves)
Now is it possible to set the ProjectId in the equipment table to be a foreign key from the project table? When I try, I get an error saying that the column in Project Table do not match an existing primary key or unique constraint?
No.
When you create a foreign key, the key that you "point to" in the other table must be a UNIQUE or PRIMARY KEY constraint. You cannot establish a foreign key that points to a column that allow duplicate values. It would be very hard to imagine how the data should "act" if you update one of the duplicate values in the other table (for instance).
To do what you want you must establish a Projects table in which ProjectID is UNIQUE or a PRIMARY KEY and then point foreign keys in both the other tables to that table.
Parenthetically, you use the term "Primary Keys" to describe the columns in each table that make up the primary key. In fact, each table can have one and only one primary key. That key can be composed of one or more columns, but the key itself is still referred to in the singular. This is an important difference when using the primary key to optimize searches.
It do not know if that's a good design practice but for sure it is possible to have a composite foreign key of one table that is the part of the composite primary key of other table.
Say we have a table test1 having a composite primary key (A, B)
Now we can have a table say test2 having primary key (P, Q, R) where in (P,Q) of test2 referencing (A,B) of test2.
I ran the following script in the MySql database and it works just fine.
CREATE TABLE `test1` (
`A` INT NOT NULL,
`B` VARCHAR(2) NOT NULL,
`C` DATETIME NULL,
`D` VARCHAR(45) NULL,
PRIMARY KEY (`A`, `B`));
CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NOT NULL,
`R` INT NOT NULL,
`S` DATETIME NULL,
`T` VARCHAR(8) NULL,
PRIMARY KEY (`P`, `Q`, `R`),
INDEX `PQ_idx` (`P`,`Q` ASC),
CONSTRAINT `PQ`
FOREIGN KEY (`P`, `Q`)
REFERENCES `test1` (`A`,`B`)
ON DELETE CASCADE
ON UPDATE CASCADE);
In the above mentioned case, the database is expecting the combination of (A,B) to be unique and it is, being a primary key in test1 table.
But if you try to do something like following, the script would fail. The database would not let you create the test2 table.
CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NULL,
`R` DATETIME NULL,
`S` VARCHAR(8) NULL,
`T` VARCHAR(45) NULL,
INDEX `P_idx` (`P` ASC),
INDEX `Q_idx` (`Q` ASC),
CONSTRAINT `P`
FOREIGN KEY (`P`)
REFERENCES `test1` (`A`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `Q`
FOREIGN KEY (`Q`)
REFERENCES `test1` (`B`)
ON DELETE CASCADE
ON UPDATE CASCADE);
In the above mentioned case database would expect the column A to be unique individually and the same follows for column B. It does not matter if combination of (A,B) is unique.
#Larry Lustig
The foreign key can be part of primary key in the other table.
source: Dependent relationship
Check relationship between tables: Zdarzenie(Event) and TypZdarzenia (type of event)