violated - parent key not found error - sql

I have the following error appearing:
INSERT INTO GroupMembers VALUES ('Goldfrat', 'Simon Palm')
*
ERROR at line 1:
ORA-02291: integrity constraint (SHAHA1.IAM_IS_GROUP_FK) violated - parent key
not found
The constraint in the GroupMembers table is:
CONSTRAINT iam_is_group_fk FOREIGN KEY(is_group) REFERENCES Members(group_name)
The Members Table looks like this:
CREATE TABLE Members (
group_name VARCHAR2(40),
CONSTRAINT g_id_pk PRIMARY KEY(group_name),
CONSTRAINT m_group_name_fk FOREIGN KEY(group_name) REFERENCES Artist(artistic_name));
All of the tables are created fine until it comes to creating the GroupMembers table. Anyone have any ideas? I've been scratching for quite a while.

The problem is that
CONSTRAINT iam_is_group_fk FOREIGN KEY(is_group) REFERENCES Members(group_name); references the table Members on the group_name field.
This means that the field is_group on the table GroupMembers must have an identical value on the table Members and group_name field.
In my opinion, this is bad practice.
First of all, you should have a primary key field on the table GroupMembers. You should not store the names of the group members in the table GroupMembers, but their corresponding id from the table Members.
Also, the table Members should look something like this:
CREATE TABLE Members (
member_id NUMBER PRIMARY KEY
member_name VARCHAR2(40),
CONSTRAINT g_id_pk PRIMARY KEY(member_id),
CONSTRAINT m_group_name_fk FOREIGN KEY(group_name) REFERENCES Artist(artistic_name));
Then on the table GroupMembers, I suppose you want to associate some members to their set of groups and back, so you should do something like this:
CREATE TABLE GroupMembers (
member_id NUMBER,
group_id NUMBER
)
CONSTRAINT iam_is_member_fk FOREIGN KEY(member_id) REFERENCES Members(member_id);
CONSTRAINT iam_is_member_fk FOREIGN KEY(group_id) REFERENCES Groups(group_id);
Supposing that you have a table Groups containing all the group details, with the primary key stored as number , and name group_id.
Always remember that each table must have a primary key. It is good practice for this key to be a number.
So by having member_id in Members, group_id in Groups, you can create a many-to-many relationship in GroupMembers. Also, put a unique index on this table so you don't have duplicates ( the same member associated with the same id several times ).
Look at this example linking users to roles. It is the same case:

error is
you have to use same column name which is defined in reference table
i.e
CONSTRAINT m_group_name_fk FOREIGN KEY(group_name) REFERENCES Artist(group_name)
That group_name should be define as primary key in Artist Table.

Order in which you are insert is the reason for the error.
Members(group_name) does not contain Goldfrat. If this is not true then it's not there in the table Artists.

Related

Away around Error: There is no unique constraint matching given keys for referenced table

Been at this for some time now. I'm getting this psql error when attepmting to create a joins table (product_type_combo):
There is no unique constraint matching given keys for referenced table product
I'm receiving this because the field (customer) I'm referencing from the table product does not have a UNIQUE constraint.
CREATE TABLE product
(
id SERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
customer VARCHAR,
CONSTRAINT product_c01 UNIQUE (name)
);
CREATE TABLE product_type_combo
(
customer VARCHAR REFERENCES product(customer),
type_id INT REFERENCES type(id),
PRIMARY KEY (customer, type_id),
CONSTRAINT product_type_combo_c01 UNIQUE (customer, type_id)
);
I don't want to have a UNIQUE constraint on the customer field on the product table since I want duplicates to appear there. I only want the customer & type combo in the joins table to have a constraint.
Is there a way around this?
This is silly:
customer VARCHAR REFERENCES product(customer),
You have a primary key on the table, an id column. You should be using that.
You could define customer to be unique -- the lack of a unique constraint on a column used for a foreign key reference is the cause of the error. However, I strongly, strongly recommend that you use the primary key.
The error is coming from the Foreign Key (REFERENCES) constraint, for reasons listed in the PostgreSQL manual:
A foreign key must reference columns that either are a primary key or form a unique constraint.
Since your "customer" column is not unique, it cannot be the target of a foreign key reference. It also suggests a problem in your data model:
If the relationship is between a product and a type, then referencing the "id" from the products table would make sense.
If the relationship is between a customer and a type, then there should be a table listing all the possible customers, and you can create foreign keys referencing that from both "product" and "product_type_combo" (which would presumably be better named "customer_type_combo").

Foreign key referencing primary key of multiple values

Im using ms sql server. I get this msg when I reference a primary key that is a composite key of 3 values in the foreign key.
"number of referencing columns in foreign key differs from the number of reference columns". The problem lies in second last line of code in member booking. Any ideas? Thanks in advance.
CREATE TABLE room
(
Block CHAR (1),
Lvl INT,
rNum INT,
RmType VARCHAR (15),
Condition VARCHAR (15),
CONSTRAINT room_PK PRIMARY KEY (Block, Lvl, rNum),
)
CREATE TABLE booking
(
BookingID INT,
BStartDate DATE,
BEndDate DATE,
Fee DECIMAL (8,2) NOT NULL CHECK (fee >= 0),
Memberbooking INT NOT NULL,
MemberID INT NOT NULL,
CONSTRAINT booking_pk PRIMARY KEY (BookingID),
CONSTRAINT FK_Booking FOREIGN KEY (Memberbooking) references room (Block, Lvl, rNum),
CONSTRAINT FK_MemberID FOREIGN KEY (MemberID) references member (ID)
)
You are getting an error because you are trying to map 1 column (FOREIGN KEY (Memberbooking)) with 3 columns room (Block, Lvl, rNum)
it's possible to create a foreign key relationship to a compound (more
than one column) primary key, make sure to specify the same number of columns in your FOREIGN KEY
You define this constraint in the table booking:
CONSTRAINT FK_Booking FOREIGN KEY (Memberbooking) references room (Block, Lvl, rNum)
meaning that you want the column Memberbooking to reference 3 columns (!!) in the table room.
Each column from a table can reference one column from another table, not multiple ones.
You can define the same column to reference more than 1 columns in another table, but with different constraints, and always 1 to 1.
Read more here: Create Foreign Key Relationships
Since I see from the comments you are intent to implement this type of check, I would propose a check constraint:
CONSTRAINT CK_MemberID CHECK (EXISTS(SELECT 1 FROM room where Memberbooking=room.Block+convert(nchar,room.Lvl)+convert(nchar,room.rNum)))
However, this design is not very good. The lack of seperators in the Membermooking field might cause collisions.
Eg, consider you have a Memberbooking: 'A1101'
Is that Block A, Lvl 11, rNum 01? Or is it Block A, Lvl 1, rNum 101?
On table "room", you currently have a compound natural key. This is a valid design decision. The alternative would be to add a single column artificial id, such as an int Identity. That would lead to two keys on the same table (one of them Primary Key, the other one Unique constraint).
In a foreign key constraint, you can reference any Unique constraint or Primary Key. If you want to keep the "room" table the way it is, then you need to mirror those key fields in the referencing table. So that would mean your "booking" table would need a Block char(1), Lvl int and rNum int column.
That is why an artificial key (on room) can be useful, because then your foreign key constraint (on booking) can be single column and reference that Unique constaint.

Create a table in SQL where the Composite Primary Key is also a Foreign Key

I need to create a table called LFM_Enroll in SQL that has a composite primary key of Student_ID and Section_Number. Student_ID is also a foreign key, it references Student_ID in the LFM_Student table and Section_Number is also a foreign key, it references Section_Number in the LFM_Section table. How do I write the constraints and foreign keys? I've attached an image of the tables and below is what I have done so far. After the LFM_Enroll table is created I need to update one row. I tried doing so but kept getting the below error.
: Error starting at line : 173 in command -
UPDATE LFM_Enroll
SET Student_ID = 1234567,
Section_Number = 01234
WHERE Student_ID = 900000 AND Section_Number = 4138
Error report -
ORA-02291: integrity constraint (SYSTEM.FK_LFM_ENROLL_SECTION_NUMBER) violated - parent key not found.
Tables Thanks in advance for all your help.
CREATE TABLE LFM_Enroll (
Student_ID char(7),
Section_Number char(4),
constraint PK_LFM_Enroll Primary Key (Student_ID,Section_Number),
constraint FK_LFM_Enroll_Student_ID
Foreign Key (Student_ID,Section_Number) references LFM_Student (Student_ID),
constraint FK_LFM_Enroll_Section_Number
Foreign Key (Student_ID,Section_Number) references LFM_Section (Section_Number)
);
Your foreign key constraints are not right. You are trying to map two columns {Student_ID,Section_Number} to a single column LFM_Student.Student_ID.
The number of columns in the principal key must match the number of columns in the foreign key. In other words, the key LFM_Student is one column (Student_ID), so the foreign key also needs to be a single matching column - in this case LFM_Enroll.Student_ID. Correct DDL would be:
constraint FK_LFM_Enroll_Student_ID
Foreign Key (Student_ID) references LFM_Student (Student_ID),
constraint FK_LFM_Enroll_Section_Number
Foreign Key (Section_Number) references LFM_Section (Section_Number)
I'm not quite sure why your RDBMS is allowing what you have, but it may be using the first column and simply ignoring the second. In which case FK_LFM_Enroll_Section_Number is creating a foreign key LFM_Enroll.Student_ID => LFM_Section.Section_Number.
The error indicates that the values with which you are trying to update the two columns may not exist in Student and / or Sections tables i.e. 1234567 doesn't exists in the student table and / or 01234 doesn't exist in your section table . You should try inserting new rows or updating existing ones with the new values you are trying to update your foreign keys with.
[Edit: For defining constraints refer lc.'s post]

SQL Constraint on join table

I have four tables in a PostgreSQL database:
Company
User (with a foreign key column company_id)
Location (with a foreign key column company_id)
UserLocations (an association table, with foreign key columns user_id and location_id)
Essentially:
a company has many users and locations
a user belongs to a company and has many locations
a location belongs to a company and has many users
I want to know if there is a way for the database to constrain entries in the UserLocations association table such that the referenced user and location must have an identical company_id value. I don't want a user from company A to have a location from company B.
I can check this at my application layer (rails) but would be interested in making this a hard database level constraint if the option exists.
One way you can accomplish this is with foreign key references and redundancy.
So, the UserLocations table would have a UserId, LocationId, and CompanyId. It would then have the following foreign key relationships:
foreign key (UserId, CompanyId) references Users(UserId, CompanyId)
foreign key (LocationId, CompanyId) references Locations(LocationId, CompanyId)
Of course, you have to declare Users(UserId, CompanyId) and Locations(LocationId, CompanyId) as unique keys for the reference. This is a bit redundant, but it does guarantee the matching to company without creating triggers.
Overlapping foreign key constraints are your friend.
create table company (
company_id integer primary key
);
-- Reserved words include "user". Better to use identifiers that
-- are not reserved words.
create table "user" (
user_id integer primary key,
company_id integer not null references company (company_id),
-- Unique constraint lets this be the target of a foreign key reference.
unique (user_id, company_id)
);
create table location (
location_id integer primary key,
company_id integer not null references company (company_id),
unique (location_id, company_id)
);
create table user_location (
user_id integer not null,
location_id integer not null,
company_id integer not null,
-- Not sure what your primary key is here.
-- These foreign keys overlap on the column "company_id", so there
-- can be only one value for it.
foreign key (user_id, company_id) references "user" (user_id, company_id),
foreign key (location_id, company_id) references location (location_id, company_id)
);

what is FOREIGN KEY is for?

let's say i have 2 tables:
Department(depNum)
Worker(id,deptNum) - key should be id
now i want dept to reference an existing value in Department.
so i write in create table:
CREATE TABLE Worker(
id integer primary key,
dept integer references Department);
my question is, i've seen in many examples that you also put foreign key with the references statement. i don't understand what is primary key for.
does it mean that dept will be also a key on Worker?
thank you
From Wikipedia:
A primary key is a combination of columns which uniquely specify a
row. It is a special case of unique keys. . . . Primary keys were
added to the SQL standard mainly as a convenience to the application
programmer.
You cannot reference a record in a table without a primary key. A foreign key lets you reference a record in another table within an individual record. This foreign key is usually referencing the primary key in the foreign table.
This post has a lot of great information. In particular, check out the highest ranked answer for a bullet list of do's and do not's.
What's wrong with foreign keys?
This post gives a pretty decent explanation, given the poster's
original example:
What will these foreign keys do?
Let's say that each worker can only work in one department at any one time.
So each department has its own unique ID. This is the department's primary key because two departments should never have the same id.
Now, each individual worker must be tracked so they are also assigned their own unique ID. This is their primary key. You need to link the worker to the department that they work in and since they can only work in one department at a time, you can have their department as a foreign key. The foreign key in the worker table is linked to the ID of the department table.
This has more information: http://www.1keydata.com/sql/sql-foreign-key.html
You have two tables:
PLAYER,
primary key (unique) PK_player_id
player_name
foreignt key to TEAM.team_id FK_team_id
TEAM
primary key (unique) PK_team_id
team_name
Every PLAYER is in exact one TEAM.
The PLAYER has a FOREIGN-KEY to the TEAM (FK_team_id). Also you can delete the TEAM, which will delete all player in it cascading (if configured).
Now you can't create a player without an existing TEAM, because the database ensures this.
EDIT:
Didn't you ask for the foreign key?
The primary key is one or more than one column, which will identify on datarow within your database. If jou want to create a foreign key, you have to use a column or more than one column) which is unique.
In my example, there is a unique key (the primary key) for every table, because the name may change. To identify the 'target' of the foreign key, it has to be unique. so it is liklye to use the prmary key of the second table. (TEAM.PK_team_id)
I am not clear, the requirement should be
Department(dept)
Worker(id,dept) - key should be id
which means dept is the primary key in Department and foreign key in worker.
the foreign key is not unique in worker table but it is unique in Department Table.
The worker table cannot have some unknown department which is not defined in the Department.
Did I make sense ?
To ensure the integrity of the tables, not allowing you to enter values in the table (Worker) without referencing an existing row (at Department)
According to the SQL-92 Standard:
A foreign key (FK) may reference either a PRIMARY KEY or a UNIQUE CONSTRAINT. In the case of a PRIMARY KEY, the referenced columns may be omitted from the foreign key declaration e.g. the following three are all valid:
CREATE TABLE Department ( Department INTEGER NOT NULL PRIMARY KEY, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department, ...);
CREATE TABLE Department ( Department INTEGER NOT NULL PRIMARY KEY, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department (dept), ...);
CREATE TABLE Department ( Department INTEGER NOT NULL UNIQUE, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department (dept), ...);
The following is not valid:
CREATE TABLE Department ( Department INTEGER NOT NULL UNIQUE, ...);
CREATE TABLE Worker (dept INTEGER REFERENCES Department, ...);
...because the referenced columns involved in the foreign key must be declared.
When declaring a simple (single-column) FK in-line the FOREIGN KEY keywords are omitted as above.
A composite (multiple-column) cannot be declared in-line and a simple FK need not be declared in-line: in these cases, the referencing column(s) AND the FOREIGN KEY keywords are required (the rules for the referenced columns remain the same as stated earlier) e.g. here are just a few examples:
CREATE TABLE Department ( Department INTEGER NOT NULL PRIMARY KEY, ...);
CREATE TABLE Worker (dept INTEGER, FOREIGN KEY (dept) REFERENCES Department, ...);
CREATE TABLE Department ( Department INTEGER NOT NULL UNIQUE, ...);
CREATE TABLE Worker (dept INTEGER, FOREIGN KEY (dept) REFERENCES Department (dept), ...);
CREATE TABLE DepartmentHistory
(
dept INTEGER NOT NULL,
dt DATE NOT NULL,
PRIMARY KEY (dt, dept),
...
);
CREATE TABLE Worker
(
dept INTEGER NOT NULL,
dept_dt DATE NOT NULL,
FOREIGN KEY (dept_dt, dept) REFERENCES DepartmentHistory,
...
);