I have a table:
CREATE TABLE MY_TABLE (
MY_ID NUMBER NOT NULL,
COLUMN_1 NUMBER,
COLUMN_2 NUMBER
);
ALTER TABLE MY_TABLE ADD CONSTRAINT PK_FOO PRIMARY KEY (MY_ID);
at a later point, when executing the following sql, I get an error:
ALTER TABLE MY_TABLE DROP PRIMARY KEY DROP INDEX;
ALTER TABLE MY_TABLE ADD CONSTRAINT PK_FOO PRIMARY KEY (MY_ID)
ORA-02437: cannot validate PK_FOO - primary key violated
My table only contains 3 entries all with a different primary key which is also not null.
Anyone has an idea what this could be?
Thanks,
Peter
My table only contains 3 entries all with a different primary key which is also not null.
You must forgive a certain amount of scepticism on our part. Because that error definitely indicates a duplicate value.
What you need to do is use the exceptions clause. This will show you the ROWIDs of the records which are violating your constraint. You may need to create the target table: by default the script creates a table called EXCEPTIONS:
SQL> ALTER TABLE MY_TABLE ADD CONSTRAINT PK_FOO PRIMARY KEY (MY_ID);
ALTER TABLE MY_TABLE ADD CONSTRAINT PK_FOO PRIMARY KEY (MY_ID)
*
ERROR at line 1:
ORA-02437: cannot validate (APC.PK_FOO) - primary key violated
SQL> #%ORACLE_HOME%\rdbms\admin\utlexpt1.sql
Table created.
SQL> ALTER TABLE MY_TABLE ADD CONSTRAINT PK_FOO PRIMARY KEY (MY_ID)
2 exceptions into exceptions
3 /
ALTER TABLE MY_TABLE ADD CONSTRAINT PK_FOO PRIMARY KEY (MY_ID)
*
ERROR at line 1:
ORA-02437: cannot validate (APC.PK_FOO) - primary key violated
SQL> select * from exceptions
2 /
ROW_ID OWNER TABLE_NAME CONSTRAINT
------ ----- ---------- ----------
AABQXcAAEAAAXUPAAD APC MY_TABLE PK_FOO
AABQXcAAEAAAXUPAAB APC MY_TABLE PK_FOO
SQL>
Edit
You need to figure out what is different between your install code and the simplification you posted here. The chances are you have one or more INSERT statements which are accidentally executed more than once while the constraint is not in force. Adding the EXCEPTIONS INTO clause to your code might help you track it down.
from here
Cause: You tried to tried to enable a
primary key constraint, but the
columns in the primary key either
contained NULL values or duplicates..
The maim reason of violation of primary ki is the atrrbute you making is nullable or you have some dupliactes in table for that id or attribute
create table client_master
(
client_no varchar2(6),
client_name varchar2(20),
city varchar2(25),
state varchar2(15),
pin number(6),
balance_due number(10,2));
for e.g,
after inserting values
0008 Mukul NYCT NYC 199560 2500
0006 Rukmini bombay maharastra 100001 0
0007 Krishna mathura up 900050 100000
0008 Mukul NYCT NYC 199560 2500
or your id is nullable
so just MODIFY THE ATTRIBUTE is and set to NOT NULL
also remove duplicates if any
DELETE client_master
WHERE rowid NOT IN
(SELECT MAX(rowid)
FROM client_master
GROUP BY client_no,client_name,city,state,pin,balance_due);
then you we will be able to add primary key to client _no
Are 2 primary keys identical?
This error is usually thrown when you try to create/enable a primary key on a table
I'm upvoting APC's answer, but since you seem to have some problems implementing it, could you just post the results of this query:
select my_id, count(*) from my_table group by my_id having count(*) >1
This will give us (and you) some idea of the problematic keys.
Related
I Not able to add foreign key to tbl1 referencing tbl2 (Desc), here are the two tables :
please notice Tbl1 includes all values,tbl2 Has more values that doesn't necessarily exists in tbl1
Error(Msg 1776): There are no primary or candidate keys in the referenced table 'tbl2' that match the referencing column list in the foreign key 'fk_desc'.
tbl1:
alter table tbl1 add constraint pk_desc primary key (desc)
The Error:**alter table tbl1 add constraint fk_desc foreign key (desc)
references tbl2(desc)**
Desc
Astrogator
Geologist
Technician
tbl2:
alter table tbl2 add constraint pk_canid_desc primary
key(id,desc)
ID
Desc
1001
Astrogator
1001
Geologist
1001
Technician
2003
Biochemist
thank you for the help,
you cant make Desc that at table tbl2 as a FK while it contains values not exists at the table tbl1
Adding a foreign key is different depending on the flavor of SQL your using. For sql server you would bring up the parent db in SSMS using table design. Select Foreign key relationships and add a new relationship. From there select other table and column which has foreign key. Keep in mind that there needs to exist a foreign key for each Primary record or you will get an error.
As I can understand documentation the following definitions are equivalent:
create table foo (
id serial primary key,
code integer,
label text,
constraint foo_uq unique (code, label));
create table foo (
id serial primary key,
code integer,
label text);
create unique index foo_idx on foo using btree (code, label);
However, a note in the manual for Postgres 9.4 says:
The preferred way to add a unique constraint to a table is ALTER TABLE ... ADD CONSTRAINT. The use of indexes to enforce unique constraints
could be considered an implementation detail that should not be
accessed directly.
(Edit: this note was removed from the manual with Postgres 9.5.)
Is it only a matter of good style? What are practical consequences of choice one of these variants (e.g. in performance)?
I had some doubts about this basic but important issue, so I decided to learn by example.
Let's create test table master with two columns, con_id with unique constraint and ind_id indexed by unique index.
create table master (
con_id integer unique,
ind_id integer
);
create unique index master_unique_idx on master (ind_id);
Table "public.master"
Column | Type | Modifiers
--------+---------+-----------
con_id | integer |
ind_id | integer |
Indexes:
"master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
"master_unique_idx" UNIQUE, btree (ind_id)
In table description (\d in psql) you can tell unique constraint from unique index.
Uniqueness
Let's check uniqueness, just in case.
test=# insert into master values (0, 0);
INSERT 0 1
test=# insert into master values (0, 1);
ERROR: duplicate key value violates unique constraint "master_con_id_key"
DETAIL: Key (con_id)=(0) already exists.
test=# insert into master values (1, 0);
ERROR: duplicate key value violates unique constraint "master_unique_idx"
DETAIL: Key (ind_id)=(0) already exists.
test=#
It works as expected!
Foreign keys
Now we'll define detail table with two foreign keys referencing to our two columns in master.
create table detail (
con_id integer,
ind_id integer,
constraint detail_fk1 foreign key (con_id) references master(con_id),
constraint detail_fk2 foreign key (ind_id) references master(ind_id)
);
Table "public.detail"
Column | Type | Modifiers
--------+---------+-----------
con_id | integer |
ind_id | integer |
Foreign-key constraints:
"detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
"detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)
Well, no errors. Let's make sure it works.
test=# insert into detail values (0, 0);
INSERT 0 1
test=# insert into detail values (1, 0);
ERROR: insert or update on table "detail" violates foreign key constraint "detail_fk1"
DETAIL: Key (con_id)=(1) is not present in table "master".
test=# insert into detail values (0, 1);
ERROR: insert or update on table "detail" violates foreign key constraint "detail_fk2"
DETAIL: Key (ind_id)=(1) is not present in table "master".
test=#
Both columns can be referenced in foreign keys.
Constraint using index
You can add table constraint using existing unique index.
alter table master add constraint master_ind_id_key unique using index master_unique_idx;
Table "public.master"
Column | Type | Modifiers
--------+---------+-----------
con_id | integer |
ind_id | integer |
Indexes:
"master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
"master_ind_id_key" UNIQUE CONSTRAINT, btree (ind_id)
Referenced by:
TABLE "detail" CONSTRAINT "detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
TABLE "detail" CONSTRAINT "detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)
Now there is no difference between column constraints description.
Partial indexes
In table constraint declaration you cannot create partial indexes.
It comes directly from the definition of create table ....
In unique index declaration you can set WHERE clause to create partial index.
You can also create index on expression (not only on column) and define some other parameters (collation, sort order, NULLs placement).
You cannot add table constraint using partial index.
alter table master add column part_id integer;
create unique index master_partial_idx on master (part_id) where part_id is not null;
alter table master add constraint master_part_id_key unique using index master_partial_idx;
ERROR: "master_partial_idx" is a partial index
LINE 1: alter table master add constraint master_part_id_key unique ...
^
DETAIL: Cannot create a primary key or unique constraint using such an index.
One more advantage of using UNIQUE INDEX vs. UNIQUE CONSTRAINT is that you can easily DROP/CREATE an index CONCURRENTLY, whereas with a constraint you can't.
Uniqueness is a constraint. It happens to be implemented via the creation
of a unique index since an index is quickly able to search all existing
values in order to determine if a given value already exists.
Conceptually the index is an implementation detail and uniqueness should be
associated only with constraints.
The full text
So speed performance should be same
Since various people have provided advantages of unique indexes over unique constraints, here's a drawback: a unique constraint can be deferred (only checked at the end of the transaction), a unique index can not be.
A very minor thing that can be done with constraints only and not with indexes is using the ON CONFLICT ON CONSTRAINT clause (see also this question).
This doesn't work:
CREATE TABLE T (a INT PRIMARY KEY, b INT, c INT);
CREATE UNIQUE INDEX u ON t(b);
INSERT INTO T (a, b, c)
VALUES (1, 2, 3)
ON CONFLICT ON CONSTRAINT u
DO UPDATE SET c = 4
RETURNING *;
It produces:
[42704]: ERROR: constraint "u" for table "t" does not exist
Turn the index into a constraint:
DROP INDEX u;
ALTER TABLE t ADD CONSTRAINT u UNIQUE (b);
And the INSERT statement now works.
Another thing I've encountered is that you can use sql expressions in unique indexes but not in constraints.
So, this does not work:
CREATE TABLE users (
name text,
UNIQUE (lower(name))
);
but following works.
CREATE TABLE users (
name text
);
CREATE UNIQUE INDEX uq_name on users (lower(name));
There is a difference in locking.
Adding an index does not block read access to the table.
Adding a constraint does put a table lock (so all selects are blocked) since it is added via ALTER TABLE.
I read this in the doc:
ADD table_constraint [ NOT VALID ]
This form adds a new constraint to a table using the same syntax as CREATE TABLE, plus the option NOT VALID, which is currently only allowed for foreign key constraints. If the constraint is marked NOT VALID, the potentially-lengthy initial check to verify that all rows in the table satisfy the constraint is skipped. The constraint will still be enforced against subsequent inserts or updates (that is, they'll fail unless there is a matching row in the referenced table). But the database will not assume that the constraint holds for all rows in the table, until it is validated by using the VALIDATE CONSTRAINT option.
So I think it is what you call "partial uniqueness" by adding a constraint.
And, about how to ensure the uniqueness:
Adding a unique constraint will automatically create a unique B-tree index on the column or group of columns listed in the constraint. A uniqueness restriction covering only some rows cannot be written as a unique constraint, but it is possible to enforce such a restriction by creating a unique partial index.
Note: The preferred way to add a unique constraint to a table is ALTER TABLE … ADD CONSTRAINT. The use of indexes to enforce unique constraints could be considered an implementation detail that should not be accessed directly. One should, however, be aware that there’s no need to manually create indexes on unique columns; doing so would just duplicate the automatically-created index.
So we should add constraint, which creates an index, to ensure uniqueness.
How I see this problem?
A "constraint" aims to gramatically ensure that this column should be unique, it establishes a law, a rule; while "index" is semantical, about "how to implement, how to achieve the uniqueness, what does unique means when it comes to implementation". So, the way Postgresql implements it, is very logical: first, you declare that a column should be unique, then, Postgresql adds the implementation of adding an unique index for you.
SELECT a.phone_number,count(*) FROM public.users a
Group BY phone_number Having count(*)>1;
SELECT a.phone_number,count(*) FROM public.retailers a
Group BY phone_number Having count(*)>1;
select a.phone_number from users a inner join users b
on a.id <> b.id and a.phone_number = b.phone_number order by a.id;
select a.phone_number from retailers a inner join retailers b
on a.id <> b.id and a.phone_number = b.phone_number order by a.id
DELETE FROM
users a
USING users b
WHERE
a.id > b.id
AND a.phone_number = b.phone_number;
DELETE FROM
retailers a
USING retailers b
WHERE
a.id > b.id
AND a.phone_number = b.phone_number;
CREATE UNIQUE INDEX CONCURRENTLY users_phone_number
ON users (phone_number);
To Verify:
insert into users(name,phone_number,created_at,updated_at) select name,phone_number,created_at,updated_at from users
I have a table in SQL like;
table Court
CourtID numeric(4) primary key
Name varchar(40) not null
Place varchar(40) not null
Type varchar(3) not null
TypeID numeric(4) references Court(CourtID) default null
I could not find info about what that reference statement stands for and how does it relate TypeID with CourtID?
It is simply shorthand syntax for a FOREIGN KEY.
All sorts of Google results are found with "sql references keyword"
Or simply trying it can often help more than a Google search (the old fashioned way).
Your example shows a self-referential foreign key. It is a common pattern seen to model relationships like PARENT or SPOUSE, where all records belong in the same base table, but may reference each other.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> create table court(
2 courtid integer primary key,
3 typeid integer references court(courtid)
4 );
Table created.
SQL> insert into court values(1,0);
insert into court values(1,0)
*
ERROR at line 1:
ORA-02291: integrity constraint (MSMITH.SYS_C0016710) violated - parent key not
found
SQL> insert into court values(1,1);
1 row created.
The above syntax will generate a "random" name for the constraint. A better syntax is to explicitly name the constraint. Notice what happens if I recreate it with additional FOREIGN KEY syntax.
SQL> create table court(
2 courtid integer primary key,
3 typeid integer,
4 constraint fk_typeid foreign key (typeid) references court(courtid)
5 );
Table created.
SQL> insert into court values(1,0);
insert into court values(1,0)
*
ERROR at line 1:
ORA-02291: integrity constraint (MSMITH.FK_TYPEID) violated - parent key not
found
The key is now named FK_TYPEID rather than SYS_C0016710
As I can understand documentation the following definitions are equivalent:
create table foo (
id serial primary key,
code integer,
label text,
constraint foo_uq unique (code, label));
create table foo (
id serial primary key,
code integer,
label text);
create unique index foo_idx on foo using btree (code, label);
However, a note in the manual for Postgres 9.4 says:
The preferred way to add a unique constraint to a table is ALTER TABLE ... ADD CONSTRAINT. The use of indexes to enforce unique constraints
could be considered an implementation detail that should not be
accessed directly.
(Edit: this note was removed from the manual with Postgres 9.5.)
Is it only a matter of good style? What are practical consequences of choice one of these variants (e.g. in performance)?
I had some doubts about this basic but important issue, so I decided to learn by example.
Let's create test table master with two columns, con_id with unique constraint and ind_id indexed by unique index.
create table master (
con_id integer unique,
ind_id integer
);
create unique index master_unique_idx on master (ind_id);
Table "public.master"
Column | Type | Modifiers
--------+---------+-----------
con_id | integer |
ind_id | integer |
Indexes:
"master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
"master_unique_idx" UNIQUE, btree (ind_id)
In table description (\d in psql) you can tell unique constraint from unique index.
Uniqueness
Let's check uniqueness, just in case.
test=# insert into master values (0, 0);
INSERT 0 1
test=# insert into master values (0, 1);
ERROR: duplicate key value violates unique constraint "master_con_id_key"
DETAIL: Key (con_id)=(0) already exists.
test=# insert into master values (1, 0);
ERROR: duplicate key value violates unique constraint "master_unique_idx"
DETAIL: Key (ind_id)=(0) already exists.
test=#
It works as expected!
Foreign keys
Now we'll define detail table with two foreign keys referencing to our two columns in master.
create table detail (
con_id integer,
ind_id integer,
constraint detail_fk1 foreign key (con_id) references master(con_id),
constraint detail_fk2 foreign key (ind_id) references master(ind_id)
);
Table "public.detail"
Column | Type | Modifiers
--------+---------+-----------
con_id | integer |
ind_id | integer |
Foreign-key constraints:
"detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
"detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)
Well, no errors. Let's make sure it works.
test=# insert into detail values (0, 0);
INSERT 0 1
test=# insert into detail values (1, 0);
ERROR: insert or update on table "detail" violates foreign key constraint "detail_fk1"
DETAIL: Key (con_id)=(1) is not present in table "master".
test=# insert into detail values (0, 1);
ERROR: insert or update on table "detail" violates foreign key constraint "detail_fk2"
DETAIL: Key (ind_id)=(1) is not present in table "master".
test=#
Both columns can be referenced in foreign keys.
Constraint using index
You can add table constraint using existing unique index.
alter table master add constraint master_ind_id_key unique using index master_unique_idx;
Table "public.master"
Column | Type | Modifiers
--------+---------+-----------
con_id | integer |
ind_id | integer |
Indexes:
"master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
"master_ind_id_key" UNIQUE CONSTRAINT, btree (ind_id)
Referenced by:
TABLE "detail" CONSTRAINT "detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
TABLE "detail" CONSTRAINT "detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)
Now there is no difference between column constraints description.
Partial indexes
In table constraint declaration you cannot create partial indexes.
It comes directly from the definition of create table ....
In unique index declaration you can set WHERE clause to create partial index.
You can also create index on expression (not only on column) and define some other parameters (collation, sort order, NULLs placement).
You cannot add table constraint using partial index.
alter table master add column part_id integer;
create unique index master_partial_idx on master (part_id) where part_id is not null;
alter table master add constraint master_part_id_key unique using index master_partial_idx;
ERROR: "master_partial_idx" is a partial index
LINE 1: alter table master add constraint master_part_id_key unique ...
^
DETAIL: Cannot create a primary key or unique constraint using such an index.
One more advantage of using UNIQUE INDEX vs. UNIQUE CONSTRAINT is that you can easily DROP/CREATE an index CONCURRENTLY, whereas with a constraint you can't.
Uniqueness is a constraint. It happens to be implemented via the creation
of a unique index since an index is quickly able to search all existing
values in order to determine if a given value already exists.
Conceptually the index is an implementation detail and uniqueness should be
associated only with constraints.
The full text
So speed performance should be same
Since various people have provided advantages of unique indexes over unique constraints, here's a drawback: a unique constraint can be deferred (only checked at the end of the transaction), a unique index can not be.
A very minor thing that can be done with constraints only and not with indexes is using the ON CONFLICT ON CONSTRAINT clause (see also this question).
This doesn't work:
CREATE TABLE T (a INT PRIMARY KEY, b INT, c INT);
CREATE UNIQUE INDEX u ON t(b);
INSERT INTO T (a, b, c)
VALUES (1, 2, 3)
ON CONFLICT ON CONSTRAINT u
DO UPDATE SET c = 4
RETURNING *;
It produces:
[42704]: ERROR: constraint "u" for table "t" does not exist
Turn the index into a constraint:
DROP INDEX u;
ALTER TABLE t ADD CONSTRAINT u UNIQUE (b);
And the INSERT statement now works.
Another thing I've encountered is that you can use sql expressions in unique indexes but not in constraints.
So, this does not work:
CREATE TABLE users (
name text,
UNIQUE (lower(name))
);
but following works.
CREATE TABLE users (
name text
);
CREATE UNIQUE INDEX uq_name on users (lower(name));
There is a difference in locking.
Adding an index does not block read access to the table.
Adding a constraint does put a table lock (so all selects are blocked) since it is added via ALTER TABLE.
I read this in the doc:
ADD table_constraint [ NOT VALID ]
This form adds a new constraint to a table using the same syntax as CREATE TABLE, plus the option NOT VALID, which is currently only allowed for foreign key constraints. If the constraint is marked NOT VALID, the potentially-lengthy initial check to verify that all rows in the table satisfy the constraint is skipped. The constraint will still be enforced against subsequent inserts or updates (that is, they'll fail unless there is a matching row in the referenced table). But the database will not assume that the constraint holds for all rows in the table, until it is validated by using the VALIDATE CONSTRAINT option.
So I think it is what you call "partial uniqueness" by adding a constraint.
And, about how to ensure the uniqueness:
Adding a unique constraint will automatically create a unique B-tree index on the column or group of columns listed in the constraint. A uniqueness restriction covering only some rows cannot be written as a unique constraint, but it is possible to enforce such a restriction by creating a unique partial index.
Note: The preferred way to add a unique constraint to a table is ALTER TABLE … ADD CONSTRAINT. The use of indexes to enforce unique constraints could be considered an implementation detail that should not be accessed directly. One should, however, be aware that there’s no need to manually create indexes on unique columns; doing so would just duplicate the automatically-created index.
So we should add constraint, which creates an index, to ensure uniqueness.
How I see this problem?
A "constraint" aims to gramatically ensure that this column should be unique, it establishes a law, a rule; while "index" is semantical, about "how to implement, how to achieve the uniqueness, what does unique means when it comes to implementation". So, the way Postgresql implements it, is very logical: first, you declare that a column should be unique, then, Postgresql adds the implementation of adding an unique index for you.
SELECT a.phone_number,count(*) FROM public.users a
Group BY phone_number Having count(*)>1;
SELECT a.phone_number,count(*) FROM public.retailers a
Group BY phone_number Having count(*)>1;
select a.phone_number from users a inner join users b
on a.id <> b.id and a.phone_number = b.phone_number order by a.id;
select a.phone_number from retailers a inner join retailers b
on a.id <> b.id and a.phone_number = b.phone_number order by a.id
DELETE FROM
users a
USING users b
WHERE
a.id > b.id
AND a.phone_number = b.phone_number;
DELETE FROM
retailers a
USING retailers b
WHERE
a.id > b.id
AND a.phone_number = b.phone_number;
CREATE UNIQUE INDEX CONCURRENTLY users_phone_number
ON users (phone_number);
To Verify:
insert into users(name,phone_number,created_at,updated_at) select name,phone_number,created_at,updated_at from users
Why does add a foreign key to the tblDomare table result in this error?
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__tblDomare__PersN__5F7E2DAC". The conflict occurred in database "almu0004", table "dbo.tblBana", column 'BanNR'.
Code
CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
PRIMARY KEY (PersNR));
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (7606091347,'Josefin','Backman',4);
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (8508284163,'Johanna','Backman',1);
CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL,
PRIMARY KEY (BanNR));
INSERT INTO tblBana (BanNR)
Values (1);
INSERT INTO tblBana (BanNR)
Values (2);
INSERT INTO tblBana (BanNR)
Values (3);
ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
It occurred because you tried to create a foreign key from tblDomare.PersNR to tblBana.BanNR but/and the values in tblDomare.PersNR didn't match with any of the values in tblBana.BanNR. You cannot create a relation which violates referential integrity.
This query was very useful for me. It shows all values that don't have any matches
select FK_column from FK_table
WHERE FK_column NOT IN
(SELECT PK_column from PK_table)
Try this solution:
There is a data item in your table whose associated value doesn't exist in the table you want to use it as a primary key table.
Make your table empty or add the associated value to the second table.
It is possible to create the foreign key using ALTER TABLE tablename WITH NOCHECK ..., which will allow data that violates the foreign key.
"ALTER TABLE tablename WITH NOCHECK ..." option to add the FK -- This solution worked for me.
Remove all existing data from your tables and then make a relation between the tables.
Before You add Foreign key to the table, do the following
Make sure the table must empty or The column data should match.
Make sure it is not null.
If the table contains do not go to design and change, do it manually.
alter table Table 1 add foreign key (Column Name) references Table 2 (Column Name)
alter table Table 1 alter column Column Name attribute not null
I guess, a column value in a foreign key table should match with the column value of the primary key table. If we are trying to create a foreign key constraint between two tables where the value inside one column(going to be the foreign key) is different from the column value of the primary key table then it will throw the message.
So it is always recommended to insert only those values in the Foreign key column which are present in the Primary key table column.
For ex. If the Primary table column has values 1, 2, 3 and in Foreign key column the values inserted are different, then the query would not be executed as it expects the values to be between 1 & 3.
In very simple words your table already has data present in it and the table you are trying to create relationship with does have that Primary key set for the values that are already present.
Either delete all the values of the existing table.
Add all the values of foreign key reference in the new table.
Try DELETE the current datas from tblDomare.PersNR . Because the values in tblDomare.PersNR didn't match with any of the values in tblBana.BanNR.
When you define a Foreign Key in table B referencing the Primary Key of table A it means that when a value is in B, it must be in A. This is to prevent unconsistent modifications to the tables.
In your example, your tables contain:
tblDomare with PRIMARY KEY (PersNR):
PersNR |fNamn |eNamn |Erfarenhet
-----------|----------|-----------|----------
6811034679 |'Bengt' |'Carlberg' |10
7606091347 |'Josefin' |'Backman' |4
8508284163 |'Johanna' |'Backman' |1
---------------------------------------------
tblBana:
BanNR
-----
1
2
3
-----
This statement:
ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
says that any line in tblDomare with key PersNR must have a correspondence in table tblBana on key BanNR. Your error is because you have lines inserted in tblDomare with no correspondence in tblBana.
2 solutions to fix your issue:
either add lines in tblBana with BanNR in (6811034679, 7606091347, 8508284163)
or remove all lines in tblDomare that have no correspondence in tblBana (but your table would be empty)
General advice: you should have the Foreign Key constraint before populating the tables. Foreign keys are here to prevent the user of the table from filling the tables with inconsistencies.
i had this error too
as Smutje reffered make sure that you have not a value in foreign key column of your base foreign key table that is not in your reference table i.e(every value in your base foreign key table(value of a column that is foreign key) must also be in your reference table column)
its good to empty your base foreign key table first then set foreign keys
the data you have entered a table(tbldomare) aren't match a data you have assigned primary key table. write between tbldomare and add this word (with nocheck) then execute your code.
for example you entered a table tbldomar this data
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);
and you assigned a foreign key table to accept only 1,2,3.
you have two solutions one is delete the data you have entered a table then execute the code. another is write this word (with nocheck) put it between your table name and add
like this
ALTER TABLE tblDomare with nocheck
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
Smutje is correct and Chad HedgeCock offered a great layman's example.
Id like to build on Chad's example by offering a way to find/delete those records.
We will use Customer as the Parent and Order as the child. CustomerId is the common field.
select * from Order Child
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null
if you are reading this thread... you will get results. These are orphaned children. select * from Order Child
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null Note the row count in the bottom right.
Go verify w/ whomever you need to that you are going to delete these rows!
begin tran
delete Order
from Order Child
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null
Run the first bit.
Check that row count = what you expected
commit the tran
commit tran
Be careful. Someone's sloppy programming got you into this mess. Make sure you understand the why before you delete the orphans. Maybe the parent needs to be restored.
From our end, this is the scenario:
We have an existing table in the database with records.
Then I introduces a NOT nullable foreign key
After executing the update i got this error.
How did i solve you ask?
SOLUTION: I just removed all the records of the table, then tried to update the database and it was successful.
This happens to me, since I am designing my database, I notice that I change my seed on my main table, now the relational table has no foreign key on the main table.
So I need to truncate both tables, and it now works!
You should see if your tables has any data on the rows. If "yes" then you should truncate the table(s) or else you can make them to have the same number of data at tblDomare.PersNR to tblBana.BanNR and vise-verse.
In my scenario, using EF, upon trying to create this new Foreign Key on existing data, I was wrongly trying to populate the data (make the links) AFTER creating the foreign key.
The fix is to populate your data before creating the foreign key since it checks all of them to see if the links are indeed valid. So it couldn't possibly work if you haven't populated it yet.
I encounter some issue in my project.
In child table, there isn't any record Id equals 1 and 11
I inserted DEAL_ITEM_THIRD_PARTY_PO table which Id equals 1 and 11 then I can create FK
Please first delete data from that table and then run the migration again. You will get success
I had the same problem.
My issue was having nullable: true in column (migration file):
AddColumn("dbo.table", "column", c => c.Int(nullable: true));
Possible Solutions:
Change nullable 'false' to 'true'. (Not Recommended)
Change property type from int to int? (Recommended)
And if required, change this later after adding column > then missing field data in previous records
If you've changed an existing property from nullable to non-nullable:
3) Fill the column data in database records
A foreign key constraint in a child table must have a parent table with a primary key. The primary key must be unique. The foreign key value must match a value in the patent table primary key
When you alter table column from nullable to not nullable column where this column is foreign key, you must :
Firstly, initialize this column with value (because it is foreign
key not nullable).
After that you can alter your table column normally.
Please try below query:
CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL PRIMARY KEY,
);
CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL PRIMARY KEY,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
FK_tblBana_Id VARCHAR (15) references tblBana (BanNR)
);
INSERT INTO tblBana (BanNR)
Values (3);
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet,FK_tblBana_Id)
Values (8508284173,'Johanna','Backman',1,3);
or you can use this
SELECT fk_id FROM dbo.tableA
Except
SELECT fk_id From dbo.tableB
and just FYI, in case you do all of your data reference checks and find no bad data...apparently it is not possible to create a foreign key constraint between two tables and fields where those fields are the primary key in both tables! Do not ask me how I know this.