When creating foreign key constraint, is column name needed? - sql

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.

Related

Create table with foreign key to an other table created below in sql file

My problem is that i have two tables with each table having a foreign key to the other table.
Each time , i execute the SQL file containing the creation of the two tables, it gives me an error that he doesn't find the other table. I'm working with sqlplus to execute the sql file.
Here's an example of SQL file i tried with :
create table A(
Age number(3),
name number(3) constraint A_FK references B(name))
/
create table B(
Age number(3) constraint B_FK references A(Age),
name number(3))
And even if i reverse the order, it gives the same error.
Thanks for help.
This is a problem of cycles in foreign keys. One method is to add all foreign keys after table creation (as I think the other answers propose).
You can also just do that for the first table:
create table A (
Age number(3) primary key,
name number(3)
);
create table B (
name number(3) primary key,
Age number(3),
constraint B_FK foreign key (age) references A(Age)
);
alter table B add constraint A_FK foreign key (name) references B(name);
Here is a db<>fiddle.
Notes:
Foreign keys should reference primary keys, so I added that declaration as well.
I recommend making the primary key the first column in the table.
You can also define the constraint inline for one of the tables (i.e. age number(3) constraint b_fk references a(age)).
The table column(s) that is referred by a foreign key must exist at the time when the constraint is created. Since you have some kind of cyclic reference between the tables, you need to do this in three steps:
first create one table without the foreign key
create the second table (with its foreign key)
finally add the foreign key to the first table with an alter table statement
You also need the referred column to have a unique or primary key constraint set up, otherwise you would get error ORA-02270: no matching unique or primary key for this column-list.
create table A(
age number(3) primary key,
name number(3)
);
create table B(
age number(3) constraint B_FK references A(Age),
name number(3) primary key
);
alter table A add constraint A_FK foreign key (name) references B(name);
Demo on DB Fiddle
Side note: I am quite suspicious about your sample structure, but this could be because your oversimplified it in the question.
It fails because the reference table doesn't exist yet.
Create the tables without the key first. Then drop one and recreated it with the reference. Then drop the 2nd and recreate it with the reference.
Create table first and then ADD the CONSTRAINT
ALTER TABLE A
ADD FOREIGN KEY (name) REFERENCES B(name);
ALTER TABLE B
ADD FOREIGN KEY (age) REFERENCES A(age);

How to reference a postgres table with multiple primary keys

How could I create a xref table with a reference to this table?
CREATE TABLE reviewer (
screen_name integer,
identity_provider text
CONSTRAINT identity PRIMARY KEY (screen_name, identity_provider)
);
This is what I've tried so far:
CREATE TABLE business_reviewer_xref (
reviewer_screen_name integer,
reviewer_identity_provider text,
CONSTRAINT reviewer_identity UNIQUE (reviewer_screen_name, reviewer_identity_provider),
reviewer_identity REFERENCES reviewer(identity)
);
CREATE TABLE business_reviewer_xref (
reviewer_screen_name integer,
reviewer_identity constraint REFERENCES reviewer(identity)
);
CREATE TABLE business_reviewer_xref (
reviewer_screen_name integer,
reviewer_identity REFERENCES reviewer(identity)
);
A table cannot have multiple primary keys. It can only have one or none. But a primary key can of course consist of more than one column (but at least of one of course). To reference such a multi column primary key, you need a corresponding column in the referencing table for each column in the primary key of the referenced column.
To define a foreign key constraint, list the corresponding columns in the referencing table in the same order as their counterparts occur in the primary key constraint in the referenced table in the defining tuple of the foreign key. Also keep the order in the definition of the referenced columns' tuple.
In your case:
CREATE TABLE business_reviewer_xref
(reviewer_screen_name integer,
reviewer_identity text,
FOREIGN KEY (reviewer_screen_name,
reviewer_identity)
REFERENCES reviewer
(screen_name,
identity));
Note that a foreign key constraint, in contrast to a primary key constraint, doesn't implicitly set a unique constraint. If you want uniqueness too, you'd have to define another constraint for that.

Cannot create foreign key on oracle

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.

SQL: Primary and foreign key

I am creating a table that has two values that are both primary and foreign at the same time. I do not know how to create them in SQL. Here is what I did but I get the error, there must only be one primary key. what is the correct way?
CREATE TABLE movie_director(
director_id CHAR(8)
constraint pk_director_id_movie_director
PRIMARY KEY
constraint fk_director_id_movie_director
REFERENCES director,
movie_id VARCHAR(30)
constraint pk_movie_id_movie_director
PRIMARY KEY
constraint fk_movie_id_movie_director
REFERENCES movie
)
What you seem to be looking for is a compound primary key. Change your table definition to something like the following:
CREATE TABLE movie_director(
director_id CHAR(8)
constraint fk_director_id_movie_director
REFERENCES director,
movie_id VARCHAR(30)
constraint fk_movie_id_movie_director
REFERENCES movie,
CONSTRAINT PK_MOVIE_DIRECTOR
PRIMARY KEY (DIRECTOR_ID, MOVIE_ID));
Your error seems pretty clear. There can only be one PRIMARY KEY on a table.
You need to create a COMPOUND PRIMARY KEY which consists of two columns (director_id,movie_id).
From wikipedia:
In database design, a compound key is a key that consists of two or more attributes that uniquely identify an entity occurrence.

How to use two columns in a foreign key constraint

I have two tables:
Article
Subscription
In the Article table I have two columns that make up the primary key: id, sl. In the Subscription table I have a foreign key 'idsl`.
I use this constraint :
constraint FK_idsl
foreign key (idsl) references CSS_SubscriptionGroup(id, sl)
But when I run the query, I getting this error:
Number of referencing columns in foreign key differs from number of referenced columns, table X
In Article Table I have two fields that are the primary key: id,sl. In the Subscription Table I have a foreign key 'idsl`
This design is broken - it is apparent that the composite primary key in Article(id, sl) has been mangled into a single compound foreign key in table Subscription. This isn't a good idea.
Instead, you will need to change the design of table Subscription to include separate columns for both id and sl, of the same type as the Article Table, and then create a composite foreign key consisting of both columns, referencing Article in the same order as the primary key, e.g:
CREATE TABLE Article
(
id INT NOT NULL,
sl VARCHAR(50) NOT NULL,
-- Other Columns
CONSTRAINT PK_Article PRIMARY KEY(id, sl) -- composite primary key
);
CREATE TABLE Subscription
(
-- Other columns
id INT NOT NULL, -- Same type as Article.id
sl VARCHAR(50) NOT NULL, -- Same type as Article.sl
CONSTRAINT FK_Subscription_Article FOREIGN KEY(id, sl)
REFERENCES Article(id, sl) -- Same order as Article PK
);
Edit
One thing to consider here is that by convention a column named table.id or table.tableid should be unique, and is the primary key for the table. However, since table Article requires an additional column sl in the primary key, it implies that id isn't unique.
correct syntax for relation:
CONSTRAINT FK_OtherTable_ParentTable
FOREIGN KEY(OrderId, CompanyId) REFERENCES dbo.ParentTable(OrderId, CompanyId)
You must try like this:
constraint FK_idsl foreign key (id,sl) references CSS_SubscriptionGroup(id,sl)