How to create foreign key with ON DELETE CASCADE constraint that references the same table? - sql

I tried to create foreign key with ON DELETE CASCADE constraint that references the same table, but that deemed to be impossible due to the following error:
Introducing FOREIGN KEY constraint 'FK_Employees_Employees' on table
'Employees' may cause cycles or multiple cascade paths.
How should I be defining my table? My requirements are:
Employee might not have a manager
When employee who is a manager is deleted all of his employees are also deleted
CREATE TABLE [dbo].[Employees]
(
[EmployeeId] INT NOT NULL IDENTITY(1,1),
[ManagerId] INT NULL,
--...
CONSTRAINT [PK_Employees] PRIMARY KEY ([EmployeeId]),
CONSTRAINT [FK_Employees_Employees] FOREIGN KEY ([ManagerId])
REFERENCES [dbo].[Employees] ([EmployeeId]) -- ON DELETE CASCADE
)

Related

Recover Foreign keys

CREATE TABLE Infrastructure.OBSModules(
OBSId int FOREIGN KEY REFERENCES Infrastructure.OBS(Id) NOT NULL,
ModuleId int FOREIGN KEY REFERENCES Infrastructure.Module(Id) NOT NULL,
Constraint PK_Infrastructure_OBS_Module Primary Key(OBSId,ModuleId)
)
Go
The above code is my code by which I created Infrastructure.OBSType table,but I deleted foreign keys manually so I cant Insert any rows in my table.how can I recover those foreign keys?

Defining foreign key for a composite primary key in SQL Server

I have two tables: Ticket and TicketRelation. I am trying to relate 2 Tickets using the TicketRelation table.
I want to add a cascade constraint to both foreign keys.
I am using SQL Server Management Studio to add the constraints but I get this error:
Introducing FOREIGN KEY constraint 'FK_destiny_ticket' on table 'ticketRelation' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I also tried to do this with a trigger, but I am not sure how to define it.
Here I provide the tables definitions:
This is the base entity TICKET
CREATE TABLE ticket
(
ticket_id BIGINT,
some_data VARCHAR (50),
CONSTRAINT PK_ticket PRIMARY KEY (ticket_id)
);
and the relational table TICKETRELATION
CREATE TABLE ticketRelation
(
origin_ticket BIGINT,
destiny_ticket BIGINT,
relation_data VARCHAR (50),
CONSTRAINT PK_ticket_relation PRIMARY KEY (origin_ticket, destiny_ticket),
CONSTRAINT FK_origin_ticket FOREIGN KEY (origin_ticket)
REFERENCES ticket(ticket_id),
CONSTRAINT FK_destiny_ticket FOREIGN KEY (destiny_ticket)
REFERENCES ticket(ticket_id),
)
I want to add an ON DELETE CASCADE constraint to both foreign keys:
CONSTRAINT FK_origin_ticket FOREIGN KEY (origin_ticket)
REFERENCES ticket(ticket_id)
ON DELETE CASCADE, -- I want to add this --
CONSTRAINT FK_destiny_ticket FOREIGN KEY (origin_ticket)
REFERENCES ticket(ticket_id)
ON DELETE CASCADE, -- and this --

Recursive relationship SQL error

I am pretty new to SQL and I have a problem. I want to make a recursive relationship (a table that relates to itself), but I get an error when I try to execute my code. It's working fine without the Coordinator_Office_ID foreign key.
The error is:
The number of columns in the foreign-key referencing list is not equal
to the number of columns in the referenced list.
Create table Logistican (
Office_ID Number(10) Constraint nb_office Not NULL,
Worker_ID Number(15) Constraint lg_worker not null,
Name_logistican Varchar(20),
Room Varchar(10) constraint log_room UNIQUE,
Coordinator_Office_ID Integer,
Primary key (Office_ID, Worker_ID),
Constraint work_id Foreign key (Worker_ID) References worker(worker_ID) on delete cascade,
Constraint lg_cord_id Foreign key (Coordinator_Office_ID) References Logistican(Office_ID)
);
Yes, that's cause you have defined composite primary key like Primary key (Office_ID, Worker_ID) and thus your FK should include both of them else it will result in PFD (partial functional dependency)
Add the constraint with alter table:
Create table Logistican (
Office_ID Number(10) Constraint nb_office Not NULL,
Worker_ID Number(15) Constraint lg_worker not null,
Name_logistican Varchar(20),
Room Varchar(10) constraint log_room UNIQUE,
Coordinator_Office_ID Integer,
Primary key (Office_ID, Worker_ID),
Constraint work_id Foreign key (Worker_ID) References worker(worker_ID) on delete cascade
);
alter table Logistican
add Constraint lg_cord_id
Foreign key (Coordinator_Office_ID, Worker_Id) References Logistican(Office_ID, Worker_Id);
The relationship needs all elements of the primary key to be valid. I'm not sure if it needs to be a separate statement in Oracle.

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

SQL ALTER TABLE ON DELETE CASCADE

I have the following tables:
CREATE TABLE BOOK_AUTHORS
(Book_id CHAR(20) NOT NULL,
AuthorName VARCHAR(30) NOT NULL,
PRIMARY KEY (Book_id, AuthorName),
FOREIGN KEY (Book_id) REFERENCES BOOK (Book_id));
CREATE TABLE BOOK_COPIES
(Book_id CHAR(20) NOT NULL,
Branch_id CHAR(20) NOT NULL,
No_of_copies NUMBER,
PRIMARY KEY (Book_id, Branch_id),
FOREIGN KEY (Book_id) REFERENCES BOOK (Book_id),
FOREIGN KEY (Branch_id) REFERENCES LIBRARY_BRANCH (Branch_id));
I want to add ON DELETE CASCADE constraints to the both of them:
The first time I tried it said it worked. That file looks like:
ALTER TABLE "BOOK_AUTHORS"
ADD CONSTRAINT "fk_test"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
Then I went through and made two separate tables for the two foreign keys in the second table:
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test1"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test2"
FOREIGN KEY ("Branch_id")
REFERENCES "LIBRARY_BRANCH" ("Branch_id")
ON DELETE CASCADE;
However, upon doing so I got the errors
"Book_id" invalid identifier
and then
"Branch_id" invalid identifier
I don't know what I did wrong. I then went back and did the first alter table again (the one that I originally thought worked) and it gave me the same error message ("Book_id" invalid identifier). Can someone help me add these constraints? I also have five other tables to add these constraints to.
If you put double quotes around your identifiers (like you did in
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test1"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
) your identifiers (e.g. "Book_id" in this case) become case-sensitive.
So either you'll have to change your table definition and rename the column to "Book_id" or (much preferably IMHO) just get rid of the double quotes in your constraint definition:
ALTER TABLE BOOK_COPIES
ADD CONSTRAINT fk_test1
FOREIGN KEY (Book_id)
REFERENCES BOOK (Book_id)
ON DELETE CASCADE;
First of all let me clear one thing, You cant add on delete cascade to an already existing foreign key constraint, as shown in docs you can only change its state which means enable or disable, in case if you need to add then drop the constraint first. This question is asked twice and still repeating please moderators have a glance on this. Here are links that has already solved your problem. first , second and this third and who knows how many questioned asked on on delete cascade.
Put doublequotes (") around your table and column names.
I added table "BOOK" and table "LIBRARY_BRANCH":
CREATE TABLE "BOOK"
("Book_id" CHAR(20) NOT NULL,
"BookName" VARCHAR(30) NOT NULL,
PRIMARY KEY ("Book_id"));
CREATE TABLE "BOOK_AUTHORS"
("Book_id" CHAR(20) NOT NULL,
"AuthorName" VARCHAR(30) NOT NULL,
PRIMARY KEY ("Book_id", "AuthorName"));
CREATE TABLE "LIBRARY_BRANCH"
("Branch_id" CHAR(20) NOT NULL,
"Branch_name" VARCHAR(50),
"Address" VARCHAR(100),
PRIMARY KEY ("Branch_id"));
CREATE TABLE "BOOK_COPIES"
("Book_id" CHAR(20) NOT NULL,
"Branch_id" CHAR(20) NOT NULL,
"No_of_copies" NUMBER,
PRIMARY KEY ("Book_id", "Branch_id"));
ALTER TABLE "BOOK_AUTHORS"
ADD CONSTRAINT "fk_test"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test1"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test2"
FOREIGN KEY ("Branch_id")
REFERENCES "LIBRARY_BRANCH" ("Branch_id")
ON DELETE CASCADE;
sqlfiddle demo