Cannot create foreign key on oracle - sql

I'm trying to create a foreign key for a table named: Words_in_group, which holds all the words in a froup that the user creates.
I'm trying to refer the words to a table named: Words, which it's P-key is "Word".
Maybe this has something to do with the table "Words", that uses a composite key?
This is the script for creating the foreign key.
alter table "WORDS_IN_GROUP" add constraint
"WORDS_IN_GROUP_FK1" foreign key ("WORD") references "WORDS" ("WORD")
/
Here are the tables SQL:
CREATE TABLE "WORDS_IN_GROUP" ( "GROUP_CODE" NUMBER(9,0) NOT NULL ENABLE,
"WORD" VARCHAR2(45) NOT NULL ENABLE,
CONSTRAINT "WORDS_IN_GROUP_PK" PRIMARY KEY ("GROUP_CODE") ENABLE ) ;ALTER TABLE "WORDS_IN_GROUP" ADD CONSTRAINT "WORDS_IN_GROUP_FK" FOREIGN KEY ("GROUP_CODE")
REFERENCES "GROUP_OF_WORDS" ("GROUP_CODE") ON DELETE CASCADE ENABLE;CREATE OR REPLACE TRIGGER "BI_WORDS_IN_GROUP" before insert on "WORDS_IN_GROUP" for each row begin if :NEW."GROUP_CODE" is null then
select "GROUP_OF_WORDS_SEQ".nextval into :NEW."GROUP_CODE" from dual; end if; end; /ALTER TRIGGER "BI_WORDS_IN_GROUP" ENABLE;
***///////////
CREATE TABLE "WORDS" ( "WORD" VARCHAR2(45) NOT NULL ENABLE,
"FILE_SN" NUMBER(9,0) NOT NULL ENABLE,
"FILE_NAME" VARCHAR2(16) NOT NULL ENABLE,
"POSITION_NUM" NUMBER(5,0) NOT NULL ENABLE,
"SECTION_NUM" NUMBER(5,0) NOT NULL ENABLE,
"WORD_SECTION_POSITION" NUMBER(4,0) NOT NULL ENABLE,
CONSTRAINT "WORDS_PK" PRIMARY KEY ("WORD", "FILE_SN") ENABLE ) ;
This is the error that I get:
ORA-02270: no matching unique or primary key for this column-list

A foreign key must always point to a unique key (either explicitly defined as such or defined as a primary key). As you noted, word in words is not necessarily unique - only the combination of word, file_sn is. You could either make word itself unique or add a flie_sn column to the word_in_group table and have a composite foreign key, whichever fits your application logic better.

You created composite Primary key for the table WORDS. But you just refer only single column in the table WORDS_IN_GROUP. This is not allowed.
You can refer only those column/group of columns which are unique(either enable Primary key/Unique key). If it is composite then you can create composite FK.

Related

Error implementing relational model in Oracle

MER
I need help creating this MER in Oracle. Specifically in FOTOS table as I have this code:
CREATE TABLE "FOTOS"
(
"ID_FOTO" INT NOT NULL ENABLE,
"ID_USU" INT NOT NULL ENABLE,
"FECHA" DATE NOT NULL ENABLE,
CONSTRAINT "FOTOS_PK"
PRIMARY KEY ("ID_FOTO") ENABLE,
CONSTRAINT "FOTOS_FK"
FOREIGN KEY ("ID_USU") REFERENCES "USUARIOS" ("ID_USU") ENABLE
)
However I keep getting this error:
ORA-02270: no matching unique or primary key for this column-list
ID_USU is one of two primary keys in USUARIOS
USUARIOS TABLE
ID_USU is one of two primary keys in USUARIOS
No. A table can have just one primary key. It can have more than one unique key, but you can only make one of them primary.
What you mistakenly did instead is create a composite primary key. You want the ID to be unique and the name to be unique, but instead you made the combination of ID and name unique, thus allowing duplicate IDs and duplicate names in the table.
What you have:
create table usuarios
(
id_usu number not null,
nomusu varchar2(50) not null,
...
constraint pk_usuarios primary key (id_usu, nomusu)
);
What you want instead:
create table usuarios
(
id_usu number not null,
nomusu varchar2(50) not null,
...
constraint pk_usuarios primary key (id_usu),
constraint uq_usuarios_nomusu unique (nomusu)
);
Foreign keys have to match the primary/unique key they reference column for column. Since the primary key of "USUARIOS" are columns "ID_USU" and "NOMUSU" you need two columns to add FK from "FOTOS" to "USUARIOS", so just add "NOMUSU" column to "FOTOS" and write:
CREATE TABLE "FOTOS"
(
"ID_FOTO" INT NOT NULL ENABLE,
"ID_USU" INT NOT NULL ENABLE,
"NOMUSU" VARCHAR2(50) NOT NULL ENABLE,
"FECHA" DATE NOT NULL ENABLE,
CONSTRAINT "FOTOS_PK"
PRIMARY KEY ("ID_FOTO") ENABLE,
CONSTRAINT "FOTOS_FK"
FOREIGN KEY ("ID_USU","NOMUSU") REFERENCES "USUARIOS" ("ID_USU","NOMUSU") ENABLE);

When creating foreign key constraint, is column name needed?

Let's say we have two tables created by following script:
create table CAR (
CAR_ID number(19,0),
NAME varchar2(255 char),
primary key (CAR_ID)
);
create table CAR_WHEEL (
CAR_WHEEL_ID number(19,0),
CAR_REF_ID number(19,0),
WHEEL_COLOR varchar2(255 char),
primary key (CAR_WHEEL_ID)
);
Now I want to add a constraint, so I can create this statement:
alter table CAR_WHEEL
add constraint FK_CAR
foreign key (CAR_REF_ID)
references CAR (CAR_ID);
But I saw also scripts, where there would be references CAR; in last line, instead of references CAR (CAR_ID);
What is the difference and when should I add column names? Would there be any change if CAR table had primary key with more columns, e.g. primary key (CAR_ID, NAME)?
If the answer depends on SQL dialect, I am particulary interested in Oracle.
Foreign key without specific column will create it on the primary key, so with different primary key you need to add all the columns from it. I would not recomend using the implicit foreign key creation.

ALTER TABLE query for foreign key constraint does not work

I'm a beginner and creating my own simple blockchain app for fun. The blockchain itself is fully functional. Now I'm trying to implement a database to store the data of the blockchain (right now I'm writing it to a .txt file). So I want to create the following database schema in sqlite:
CREATE TABLE `Blockchain`
(
`previous_hash` string NOT NULL ,
`timestamp` float NOT NULL ,
`signature_of_transactions` string NOT NULL ,
`index` bigint NOT NULL ,
PRIMARY KEY (`previous_hash`)
);
CREATE TABLE `Wallet`
(
`public_key` string NOT NULL ,
PRIMARY KEY (`public_key`)
);
CREATE TABLE `Transactions`
(
`signature` string NOT NULL ,
`sender` string NOT NULL ,
`recipient` string NOT NULL ,
`amount` float NOT NULL ,
PRIMARY KEY (`signature`)
);
CREATE TABLE `Peer_nodes`
(
`id` string NOT NULL ,
`public_key` string NOT NULL ,
PRIMARY KEY (`id`)
);
ALTER TABLE `Wallet`
ADD CONSTRAINT `fk_Wallet_public_key`
FOREIGN KEY(`public_key`) REFERENCES `Peer_nodes` (`public_key`);
ALTER TABLE `Transactions`
ADD CONSTRAINT `fk_Transactions_signature`
FOREIGN KEY(`signature`) REFERENCES `Blockchain` (`signature_of_transactions`);
ALTER TABLE `Transactions`
ADD CONSTRAINT `fk_Transactions_sender`
FOREIGN KEY(`sender`) REFERENCES `Wallet` (`public_key`);
ALTER TABLE `Transactions`
ADD CONSTRAINT `fk_Transactions_recipient`
FOREIGN KEY(`recipient`) REFERENCES `Wallet` (`public_key`);
Creating the tables with the columns etc. works fine with the script above. The ALTER TABLE queries do not work somehow. This is the following error message I receive:
ALTER TABLE Wallet ADD CONSTRAINT fk_Wallet_public_key FOREIGN KEY(public_key) REFERENCES Peer_nodes (public_key)
ERROR:
As you can see, it has no real error message. I haven't found a possible error in the queries themselves after searching a lot on the internet. What am I doing wrong? I try to do this via phpLitedmin, so maybe the problem is there?
SQLite's ALTER TABLE does not support adding constraints.
You have to include the constraints into the CREATE TABLE statements.
And as already noted by Gordon, foreign key constraints require the target to be a primary or candidate key.
Your foreign key reference is to the wrong column. It should be to the primary key, although it can be to a unique key.
As explained in the documentation:
Usually, the parent key of a foreign key constraint is the primary key
of the parent table. If they are not the primary key, then the parent
key columns must be collectively subject to a UNIQUE constraint or
have a UNIQUE index. If the parent key columns have a UNIQUE index,
then that index must use the collation sequences that are specified in
the CREATE TABLE statement for the parent table.
You should fix the table definition and add the foreign key to use the primary key.

There are no PK in the referenced table. Why?

I have the following T-SQL to create 3 SQL tables:
create table dbo.Posts
(
Id int identity not null
constraint PK_Posts_Id primary key clustered (Id),
Active bit not null
constraint DF_Posts_Active default (0)
);
create table dbo.PostsLocalized
(
Id int not null,
Culture int not null
constraint CK_PostsLocalized_Culture check ([Culture] in ('1', '2', '3')),
[Text] nvarchar (200) not null,
constraint PK_PostsLocalized_Id_Culture primary key clustered (Id, Culture)
);
create table dbo.Tags
(
Id int identity not null
constraint PK_Tags_Id primary key clustered (Id),
Name nvarchar not null
);
create table dbo.PostsLocalized_Tags
(
PostLocalizedId int not null,
TagId int not null,
constraint PK_PostsLocalized_Tags_Post_PostLocalizedId_TagId primary key clustered (PostLocalizedId, TagId)
);
Then I have added the following constraints:
alter table dbo.PostsLocalized
add constraint FK_PostsLocalized_Id foreign key (Id) references dbo.Posts(Id) on delete cascade on update cascade;
alter table dbo.PostsLocalized_Tags
add constraint FK_PostsLocalized_Tags_PostLocalizedId foreign key (PostLocalizedId) references PostsLocalized(Id) on delete cascade on update cascade,
constraint FK_PostsLocalized_Tags_TagId foreign key (TagId) references Tags(Id) on delete cascade on update cascade;
But I get the following error:
There are no primary or candidate keys in the referenced table 'PostsLocalized' that match the referencing column list in the foreign key 'FK_PostsLocalized_Tags_PostLocalizedId'.
How can I solve this?
Thank You,
Miguel
SQL Server mandates that foreign key references be to a primary key or unique key. The foreign key reference has to be to all the columns that constitute the primary/unique key. The documentation says:
In a foreign key reference, a link is created between two tables when
the column or columns that hold the primary key value for one table
are referenced by the column or columns in another table. This column
becomes a foreign key in the second table.
A FOREIGN KEY constraint does not have to be linked only to a PRIMARY
KEY constraint in another table; it can also be defined to reference
the columns of a UNIQUE constraint in another table. A FOREIGN KEY
constraint can contain null values; however, if any column of a
composite FOREIGN KEY constraint contains null values, verification of
all values that make up the FOREIGN KEY constraint is skipped. To make
sure that all values of a composite FOREIGN KEY constraint are
verified, specify NOT NULL on all the participating columns.
The primary key in PostsLocalized contains the culture column, so you need to add it into the foreign key reference.
Your PK on PostsLocalized table is complex consisting of two columns - id and culture and you are trying to create FK on only one of those columns which is not possible.
You'll have to either add Culture column on PostsLocalized_Tags and use them both in foreign key or remove Culture from your PK on PostLocalized

Invalid FK and PK reference

Unable to create table as oracle shows ' no matching unique or primary key for this column-list' when I did label the primary key reference for the required table.
First table created successfully:
CREATE TABLE TEST
(
TESTno VARCHAR2(6) NOT NULL,
ExamNo VARCHAR2(6) NOT NULL,
TEST_Date DATE NOT NULL,
ACTUAL DATE,
PREDICTED Date,
CONSTRAINT TESTPKs PRIMARY KEY (TEST_Date, TESTno, ExamNo),
CONSTRAINT TTESTNO_Fk FOREIGN KEY (TESTno) REFERENCES TESTPAPER (Flightno)
CONSTRAINT TEXAMNo_FK FOREIGN KEY (ExamNo) REFERENCES Exam (ExamNo)
);
Here's the table i want to create and gives me error:
CREATE TABLE Assignment
(
TEST_Date DATE NOT NULL,
ExamNo VARCHAR2(6) NOT NULL,
TestNo VARCHAR2(6) NOT NULL,
Type VARCHAR2(20),
Hours_Spent Decimal(4,2),
CONSTRAINT ASSIGNPKS PRIMARY KEY (TEST_Date, TestNo , ExamNo),
CONSTRAINT ASSIGNTESTDATE_FK FOREIGN KEY (TEST_Date) REFERENCES TEST(TEST_Date) ON
DELETE CASCADE,
CONSTRAINT ASSIGNTESTNO_FK FOREIGN KEY (TESTno) REFERENCES TESTPAPER (Flightno)
CONSTRAINT TEXAMNo_FK FOREIGN KEY (ExamNo) REFERENCES Exam (ExamNo)
);
May i know where's the issue that it keeps giving me no matching unique primary keys? I already tried to recreate and labelled the 'test_Date' as my primary key. But oracle can't seems to find.
Thanks
The PK you refer to is PRIMARY KEY (TEST_Date, TESTno, ExamNo) — hence the foreign key should be FOREIGN KEY (TEST_Date, TESTno, ExamNo) as well. The error you're getting is due to your attempt to refer to a part of TEST's PK.
See also http://download.oracle.com/docs/cd/B10500_01/server.920/a96524/c22integ.htm
Check the tables you are referencing in your foreign keys. Those columns must be the primary key or otherwise unique on the foreign table.