SQL Server foreign key constraints issue - sql

I have 2 tables :
dog
dogowner
I am trying to create a foreign key from DogOwner to Dog but not on the Primary Key of the dog table.
I am planning to create my own unique id's for the dog table's dog_id column.
Herewith the schemas :
CREATE TABLE dog(
id INT NOT NULL identity(1,1),
dog_id INT NOT NULL,
dog_name VARCHAR (200) NOT NULL,
create_date DATETIME NOT NULL,
update_date DATETIME DEFAULT getutcdate(),
start_date DATETIME DEFAULT getutcdate(),
end_date DATETIME DEFAULT getDate() - 101,
is_active BIT NOT NULL DEFAULT '0',
PRIMARY KEY (id,dog_id)
);
CREATE TABLE dogowner(
dogowner_id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
dog_id INT NOT NULL,
FOREIGN KEY (dog_id) REFERENCES dog(dog_id)
);
As soon as I create the foreign key constraint on the dogowner table it fails with the following error :
There are no primary or candidate keys in the referenced table 'dog' that match the referencing column list in the foreign key 'FK__dogowner__dog_id__00AA174D'.
> UPDATE :
So eventually I dropped the complicated Schema design and opted for history tables on every table
that I want to version.So the dog table will have a dog_history or dog_log table with a post insert/update done on all the history tables.
This is not the way I wanted to do it but it allows me to have foreign key constraints in my database, soft deletes and logging of data. Thanks all for the input. I am following the KISS principle.

The dog_id field needs to be unique field, the following will work:
create table dog(
id int not null identity(1,1),
dog_id int unique not null,
dog_name varchar(200) not null,
create_date datetime not null ,
update_date datetime default getutcdate(),
start_date datetime default getutcdate(),
end_date datetime default getDate() - 101,
is_active bit not null default '0',
primary key(id,dog_id)
);
create table dogowner(
dogowner_id int not null identity(1,1) primary key,
dog_id int not null,
foreign key(dog_id) references dog(dog_id)
);
From the MSFT documentation:
You can use UNIQUE constraints to make sure that no duplicate values
are entered in specific columns that do not participate in a primary
key. Although both a UNIQUE constraint and a PRIMARY KEY constraint
enforce uniqueness, use a UNIQUE constraint instead of a PRIMARY KEY
constraint when you want to enforce the uniqueness of a column, or
combination of columns, that is not the primary key.
Hope this helps

First create unique key on dog_id field in dog table and create unique constraint on it and then you can refer this unique key as foreign key in Dog_owner table.

Related

How to add foreign key that points to one of 2 tables with Postgres?

I want to add a foreign key that is check record_id of activity exists in one of the record or personal_record tables. Is it possible to do with Postgres?
CREATE TABLE record
(
id BIGSERIAL PRIMARY KEY
);
CREATE TABLE personal_record
(
id BIGSERIAL PRIMARY KEY
);
CREATE TABLE activity
(
id BIGSERIAL PRIMARY KEY,
record_id BIGINT NOT NULL,
CONSTRAINT record_fk FOREIGN KEY (record_id) REFERENCES record (id)
);
As stated, this is not possible. One possibility is generated columns and nullable references:
CREATE TABLE activity (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
private_record_id BIGINT,
private_personal_record_id BIGINT,
record_id BIGINT GENERATED ALWAYS AS (COLAESCE(private_record_id, private_personal_record_id)),
CHECK( (private_record_id IS NOT NULL AND private_personal_record_id IS NULL) OR
(private_record_id IS NULL AND private_personal_record_id IS NOT NULL)
),
CONSTRAINT fk_activity_record_id FOREIGN KEY (private_record_id) REFERENCES record(id),
CONSTRAINT fk_activity_record_id FOREIGN KEY (private_personal_record_id) REFERENCES personal_record(id),
);
You might also want to look into inheritance.

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

Insert null value in an association table

I have a problem with something in SQL, let's see an example of database :
CREATE TABLE person( //Employee
pe_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
pe_name VARCHAR(20),
pe_office VARCHAR(20)
);
CREATE TABLE project( //Mission
pr_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
pr_name VARCHAR(20),
pr_status VARCHAR(15)
);
CREATE TABLE techno( //Programming language
te_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
te_name VARCHAR(20)
);
CREATE TABLE job( //developer, manager, ...
jo_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
jo_name VARCHAR(20)
);
I would like to assign persons on projects for a job using technos.
For example, Rob works as a developer and project manager on the projet #13 with AngularJS and HTML.
So I created this table :
CREATE TABLE assignment(
pe_id INT,
pr_id INT,
te_id INT,
jo_id INT,
as_days INT, //Days of work
PRIMARY KEY(pe_id, pr_id, tr_id, jo_id),
CONSTRAINT fk_as_pe_id FOREIGN KEY(pe_id) REFERENCES person(pe_id),
CONSTRAINT fk_as_pr_id FOREIGN KEY(pr_id) REFERENCES project(pr_id),
CONSTRAINT fk_as_te_id FOREIGN KEY(te_id) REFERENCES techno(te_id),
CONSTRAINT fk_as_jo_id FOREIGN KEY(jo_id) REFERENCES job(jo_id)
);
I would like to have the ability to assign a developer with somes technos to a project without knowing who exaclty, like this:
INSERT INTO assignment(pr_id,te_id,jo_id,as_days) VALUES(1,2,3,4); //No person!
We suppose that this values exists in project, techno and job tables.
But it seems that I can not insert this, probably because I do not define person's ID (which is in the primary key).
How can I do this ?
Hope I'm understandable :)
You solve this problem by not having this as a primary key. Primary keys cannot be NULL or, if they're composite primary keys, cannot contain NULL. Make it a unique index instead. Create an autonumber field for the primary key. I think this is better solution in your case
Primary Key:
Can be only one in a table
It never allows null values
Primary Key is unique key identifier and can not be null and must be unique.
Unique Key:
Can be more than one unique key in one table.
Unique key can have null values(only single null is allowed).
It can be a candidate key
Unique key can be null and may not be unique.
Maybe you should do this:
Before insert disable constraint:
ALTER INDEX fk_as_pe_id ON assignment
DISABLE;
After insert enable it:
ALTER INDEX fk_as_pe_id ON assignment
REBUILD;
Another alternate way is, if it is possible to alter table structure, just exclude pe_id from the composite primary key in assignment table

creating table having foreign key that reference another table

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.

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)