How to insert a record in many to many relationship tables? - sql

For exmple i have two tables
A
create table teachers(
id number(4) primary key,
name varchar(20)
);
B
create table students(
id number(4) primary key,
name varchar(20)
);
and a third table
AB
create table Teacher_Student(
T_Id number(4),
S_Id number(4)
);
and their relationship
alter table teacher_student
add constraint s_t_pk Primary key(T_Id, S_Id);
Is this relationship is created correctly? and what would be the insertion query if i want to add a new student or a teacher.

Suggestion: also add referential integrity constraints:
alter table teacher_student
add constraint s_t_fk_t foreign key (T_Id)
references teachers (id)
on delete cascade
on update cascade;
alter table teacher_student
add constraint s_t_fk_s foreign key (S_Id)
references students (id)
on delete cascade
on update cascade;

Usual manouever for this would require primary keys for student and teacher tables, and then foreign keys for T_Id and S_id to Teachers and Students from Teacher_Student.
When you've done that, inserting to student and teacher, would only check uniqueness of their keys, i.e , you can't have two student's with an id of 1.
Inserting to Teacher_Student would check uniqueness of the relationship, and that the inserted ids exist in their respective tables.
PS abbreviating database object names is a very objectionable habit.

Related

Delete/Modify row in one table based on a condition - Oracle DBMS

I have a table structure like
create table EMPLOYE (
CodeEmploye varchar2(100) not null,
NAS varchar2(100),
CONSTRAINT employe_pk primary key (CodeEmploye)
);
create table SALAIRE (
CodeEmploye varchar2(100) not null,
Mois number not null,
CONSTRAINT salaire_pk primary key (CodeEmploye, Mois),
CONSTRAINT salaire_code_employe_fk FOREIGN KEY(CodeEmploye) REFERENCES EMPLOYE(CodeEmploye)
);
I want to add a constraint where I should not be allowed to modify/delete a row in EMPLOYE table if the same employee exist in SALAIRE table.
What is the best way to do that ?
As you have define the foreign key relationship between two tables by "CodeEmployee" column, what you want has been achieved.
A little bit extension is that if you add "ON DELETE CASCADE" following the fk declaration, once you delete any row form employee table, all the related records in the salary table will be deleted as well.
One of the best ways to do is by creating a foreign key constraint on the "CodeEmploye" column during CREATE TABLE or ALTER TABLE statements. In your case, it is already created (salaire_code_employe_fk) as part of your CREATE statement.
A foreign key constraint ensures that an employee row from the parent table (EMPLOYE) cannot be modified/deleted if the same employee exists in the child table (SALAIRE).
In this case, when you create the order_items table, you define a foreign key constraint with the DELETE CASCADE option as follows:
CREATE TABLE order_items
(
order_id NUMBER( 12, 0 ),
-- other columns
-- ...
CONSTRAINT fk_order_items_orders
FOREIGN KEY( order_id )
REFERENCES orders( order_id )
ON DELETE CASCADE
);
By doing this, whenever you delete a row from the orders table, for example:
DELETE
FROM
orders
WHERE
order_id = 1;
All the rows whose order id is 1 in the order_items table are also deleted automatically by the database system.

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);

Creating a table with 2 primary keys and two foreign keys referring to 2 different tables with same constraint name

For this particular schema:
I have created the department student and subject tables now the problem right now arises in the creation of the mark table.
It is specified that there are 2 primary keys and 2 foreign keys , but as the title suggests creating 2 foreign keys referring to 2 different tables having the same constraint name seems impossible as per my understanding by surfing on the internet and reading on few threads here.
Is there any way to do this ? I want to have both the foreign key's constraint name to be "fk".
This code pops with a identifier error:
create table mark(
value number,
subject_id number,
student_id number,
constraint pk primary key(subject_id,student_id),
constraint fk foreign key(subject_id,student_id) references subject(subject_id,student_id));
But even if i create 2 constraints with different name test cases fail. Is there a solution?
This is department table
create table department(
department_id number(2),
department_name varchar(30),
department_block_number number,
constraint PK primary key(department_id));
This is student table
create table student(
student_id number,
student_name varchar(30),
address varchar(40),
city varchar(30),
department_id number,
constraint pk primary key(student_id),
constraint fk foreign key(department_id) references department(department_id));
This is staff table
create table staff(
staff_id number,
staff_name varchar(30),
department_id number,
constraint pk primary key(staff_id),
constraint fk foreign key(department_id) references department(department_id));
You have a composite primary key - on more than one column - which is fine; but you can't have a composite foreign key as the student table doesn't have a subject_id column - hence it giving you an invalid-identifier error.
You need two foreign keys, something like:
create table mark(
value number,
subject_id number,
student_id number,
constraint mark_pk primary key(subject_id,student_id),
constraint mark_fk_subject foreign key(subject_id) references subject(subject_id),
constraint mark_fk_student foreign key(student_id) references student(student_id));
The constraint names have to be unique, both within and across tables in the same schema, and something more descriptive than 'pk' or 'fk' would be sensible anyway.
db<>fiddle

Postgresql, references to unique constraint

I'm running PostgreSQL 9.4 and have the following table:
CREATE TABLE user_cars (
user_id SERIAL REFERENCES users (id) ON DELETE CASCADE,
car CHARACTER VARYING(255) NOT NULL,
CONSTRAINT test UNIQUE (user_id, car)
);
The table allows a user to have multiple cars, but only use the car name once. But other users may have the same car name.
I would like to have another table with references to the unique constraint test, and have tried stuff like:
CREATE TABLE mappings (
other_id CHARACTER(9) REFERENCES other (id) ON DELETE CASCADE,
user_cars REFERENCES user_cards (test) ON DELETE CASCADE
);
But that fails "obviously". I would like to make sure that other_id only have a single references to a user_car entry.
So to explain, how can I in table mappings have a references to test from table user_cars.
This is the thing that fails currently:
user_cars REFERENCES user_cards (test) ON DELETE CASCADE
Don't use composite foreign key references, if you can avoid it. Just add a unique id to the table:
CREATE TABLE user_cars (
user_car_id serial primary key,
user_id int REFERENCES users (id) ON DELETE CASCADE,
car CHARACTER VARYING(255) NOT NULL,
CONSTRAINT test UNIQUE (user_id, car)
);
Then mappings is simply:
CREATE TABLE mappings (
mapping_id serial primary key,
user_car_id int references user_cars(user_car_id) on delete cascade,
other_id CHARACTER(9) REFERENCES other (id) ON DELETE CASCADE,
);
If car should be unique, add UNIQUE constrain only on car column.
If user should be unique, add UNIQUE constrain only on user column.
If you add UNIQUE constrain on combination, then there will be duplicate values in the table.
UPDATE:
You can add multiple constraints on single column. With Foreign key add UNIQUE constraint as well on user_cars column in mapping table.

How to add a foreign key referring to itself in SQL Server 2008?

I have not seen any clear, concise examples of this anywhere online.
With an existing table, how do I add a foreign key which references this table? For example:
CREATE TABLE dbo.Projects(
ProjectsID INT IDENTITY(1,1) PRIMARY KEY,
Name varchar(50)
);
How would I write a command to add a foreign key which references the same table? Can I do this in a single SQL command?
I'll show you several equivalent ways of declaring such a foreign key constraint. (This answer is intentionally repetitive to help you recognise the simple patterns for declaring constraints.)
Example: This is what we would like to end up with:
Case 1: The column holding the foreign keys already exists, but the foreign key relationship has not been declared / is not enforced yet:
In that case, run this statement:
ALTER TABLE Employee
ADD FOREIGN KEY (ManagerId) REFERENCES Employee (Id);
Case 2: The table exists, but it does not yet have the foreign key column:
ALTER TABLE Employee
ADD ManagerId INT, -- add the column; everything else is the same as with case 1
FOREIGN KEY (ManagerId) REFERENCES Employee (Id);
or more succinctly:
ALTER TABLE Employee
ADD ManagerId INT REFERENCES Employee (Id);
Case 3: The table does not exist yet.
CREATE TABLE Employee -- create the table; everything else is the same as with case 1
(
Id INT NOT NULL PRIMARY KEY,
ManagerId INT
);
ALTER TABLE Employee
ADD FOREIGN KEY (ManagerId) REFERENCES Employee (Id);
or, declare the constraint inline, as part of the table creation:
CREATE TABLE Employee
(
Id INT NOT NULL PRIMARY KEY,
ManagerId INT,
FOREIGN KEY (ManagerId) REFERENCES Employee (Id)
);
or even more succinctly:
CREATE TABLE Employee
(
Id INT NOT NULL PRIMARY KEY,
ManagerId INT REFERENCES Employee (Id)
);
P.S. regarding constraint naming: Up until the previous revision of this answer, the more verbose SQL examples contained CONSTRAINT <ConstraintName> clauses for giving unique names to the foreign key constraints. After a comment by #ypercube I've decided to drop these clauses from the examples, for two reasons: Naming a constraint is an orthogonal issue to (i.e. independent from) putting the constraint in place. And having the naming out of the way allows us to focus on the the actual adding of the constraints.
In short, in order to name a constraint, precede any mention of e.g. PRIMARY KEY, REFERENCES, or FOREIGN KEY with CONSTRAINT <ConstraintName>. The way I name foreign key constraints is <TableName>_FK_<ColumnName>. I name primary key constraints in the same way, only with PK instead of FK. (Natural and other alternate keys would get the name prefix AK.)
You can add the column and constraint in one operation
ALTER TABLE dbo.Projects ADD
parentId INT NULL,
CONSTRAINT FK FOREIGN KEY(parentid) REFERENCES dbo.Projects
Optionally you could specify the PK column in brackets after the referenced table name but it is not needed here.
If the table already exists: Assuming you don't already have a column to store this data. If you do then skip this step.
ALTER TABLE [dbo].[project]
ADD [fkProjectsId] INT;
GO
ALTER TABLE [dbo].[projects]
ADD CONSTRAINT [FK_Projects_ProjectsId] FOREIGN KEY ([fkProjectsId]) REFERENCES [dbo].[Projects] ([ProjectsID])
GO