I have a child table. and foreign key there with ON DELETE CASCADE while creating the table.
There are no records either in child or parent table.
I want the primary key, foreign key to be as they are but want to remove only the CASCADING option from the child table .
is there anyway that i can Alter that child table.
Thank you.
The table:
SHOW CREATE TABLE table;
CREATE TABLE `table` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`id_departamento` int(11) unsigned DEFAULT NULL,
`name` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `id_departamento` (`id_departamento`),
CONSTRAINT `departamentos_direcciones_pedidos_ibfk_1` FOREIGN KEY (`id_departamento`) REFERENCES `departamentos` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
First drop foreign key.
ALTER TABLE departamentos_direcciones_pedidos DROP CONSTRAINT departamentos_direcciones_pedidos_ibfk_1;
Second, create the correct foreign key
ALTER TABLE departamentos_direcciones_pedidos ADD FOREIGN KEY (id_departamento) REFERENCES departamentos(id);
ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
The default is NO ACTION.
So try altering your child table back to default.
(Oracle) You can only alter the state of a constraint. ON DELETE is not a state. So you need to drop constraint and recreate it.
drop table t1 cascade constraints;
create table t1 (id number unique, rid number constraint t1_fk references t1(id) on delete cascade);
alter table t1 drop constraint t1_fk;
alter table t1 add constraint t1_fk foreign key(rid) references t1(id);
if you're using Oracle there are different dictionary views which might help you to recreate the constraint correctly
Export the database as a .sql file
Then press ctrl + H to replace all ON DELETE CASCADE with ""
Then drop the tables from the DB and use the new file to instantiate a new one without ON DELETE CASCADE
Related
I get error 1452 when updating a row in a parent table when running mariaDB 10.5.8. The tables are defined as follows:
> SHOW CREATE TABLE files;
files CREATE TABLE `files` (
`file_path` varchar(255) NOT NULL,
`md5` text NOT NULL,
`size` int(11) NOT NULL,
PRIMARY KEY (`file_path`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
> SHOW CREATE TABLE headlines;
headlines CREATE TABLE `headlines` (
`file_path` varchar(255) NOT NULL,
`headline_offset` int(11) NOT NULL,
-- other columns
PRIMARY KEY (`file_path`,`headline_offset`),
CONSTRAINT `headlines_ibfk_1` FOREIGN KEY (`file_path`) REFERENCES `files` (`file_path`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
> SHOW CREATE TABLE headline_closures;
headline_closures CREATE TABLE `headline_closures` (
`file_path` varchar(255) NOT NULL,
`headline_offset` int(11) NOT NULL,
`parent_offset` int(11) NOT NULL,
`depth` int(11) DEFAULT NULL,
PRIMARY KEY (`file_path`,`headline_offset`,`parent_offset`),
KEY `file_path` (`file_path`,`parent_offset`),
CONSTRAINT `headline_closures_ibfk_1` FOREIGN KEY (`file_path`, `headline_offset`) REFERENCES `headlines` (`file_path`, `headline_offset`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `headline_closures_ibfk_2` FOREIGN KEY (`file_path`, `parent_offset`) REFERENCES `headlines` (`file_path`, `headline_offset`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
The contents of the database (minimal example):
> SELECT * FROM files;
/path/to/foo1.org 106e9f12c9e4ff3333425115d148fbd4 6
> SELECT * FROM headlines;
/path/to/foo1.org 1 --other columns
> SELECT * FROM headline_closures;
/path/to/foo1.org 1 1 0
Executing the following produces the error (expected behavior is that the file path changes for all tables per the CASCADE clauses):
> UPDATE files SET file_path='/path/to/foo2.org' WHERE md5='106e9f12c9e4ff3333425115d148fbd4';
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`org_sql`.`headline_closures`, CONSTRAINT `headline_closures_ibfk_2` FOREIGN KEY (`file_path`, `parent_offset`) REFERENCES `headlines` (`file_path`, `headline_offset`))
Things I've tried (per MySQL cascade update failed when foreign key column referenced in composite primary key)
Removing the second ON DELETE CASCADE ON UPDATE CASCADE from the headline_closures table (same error)
Dropping the primary key from the headline_closures table and that produced error 150 (Foreign key constraint is incorrectly formed)
I thought (1) would work because the docs state to not have multiple CASCADEs that could change a single column; I'm not sure why (2) would work. What am I not getting here?
Also, if someone could explain why this same arrangement works for SQLite and postgreSQL that would be appreciated since I don't get the same error with those ;)
Edit 1
This same behavior happens with MySQL 8.0.22 (so not just a mariaDB error, not too surprising)
I don't get the error if I take away one of the foreign keys in headline_closures (so there is still one constraint that has ON UPDATE CASCADE)
If I remove the ON UPDATE CASCADE from headline_closures_ibfk_1 instead of headline_closures_ibfk_2, the error then complains about headline_closures_ibfk_1 (where it complained about headline_closures_ibfk_2 when I took the CASCADEs away from headline_closures_ibfk_2 or if I left them on both) so it seem that the error is due to updating the parent, having the cascade propagate to the headline_closures table where the second constraint doesn't see the update and therefore complains (or something)
Edit 2:
DELETE FROM files WHERE md5='106e9f12c9e4ff3333425115d148fbd4'; works as intended with the constraints as written above (no error and the the deletion propagates to all child tables).
Here how I created tables:
CREATE TABLE TABLE_A(
id uuid NOT NULL, UNIQUE
name text
);
CREATE TABLE TABLE_B(
id uuid NOT NULL, UNIQUE
name text
);
-- custom realization of many-to-many association
CREATE TABLE TABLE_A_B(
id uuid NOT NULL, UNIQUE
a_id uuid REFERENCES TABLE_A(id) ON UPDATE CASCADE,
B_id uuid REFERENCES TABLE_B(id) ON UPDATE CASCADE
);
I've already created tables and now can't update it by adding ON DELETE CASCADE.
And I need now to add ON DELETE CASCADE to staging table TABLE_A_B. How to do it ?(
You use ON DELETE CASCADE:
CREATE TABLE TABLE_A_B(
id uuid NOT NULL UNIQUE,
a_id uuid REFERENCES TABLE_A(id) ON UPDATE CASCADE ON DELETE CASCADE,
B_id uuid REFERENCES TABLE_B(id) ON UPDATE CASCADE ON DELETE CASCADE
);
Here is a db<>fiddle that fixed some typos in your code.
In particular, the foreign key reference should be to a primary key. Although allowed to a unique key, the purpose of primary keys is really to identify individual rows -- and one main use is for foreign key references.
EDIT:
If the constraints already exist, then do the following.
First, get their names:
select *
from information_schema.table_constraints
where constraint_type = 'FOREIGN KEY' and table_name = 'table_a_b';
Note: You can assign names to skip this step.
Then drop the existing foreign key constraint:
alter table table_a_b
drop constraint table_a_b_a_id_fkey;
Finally, add a new one:
alter table table_a_b
add constraint fk_table_a_b_a
foreign key (a_id) references table_a(id)
on update cascade
on delete cascade;
I built a big database with many tables. After that I forgat to add "delete on cascade". How do I add the "delete on casade" on the specific columns I want ?
For example:
create table Users
(
ID char(9) primary key check (ID like replicate('[0-9]',9)),
firstName nvarchar(20) not null,
)
And
create table Applications
(
name nvarchar(20) primary key,
establishDate date not null
)
How do I alter this table-registered to, so that when I delete an app or users it deletes the rows that has this value?
create table RegisteredTo
(
userID char(9) references Users(ID),
ApplicationName nvarchar(20) references Applications(name),
primary key(userID, ApplicationName)
)
I tried something like that - but I got errors.
alter table RegisteredTo
ALTER COLUMN applicationName references Applications(name) ON DELETE CASCADE
nvarchar(20)
You need to add a FOREIGN CONSTRAINT and ON DELETE CASCADE:
ALTER TABLE RegisteredTo
ADD CONSTRAINT FK_RegisteredTo_Users FOREIGN KEY (userID) REFERENCES Users(ID) ON DELETE CASCADE;
ALTER TABLE RegisteredTo
ADD CONSTRAINT FK_RegisteredTo_Applications FOREIGN KEY (ApplicationName) REFERENCES Applications(name) ON DELETE CASCADE;
I have a simple table like below.
create table chemlab.rule_header (
id serial PRIMARY KEY,
name varchar(50),
grade varchar(20),
class_tag varchar(20), --tag added to sammple if match
parent_id int REFERENCES chemlab.rule_header(id) DEFAULT NULL,
unique( grade, class_tag )
)
But afterwards, I found that I need to add ON DELETE action, the default is NO ACTION. I couldn't figure out how to change the action.
Now I have to DROP & ADD
ALTER table chemlab.rule_header
DROP CONSTRAINT rule_header_parent_id_fkey ;
ALTER TABLE rule_header
ADD CONSTRAINT rule_header_parent_id_fkey
FOREIGN KEY (parent_id) REFERENCES chemlab.rule_header(id) ON DELETE RESTRICT;
So what is the correct syntax to alter an action on foreign key constraint ?
Well, this not directly altering FOREIGN KEY constraint, and there are DROP and ADD still, though this is only one statement:
ALTER table chemlab.rule_header
DROP CONSTRAINT rule_header_parent_id_fkey,
ADD CONSTRAINT rule_header_parent_id_fkey
FOREIGN KEY (parent_id) REFERENCES chemlab.rule_header(id) ON DELETE RESTRICT;
Take a look at the documentation at https://www.postgresql.org/docs/current/sql-altertable.html. There are options to alter a few things about a constraint (like DEFERRABLE) but not for changing the action, as I understand you need.
I need to change order of rows in database table.
My table has 4 columns and 7 rows. I need to reorder these rows
pk_i_id int(10) unsigned Auto Increment
s_name varchar(255) NULL
s_heading varchar(255) NULL
s_order_type varchar(10) NULL
In Adminer, when I've changed pk_i_id value(number) something else, I'm getting this error...
Cannot delete or update a parent row: a foreign key constraint fails (`database_name`.`oc_t_item_custom_attr_categories`, CONSTRAINT `oc_t_item_custom_attr_categories_ibfk_1` FOREIGN KEY (`fk_i_group_id`) REFERENCES `oc_t_item_custom_attr_groups` (`pk_i_id`))
Do you know how to change it ? Thank you
Edit
oc_t_item_custom_attr_categories
fk_i_group_id int(10) unsigned
fk_i_category_id int(10) unsigned
indexes
PRIMARY fk_i_group_id, fk_i_category_id
INDEX fk_i_category_id
foregin keys
fk_i_group_id oc_t_item_custom_attr_groups_2(pk_i_id) RESTRICT RESTRICT
fk_i_category_id oc_t_category(pk_i_id) RESTRICT RESTRICT
You need to change your foreign key on table database_name.oc_t_item_custom_attr_categories so that it updates along with column it references.
ALTER TABLE database_name.oc_t_item_custom_attr_categories DROP CONSTRAINT oc_t_item_custom_attr_categories_ibfk_1;
ALTER TABLE database_name.oc_t_item_custom_attr_categories
ADD CONSTRAINT oc_t_item_custom_attr_categories_ibfk_1 FOREIGN KEY (fk_i_group_id)
REFERENCES oc_t_item_custom_attr_groups (pk_i_id)
ON UPDATE CASCADE;
Since MariaDB seem to not support ADDING foreign keys after table creation, this is how it should work for you, assuming description of tables is correct:
RENAME TABLE oc_t_item_custom_attr_categories TO oc_t_item_custom_attr_categories_2;
CREATE TABLE oc_t_item_custom_attr_categories (
fk_i_group_id int(10) unsigned,
fk_i_category_id int(10) unsigned,
PRIMARY KEY(fk_i_group_id, fk_i_category_id),
INDEX (fk_i_category_id),
CONSTRAINT `oc_t_item_custom_attr_categories_ibfk_1` FOREIGN KEY (fk_i_group_id)
REFERENCES oc_t_item_custom_attr_groups (pk_i_id)
ON UPDATE CASCADE,
CONSTRAINT `oc_t_item_custom_attr_categories_ibfk_2` FOREIGN KEY (fk_i_category_id)
REFERENCES oc_t_category (pk_i_id)
) ENGINE = XtraDB; --change engine to what you are using
INSERT INTO oc_t_item_custom_attr_categories SELECT * FROM oc_t_item_custom_attr_categories_2;
How it works on example data in MySQL database: http://rextester.com/ZAKR50399