I am creating table with the following code:
CREATE TABLE ELEM
(
ID INTEGER AUTO_INCREMENT NOT NULL,
TYP_ID INTEGER,
SPELL VARCHAR(50),
CONSTRAINT ELEM_PK PRIMARY KEY (ID),
CONSTRAINT ELEM_SK UNIQUE (ID, TYP_ID),
CONSTRAINT ELEM_TYP_FK FOREIGN KEY (TYP_ID) REFERENCES TYP (ID)
);
in result I get indices with the names of PRIMARY_KEY_2, ELEM_TYP_FK_INDEX_2 and CONSTRAINT_INDEX_2. Can I control these names in CREATE TABLE statement?
Related
How can I make an attribute a primary key within a table but also as a foreign key which references another table using sql in sql developer?
I know how to make it an attribute as a foreign key and a primary separate but not as a primary key as well as a foreign key
That's perfectly normal. For example:
create table employee (
id number(6) primary key not null,
name varchar2(50)
);
create table employee_desk (
desk_id number(6) primary key not null, -- PK and FK!
location varchar2(20),
constraint fk1 foreign key (desk_id) references employee (id)
);
The column desk_id is the primary key of the table employee_desk, and also a foreign key that points to the table employee.
Below is the example of primary key with foreign key
create table animals (id integer primary key);
create table cats (
id integer primary key
, name varchar(100) not null
, constraint d_cats_animals_fk foreign key (id) references animals (id)
);
Ok, sorry if my code is not in the best format. I am getting an error when trying to create the second table. I get this error: ORA-02270: no matching unique or primary key for this column-list. I have read other posts and I am confused to what is wrong with my foreign keys. The foreign keys in E_T are D_ID, and SP_ID. D_id is referencing table d_t and SP_ID is referencing table e_t since it's a it is a unary relationship with E_ID. I believe it is employee ID and supervisor ID. The FK and PK datatypes match.
CREATE TABLE D_T
(
D_ID INTEGER NOT NULL,
D_Name VARCHAR(45),
CONSTRAINT D_T_PK PRIMARY KEY (D_ID)
);
CREATE TABLE E_T
(
E_ID INTEGER NOT NULL,
E_Name VARCHAR(45),
D_ID INTEGER,
Salary INTEGER,
SP_ID INTEGER,
CONSTRAINT E_T_PK PRIMARY KEY (E_ID),
CONSTRAINT E_T_FK1 FOREIGN KEY (D_ID) REFERENCES D_T(D_ID),
CONSTRAINT E_T_FK2 FOREIGN KEY (SP_ID) REFERENCES E_T(SP_ID)
);
I would like to note, on the Oracle server -- line 13 and 14 of my script the word "KEY" is not in blue. I am unsure if that is significant.
You are referencing the wrong column for the self-reference. So the second table should look more like:
CREATE TABLE E_T (
E_ID INTEGER NOT NULL PRIMARY KEY,
E_Name VARCHAR(45),
D_ID INTEGER,
Salary INTEGER,
SP_ID INTEGER,
CONSTRAINT E_T_FK1 FOREIGN KEY (D_ID) REFERENCES D_T(D_ID),
CONSTRAINT E_T_FK2 FOREIGN KEY (SP_ID) REFERENCES E_T(E_ID)
-------------------------------------------------------^
)
I have a question about foreign keys.
How does it work when I want to add a foreign key to the first table that I make that references to the primary key of the second table I create?
CREATE TABLE table1
(
name_id INT NOT NULL,
team TEXT REFERENCES table2(team_id),
PRIMARY KEY(name_id)
);
CREATE TABLE table2
(
team_id INT NOT NULL,
teamname TEXT,
PRIMARY KEY(team_id)
);
If I try the code above I get the following error:
ERROR: relation "" does not exist
Thanks in advance.
Either create the second table first. Or use alter table. That is, create the first table without the reference and then do:
alter table table1 add constraint fk_table1_team
foreign key (team_id) REFERENCES table2(team_id);
The declaration for table1 would be:
CREATE TABLE table1 (
name_id INT NOT NULL,
team_id INT,
PRIMARY KEY(name_id)
);
The reference between the tables should be on the primary key and certainly not on a character column, if an integer is available.
here's the syntax of creating a table with Foreign key:
CREATE TABLE table11
(
name_id INT NOT NULL,
team INT,
PRIMARY KEY(name_id),
foreign key(team) references table22(team_id)
);
CREATE TABLE table22
(
team_id INT NOT NULL,
teamname TEXT,
PRIMARY KEY(team_id)
);
but there was another problem. a foreign key from a child table cannot reference to a primary key from a parent folder if they do not contain the same type. in your code team was of TEXT and team_id was of INT which cannot be.
I have the following queries that I run to create tables in MS SQL Server:
CREATE TABLE menus
(
menu_id int NOT NULL PRIMARY KEY,
menu_name char,
other_details char
)
CREATE TABLE bookings
(
booking_Id int NOT NULL PRIMARY KEY,
date_booked DATE,
date_of_booking DATE,
other_details char,
staff_id int FOREIGN KEY REFERENCES staff(staff_id),
customer_id int FOREIGN KEY REFERENCES customers(customer_id)
)
CREATE TABLE menus_booked
(
menu_id INT NOT NULL,
booking_id INT NOT NULL,
CONSTRAINT PK_menus_booked PRIMARY KEY(menu_id,booking_id),
FOREIGN KEY (menu_id) REFERENCES menus(menu_id),
FOREIGN KEY (booking_id) REFERENCES bookings(booking_id)
)
CREATE TABLE menu_changes
(
change_id int NOT NULL PRIMARY KEY,
menu_id int NOT NULL,
booking_id int NOT NULL,
change_details char,
FOREIGN KEY (menu_id) REFERENCES menus_booked(menu_id),
FOREIGN KEY (booking_id) REFERENCES menus_booked(booking_id)
)
On running the last query I get the error:
There are no primary or candidate keys in the referenced table 'menus_booked' that match the referencing column list in the foreign key 'FK_menu_chan_menu'
I am unsure if my queries are correct and can't resolve this error.
The primary key of menus_booked is a unique combination of menu_id and booking_id. A foreign must point to that combination, not just one of its fields, which is not necessarily unique. Your query currently tries to define two foreign keys, one on each column, instead of one foreign key on the combination of the columns:
CREATE TABLE menu_changes
(
change_id int NOT NULL PRIMARY KEY,
menu_id int NOT NULL,
booking_id int NOT NULL,
change_details char,
FOREIGN KEY (menu_id, booking_id)
REFERENCES menus_booked(menu_id, booking_id) -- Here!
)
A foreign key has to reference a primary key (or unique key but here the PK is the problem), and it has to reference it in it's entirety.
FOREIGN KEY (menu_id) REFERENCES menus_booked(menu_id),
FOREIGN KEY (booking_id) REFERENCES menus_booked(booking_id)
You have two foreign key's referencing part of the primary key of menus_booked. You'll have to alter it to:
FOREIGN KEY (menu_id, booking_id) REFERENCES menus_booked(menu_id, booking_id)
In PostgreSQL I have a database, which I intend to make the following table declaration:
CREATE TABLE canvas_user (
id INTEGER,
login_id VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(355) UNIQUE NOT NULL,
name_given VARCHAR(30),
name_family VARCHAR(30),
name_full VARCHAR(50),
role canvas_role,
last_login TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE problem (
id SERIAL,
title VARCHAR(50),
author VARCHAR(50),
path TEXT,
compiler VARCHAR(20),
PRIMARY KEY (id)
);
CREATE TABLE assignment (
id INTEGER,
title TEXT NOT NULL,
points_possible INTEGER NOT NULL,
problem_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY (problem_id) REFERENCES problem(id)
);
CREATE TABLE submission (
num SERIAL,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
lti_info TEXT[],
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (user_id) REFERENCES canvas_user(id),
FOREIGN KEY (assignment_id) REFERENCES assignment(id)
);
CREATE TABLE correction (
num INTEGER,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
execution_time interval,
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (num) REFERENCES submission(num),
FOREIGN KEY (user_id) REFERENCES submission(user_id),
FOREIGN KEY (assignment_id) REFERENCES submission(assignment_id)
);
Everything works fine, except for the following error at the creation of the last table (correction):
ERROR: there is no unique constraint matching given keys for
referenced table "submission"
What I intend with the correction table is to have an unique correction for each submission but a submission can have (or not) a correction.
How can I solve this error? Is it a problem of design or just a table declaration mistake?
A foreign key constraint does not care whether the referenced column(s) is referencing another column itself. But the referenced column(s) must be unique. That's what the error message tells you (quite clearly).
What you are missing is that a foreign key constraint can be based on multiple columns. This should work:
FOREIGN KEY (num, user_id, assignment_id) REFERENCES submission
Replacing:
FOREIGN KEY (num) REFERENCES submission(num),
FOREIGN KEY (user_id) REFERENCES submission(user_id),
FOREIGN KEY (assignment_id) REFERENCES submission(assignment_id)
The short form of the syntax (REFERENCES submission) is possible, because you are referencing the primary key, which is the default.
Plus, you can simplify: make submission.num the sinlge-column primary key, drop the redundant columns user_id and assignment_id from correction and reduce the fk constraint to just (num) - as discussed in #Tim's answer.
As long as you have the multicolumn fk constraint, consider NOT NULL constraints on each of the referencing columns (as commented by #joop). Else, one or more NULL values in the referencing columns allow to escape the fk constraint with the default MATCH SIMPLE behaviour. This may or may not be intended, typically it is not.
Alternatively consider MATCH FULL for multicolumn fk constraints to only allow that if all referencing columns are NULL. Details:
MATCH FULL vs MATCH SIMPLE
Make the foreign key from the correction table to the submission table a compound key that is unique.
Also, review the design of the submission table; num is a serial type and should be the unique primary key. You can add a unique constraint to the columns num, user_id, and assignment_id
CREATE TABLE canvas_user (
id INTEGER,
login_id VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(355) UNIQUE NOT NULL,
name_given VARCHAR(30),
name_family VARCHAR(30),
name_full VARCHAR(50),
role canvas_role,
last_login TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE problem (
id SERIAL,
title VARCHAR(50),
author VARCHAR(50),
path TEXT,
compiler VARCHAR(20),
PRIMARY KEY (id)
);
CREATE TABLE assignment (
id INTEGER,
title TEXT NOT NULL,
points_possible INTEGER NOT NULL,
problem_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY (problem_id) REFERENCES problem(id)
);
CREATE TABLE submission (
num SERIAL,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
lti_info TEXT[],
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (user_id) REFERENCES canvas_user(id),
FOREIGN KEY (assignment_id) REFERENCES assignment(id)
);
CREATE TABLE correction (
num INTEGER,
user_id INTEGER,
assignment_id INTEGER,
timestamp TIMESTAMP,
path TEXT,
execution_time interval,
PRIMARY KEY(num, user_id, assignment_id),
FOREIGN KEY (num, user_id,assignment_id ) REFERENCES submission(num, user_id, assignment_id)
);