Check constraint in database db2 - sql

I'm designing a database that has, amongst others, the following entities:
create table Director(
ID integer not null,
YearsExperience integer not null,
StudioAffiliation varchar(30),
NetWorth REAL,
primary key (ID)
);
create table Movie(
ID varchar(20) not null,
Title varchar(40) not null,
Genre char(1) not null,
ReleaseDate date not null,
Earning real not null,
primary key (ID)
);
Now Director and Movie have 2 relationship: Direct and WonAward. The later is to record whether a director has won an award or more with the movie he/she directed:
create table Directs(
DirectorID integer not null,
MovieID varchar(20) not null,
primary key (DirectorID, MovieID),
foreign key (DirectorID) references Director (ID) on delete cascade,
foreign key (MovieID) references Movie (ID) on delete cascade
);
create table WonAward(
DirectorID integer not null,
MovieID varchar(20) not null,
AwardName varchar(30) not null,
Year integer not null,
Budget REAL not null,
primary key (DirectorID, MovieID),
foreign key (DirectorID) references Director (ID) on delete cascade,
foreign key (MovieID) references Movie (ID) on delete cascade
);
I need to make sure that a Director gets awards for only movies he/she has directed. Now I have tried using Check to achieve that but it keeps giving me error for the following 2 condition at the end of the WonAward relationship:
check (DirectorID = (SELECT DirectorID FROM Directs WHERE Directs.MovieID = MovieID)),
check (MovieID = (SELECT MovieID FROM Directs WHERE Directs.DirectorID = DirectorID))
This is the error I keep getting:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0548N A check constraint or generated column that is defined with "SELECT"
is invalid. SQLSTATE=42621
Without these constraints I found out that a user can enter into a database an award won for a director for a movie that wasn't directed by them. How can I make this happen?

You cannot create check constraints that query data outside the row in question. What you could do is create a BEFORE TRIGGER to verify the conditions are met. There are some examples in the CREATE TRIGGER documentation that could be customized to your needs.

Define a foreign key from WonAward to Directs, instead:
create table WonAward(
DirectorID integer not null,
MovieID varchar(20) not null,
AwardName varchar(30) not null,
Year integer not null,
Budget REAL not null,
primary key (DirectorID, MovieID),
foreign key (DirectorID, MovieID) references Directs
);

Related

References with PostgreSQL

I have this table:
CREATE TABLE cars_info.cars
(
id SERIAL,
owner_id INTEGER,
brand VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
color VARCHAR(50) NOT NULL,
register_number VARCHAR(50) NOT NULL,
created DATE NOT NULL,
PRIMARY KEY(id, brand, model, color, register_number, created),
CONSTRAINT fk_owner_id
FOREIGN KEY(owner_id)
REFERENCES persons_info.persons(id)
);
But when I tried create another table like this:
CREATE TABLE cars_info.violations
(
id SERIAL PRIMARY KEY,
car_id INTEGER NOT NULL,
message VARCHAR(100) NOT NULL,
active BOOLEAN NOT NULL,
CONSTRAINT fk_car_id
FOREIGN KEY(car_id)
REFERENCES cars_info.cars(id)
);
I get an error about that
Target external table "cars" does not have a unique constraint corresponding to the given keys
How can I fix that? I'm a beginner in SQL and don't know how to go about googling that
Your primary key definition for cars
PRIMARY KEY(id, brand, model, color, register_number, created)
makes no sense: The id column, being serial, is itself unique and it alone should be the primary key.
Delete your primary key definition and change the id column definition to:
id serial not null primary key
Unrelated, but best practice is to name table in the singular; name your tables car and violation rather than cars and violations

there is no unique constraint matching given keys for referenced table in SQL

CREATE TABLE TEST( course_number INTEGER NOT NULL,
semester INTEGER NOT NULL,
time INTEGER NOT NULL,
room INTEGER NOT NULL,
day INTEGER NOT NULL,
credit_points INTEGER NOT NULL,
UNIQUE(course_number,semester),
CHECK(course_number>0),
CHECK(credit_points>0),
CHECK(room>0));
CREATE TABLE STUDENT (student_id INTEGER NOT NULL,
student_name text NOT NULL,
faculity text NOT NULL,
credit_points INTEGER NOT NULL,
UNIQUE(student_id),
CHECK(student_id>0),
CHECK(credit_points>=0));
CREATE TABLE STUDENT_REG
(student_id INTEGER NOT NULL,
course_number INTEGER NOT NULL,
semester INTEGER NOT NULL,
FOREIGN KEY (student_id) REFERENCES STUDENT(student_id),
FOREIGN KEY (course_number) REFERENCES TEST(course_number),
FOREIGN KEY (semester) REFERENCES TEST(semester));
I have three tables:
Test
Student
Student registration, it's purpose is to a student to a course.
I get this error when I compile the third table:
ERROR: there is no unique constraint matching given keys for referenced table "test"
I have no idea why, any help will be highly appreciated.
You want a compound foreign key rather than two distinct keys:
CREATE TABLE STUDENT_REG (
student_id INTEGER NOT NULL,
course_number INTEGER NOT NULL,
semester INTEGER NOT NULL,
FOREIGN KEY (student_id) REFERENCES STUDENT(student_id),
FOREIGN KEY (course_number semester) REFERENCES TEST(course_number, semester)
);
Why you need that is because table TEST as has compound unique key on these two columns:
UNIQUE(course_number,semester)
So for table STUDENT_REG to unambigously refer to a row in TEST, you need the combination of both columns, which means a 2-columns foreign key rather than two distinct foreign keys.

ERROR: violates foreign key constraint, key is not present in parent table (but it is??)

I know this question has been asked many times, but none of the answers have solved my issue.
I am creating a database for a uni assignment, using PostgreSQL through pgadmin 4, and I have a table named "staff" populated with staff members with a primary key of "staffid". I then have another table named "client_international", which includes a foreign key of "staffid" which relates to the staff tables primary key.
When trying to insert into the client table, I am getting the following error:
ERROR: insert or update on table "client_international" violates foreign key constraint "intclient_staff_fkey"
DETAIL: Key (staffid)=(100000024) is not present in table "staff".
SQL state: 23503
I am certain that that '100000024' key is in the staff table.. yet I still get the error. Any suggestions? Below I will paste the code I used to create the staff and client tables, in case anyone notices an error in them.
Staff table:
CREATE SEQUENCE staff_seq
start 100000000
increment 1;
CREATE TABLE staff
(
staffid integer default nextval('staff_seq'),
firstname varchar(20) NOT NULL,
lastname varchar(20) NOT NULL,
"position" varchar(20) NOT NULL,
mobile varchar(20) NOT NULL,
email varchar(100) NOT NULL,
"location" integer NOT NULL,
CONSTRAINT staff_pkey PRIMARY KEY (staffid)
);
Client table:
CREATE SEQUENCE client_seq
start 200000000
increment 1;
CREATE TABLE client
(
clientid integer default nextval('client_seq'),
company varchar(100) NOT NULL,
sector varchar(100) NOT NULL,
pointofcontact varchar(20) NOT NULL,
mobile varchar(20) NOT NULL,
email varchar(100) NOT NULL,
approvalstatus boolean default (false),
"location" integer NOT NULL,
staffid integer NOT NULL,
CONSTRAINT client_pkey PRIMARY KEY (clientid)
);
CREATE TABLE client_international
(
CONSTRAINT client_international_pkey PRIMARY KEY (clientid)
) INHERITS ("client");
ALTER TABLE client
ADD CONSTRAINT client_location_fkey FOREIGN KEY ("location") REFERENCES "location" (locationid),
ADD CONSTRAINT client_staff_fkey FOREIGN KEY (staffid) REFERENCES staff (staffid);
ALTER TABLE client_international
ADD CONSTRAINT intclient_location_fkey FOREIGN KEY ("location") REFERENCES "location" (locationid),
ADD CONSTRAINT intclient_staff_fkey FOREIGN KEY (staffid) REFERENCES staff (staffid);
I get the error when running the following statements:
INSERT INTO client_international(company, sector, pointofcontact, mobile, email, approvalstatus, "location", staffid)
VALUES ('Moores Dogs', 'Border Patrol', 'Carol Moore', '07911 653453', 'jenkinsj#k9solutions.co.uk', 'false', '500000001', '100000024');
Here's a screenshot of the entry in the staff table, showing that it's definitely in there:
Foreign keys aren't "inherited".
Quote from the manual
A serious limitation of the inheritance feature is that [...] foreign key constraints only apply to single tables, not to their inheritance children. This is true on both the referencing and referenced sides of a foreign key constraint.
(emphasis mine)
So what you are trying to do, simply isn't supported.

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

The INSERT statement conflicted with the FOREIGN KEY constraint"

I'm trying to insert data into my SQL Server 2014 build and I keep getting this error. I tried searching all over the internet and at my whits end, I sort of get what people were saying but still having difficulty understanding what's wrong with my particular code.
All tables are empty without data. I cannot add data once the foreign keys are set. I read that both tables must be populated for this to work but how does that happen when I can't add anything? If I add data before the foreign key, then I'm unable to add foreign keys. Please help!
When trying to insert data into Gym row using the INSERT INTO I get this error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__Gym__staffNo". The conflict occurred in database "FitnessApp", table "dbo.Staff", column 'staffNo'.
This also happens when trying to add data into the Equipment or Staff tables as well.
See code here:
Schema:
CREATE TABLE Gym
(
gymNo int NOT NULL IDENTITY(1,1),
staffNo int NOT NULL,
streetAddress varchar(100) NOT NULL,
streetAddress2 varchar(100) NULL,
city varchar(50) NOT NULL,
state char(2) NOT NULL,
zip char(5) NOT NULL,
phone char(10) NOT NULL
) ON [fitnessPlusGroup1];
CREATE TABLE Staff
(
staffNo int NOT NULL IDENTITY(1,1),
gymNo int NOT NULL,
position varchar(50) NOT NULL,
firstName varchar(50) NOT NULL,
lastName varchar(50) NOT NULL,
streetAddress varchar(100) NOT NULL,
streetAddress2 varchar(100) NULL,
city varchar(50) NOT NULL,
state char(2) NOT NULL,
zip char(5) NOT NULL,
phone char(10) NOT NULL,
hireDate date NOT NULL
) ON [fitnessPlusGroup1];
CREATE TABLE Member
(
memberNo int NOT NULL IDENTITY(1,1),
gymNo int NOT NULL,
firstName varchar(30) NOT NULL,
lastName varchar(30) NOT NULL,
streetAddress varchar(100) NOT NULL,
streetAddress2 varchar(100) NULL,
city varchar(50) NOT NULL,
state char(2) NOT NULL,
zip char(5) NOT NULL,
phone char(10) NOT NULL,
memberSince date NOT NULL,
scheduleID int NULL
) ON [fitnessPlusGroup1];
CREATE TABLE Schedule
(
scheduleID int NOT NULL IDENTITY(1,1),
staffNo int NOT NULL,
trainDate date NOT NULL,
trainTime time(0) NOT NULL
) ON [fitnessPlusGroup1];
CREATE TABLE Equipment
(
equipNo int NOT NULL IDENTITY(1,1),
gymNo int NOT NULL,
staffNo int NOT NULL,
name varchar(50) NOT NULL,
quantity int NOT NULL
) ON [fitnessPlusGroup1];
Foreign key relationships setup:
ALTER TABLE Gym
ADD FOREIGN KEY (staffNo) REFERENCES Staff(staffNo);
ALTER TABLE Staff
ADD FOREIGN KEY (gymNo) REFERENCES Gym(gymNo);
ALTER TABLE Member
ADD FOREIGN KEY (gymNo) REFERENCES Gym(gymNo);
ALTER TABLE Member
ADD FOREIGN KEY (scheduleID) REFERENCES Schedule(scheduleID);
ALTER TABLE Schedule
ADD FOREIGN KEY (staffNo) REFERENCES Staff(staffNo);
ALTER TABLE Equipment
ADD FOREIGN KEY (gymNo) REFERENCES Gym(gymNo);
ALTER TABLE Equipment
ADD FOREIGN KEY (staffNo) REFERENCES Staff(staffNo);
The insert commands that give errors:
INSERT INTO Gym(staffNo, streetAddress, streetAddress2, city, state, zip, phone)
VALUES (1, '7300 W Greens Rd', NULL, 'Houston', 'TX', '77064', '2818946151');
Any help would be much appreciated sorry if this seems like a bit much and I hope I provided all the info I could..
I think the problem is in your table design. Take these two FKEY, as an exmpale:
ALTER TABLE Gym
ADD FOREIGN KEY (staffNo) REFERENCES Staff(staffNo);
ALTER TABLE Staff
ADD FOREIGN KEY (gymNo) REFERENCES Gym(gymNo);
You cannot add a record to Gym until you've added the supporting staffNo to Staff. But you cannot add a record to Staff until you've added the supporting gymNo to Gym. These keys prevent you populating either table, as both require records to be present in the other.
Why is this? Because an FKey is like a promise. It guarantees that the value in column x can always be found in table y. In order to fulfill this promise table y must be populated first. But when you have a circular reference, back to the original table, this can never be achieved.
Here is one possible solution. You could remove the staffNo from Gym and GymNo from Staff. Then add a new table StaffGym. This table would have two fields staffNo and gymNo. It would be populated after Staff and Gym, providing a bridge between the two. This is called a cross reference table, or sometimes xref for short.
You say:
All tables are empty without data.
So there is no staffNo with id = 1 in your Staff. You've got a foreign key constraint so you can only reference items that exist. So you first need to populate the lookup data in Staff before you can link to it with an ID.
Also, remove one of the constraint between Staff and Gym, you have this:
ALTER TABLE Gym
ADD FOREIGN KEY (staffNo)
REFERENCES Staff(staffNo);
ALTER TABLE Staff
ADD FOREIGN KEY (gymNo)
REFERENCES Gym(gymNo);
When you only need one of these. I'd say remove it from Gym, as a Gym could have many staff I'd assume, and also remove the StaffNo column from Gym. As this is preventing you from creating one without the other. Once you've removed that link, you should insert data in the correct order.
The order of the inserts is key. If you remove the column I suggested above, you should insert in the following order based on your constraints:
Gym
Staff (requires gym record)
Schedule (requires staff record)
Member (requires schedule record)
Equipment (requires gym and staff record)