SQL best solution for the delete operation on multiple relationships - sql

I would like to have a clarification on deleting the multiple relationship
I have a schema that has a table 'A' and other tables of schema, that refer to 'A' with the role (Cascade) on delete operation.
There are also tables which refer to 'A' and which also have other references to other tables of 'A', but in this case the elimination must have a null value.
CREATE TABLE A
(A_ID INTEGER PK
...
)
CREATE TABLE B
(B_ID INTEGER PK
A_ID INTEGER NOT NULL
...
FOREIGN KEY A_ID REFERENCES A(A_ID) ON DELETE CASCADE
)
CREATE TABLE C
(C_ID INTEGER PK
A_ID INTEGER NOT NULL
B_ID INTEGER
...
FOREIGN KEY A_ID REFERENCES A(A_ID) ON DELETE CASCADE
FOREIGN KEY B_ID REFERENCES B(B_ID) ON DELETE SET NULL
)
These multiple relationships cause me a problem on the role delete operation.
I would have two options:
The first, and take on the role cascade all relationship with 'A', but that means I have to create a function that when I have to delete values of table 'A', the other value reference with this table delete from the bottom up. In the future I might forget to add a new table.
The second solution and create a table of connection to their reporting obligations have null values:
CREATE TABLE C
(C_ID INTEGER PK
A_ID INTEGER NOT NULL
...
FOREIGN KEY A_ID REFERENCES A(A_ID) ON DELETE CASCADE
)
CREATE TABLE C_B
(C_ID INTEGER PK
B_ID INTEGER PK
...
FOREIGN KEY C_ID REFERENCES C(C_ID) ON DELETE CASCADE
FOREIGN KEY B_ID REFERENCES B(B_ID) ON DELETE CASCADE
)
It involves the creation of several new bridging tables.
There is a different solution to this case?
I currently use Apache Derby and JPA for persistence

Related

Create two foreign key constraints with on update/delete cascade

Example of database (SQL Server):
Table A
-colA (PK, int)
Table B
-ColB (FK, int) --> points to Table X
Table C
-ColAC (PK, FK, int not null) --> points to Table A
-ColBC (PK, FK, int not null) --> points to Table B
Table C's primary key is both ColAC and ColBC. Each column has foreign key that points to a different table. I need to have ON UPDATE/DELETE CASCADE constraints on both foreign keys for Table C. So when either Table A or B has changes then it is cascaded in Table C.
Table A and B are already in use. I can create Table C with only either one of the constraints but not both, this will return an error message. How do I create both FK constraints?
Example of SQL:
CREATE TABLE Table_C (
ColAC INT NOT NULL,
ColBC INT NOT NULL,
PRIMARY KEY (
ColAC,
ColBC
)
)
GO
ALTER TABLE Table_C WITH CHECK ADD FOREIGN KEY (ColAC)
REFERENCES Table_A (ColA)
ON UPDATE CASCADE
ON DELETE CASCADE
GO
--The second constraint will always fail (does not matter which one is first).
ALTER TABLE Table_C WITH CHECK ADD FOREIGN KEY (ColBC)
REFERENCES Table_B (ColB)
ON UPDATE CASCADE
ON DELETE CASCADE
GO
Error message:
Introducing FOREIGN KEY constraint .... on table 'Table_C' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
You can go for two different tables, instead of single TableC
Table C1
-ColAC (PK, FK, int not null) --> points to Table A
Table C2
-ColBC (PK, FK, int not null) --> points to Table B
Now, you can have UNION ALL between these two tables
CREATE VIEW vw_TableC
AS
SELECT ColAC, 'TableA' as parent ... FROM TableC1
UNION ALL
SELECT ColBC, 'TableB' as parent ... FROM TableC2

How to add delete cascade constraint in sql

I have 2 tables.Table A have columns as (aid, name,depart) where aid is primary key.
Table B has (aid1,aid2,aid3,created_by) where aid1 is the primary_key. aid1, aid2 and aid3 all are primary key of Table A
I want to delete a record in Table B i.e aid1 and simultaneously with delete cascade all three records in TABLE A should be deleted. My doubt here is where should I put the delete cascade constraint. I know that in parent child relationship we need to put delete cascade on the child table so that when parent is deleted, child entities are also deleted but in this scenario I dont understand where I should put delete cascade
Cascading a table will be on the child table. You have to set this on your child table when creating or after creating the child table.
E.g
CREATE TABLE schools (
id int auto_increment primary key not null,
schoolname varchar(191) not null
);
CREATE TABLE students(
id int auto_increment primary key not null,
studentname varchar(191) not null,
school_id int FOREIGN KEY REFERENCES students(id) ONDELETE CASCADE
);
or
You can as well alter the table by running this command.
ALTER TABLE childTable
ADD FOREIGN KEY (childTableParentTableColumn) REFERENCES parentTable(parentTableColumn);

oracle sql - on delete cascade in both directions

I have table A and table B, where the primary key of table B references the primary key of table A. If i use on delete cascade on table B how can i ensure that rows of table A are deleted when i delete a row in table B?
Edit:
Merging is unfortunately not the solution to my problem.
In my database i have three tables that are relevant for this situation.
This is what it looks like:
CREATE TABLE TABLE_A
(
TABLE_A_ID INTEGER NOT NULL,
...
PRIMARY KEY(TABLE_A_ID)
);
CREATE TABLE TABLE_B
(
TABLE_B_ID INTEGER REFERENCES TABLE_A(TABLE_A_ID) ON DELETE CASCADE,
...
PRIMARY KEY(TABLE_B_ID)
);
CREATE TABLE TABLE_C
(
TABLE_C_ID INTEGER REFERENCES TABLE_A(TABLE_A_ID) ON DELETE CASCADE,
...
PRIMARY KEY(TABLE_C_ID)
);
Although it is possible to create rows in A on its own i dont want any rows that are only in A.
Now if I delete a row in B, I want the row in A with the same ID deleted too. I dont want any ID that is only in A, or only not in A.

SQL: composite primary key, constraint on cascade

I have 3 tables: A, B, C.
The table A contains the attributes: a (primary key)
The table B contains the attributes: a, c (both of them compose a composite primary key)
The table C contains the attributes: c (primary key)
How should I set a constraint to remove the elements of B on cascade, when I remove an entry in A? (using Oracle DBMS).
I have tried this:
ALTER TABLE A ADD CONSTRAINT constraint FOREIGN KEY (a) REFERENCES B (a) ON DELETE CASCADE
But next error is thrown:
ORA-02270: no matching unique or primary key for this column-list
Thanks
Edited:
I´ve added two foreign keys to the table B:
ALTER TABLE B ADD CONSTRAINT FOREIGN KEY (a) REFERENCES A (a) ON DELETE CASCADE
ALTER TABLE B ADD CONSTRAINT FOREIGN KEY (c) REFERENCES C (c) ON DELETE CASCADE
Then, I will remove elements in table B, and the entries in A and C are also removed.
To meet this requirement:
Then, I will remove elements in table B, and the entries in A and C are also removed.
You need to make the B table a parent table for tables A and C by a adding foreign key constraint, that references B table to A and C tables.
Note that the number of referencing columns have to match the number of referenced columns:
create table A(
tab_id number primary key
);
create table B(
col1 number,
col2 number,
constraint PK_Key primary key(col1, col2)
);
create table C(
tab_id number primary key
);
alter table A add ( col1 number
, col2 number
, constraint fk_AB foreign key(col1, col2)
references B(col1, col2) on delete cascade);
alter table C add ( col1 number
, col2 number
, constraint fk_CB foreign key(col1, col2)
references B(col1, col2) on delete cascade);
This is a bit of a guess, but I am assuming table B is a child of of both A and C (perhaps B is a bridging (or cross-reference) table between A and C, where A and C share a many to many relationship).
Table A \*---1 Table B 1---\* Table C (* = many, 1 = one)
I also notice that the FK you are introducing in an identifying FK (by virtue of B(a) being a part of B's primary key).
That makes Table A the parent in this relationship, and B the child. In my experience, any FKs need to be added to the child side of the relationship (in this case, table B).
I'm no Oracle expert, but does this not make more sense?...
ALTER TABLE B ADD CONSTRAINT constraint FOREIGN KEY (a) REFERENCES A (a) ON DELETE CASCADE
This should remove all B rows referring to the PK of any A rows you choose to remove. BUT, I'm not an Oracle expert, so take only at face value until someone with Oracle smarts can confirm (or bomb) my explanation.

Enforcing unique rows in a many-to-many junction table

I have a junction table for a many-to-many relationship that just links two foreign keys together. However I've found that this will not prevent duplicate identical row entries. What's the proper way of handling that? I thought adding PRIMARY KEY to the two foreign keys would do it, but it seems like I'm not understanding that correctly.
CREATE TABLE ab_link (
a_id bigint REFERENCES a(a_id) PRIMARY KEY,
b_id bigint REFERENCES b(b_id) PRIMARY KEY
);
I found on another question this example:
CREATE TABLE bill_product (
bill_id int REFERENCES bill (bill_id) ON UPDATE CASCADE ON DELETE CASCADE
, product_id int REFERENCES product (product_id) ON UPDATE CASCADE
, amount numeric NOT NULL DEFAULT 1
, CONSTRAINT bill_product_pkey PRIMARY KEY (bill_id, product_id) -- explicit pk
);
Is that constraint the best way of enforcing uniqueness? I would think there would be some way of doing it without having a third row.
For a compound primary key, you need a separate declaration:
CREATE TABLE ab_link (
a_id bigint REFERENCES a(a_id),
b_id bigint REFERENCES b(b_id),
PRIMARY KEY (a_id, b_id)
);