MySQL cascade hard delete child row on soft delete of parent row without using a trigger: is this possible? - mysql

I'm using MySQL version 5.6.47-87.0
I have a parent table named parentTable and a child table named childTable, here's the scripts to create those tables:
CREATE TABLE `parentTable` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`customerId` int(10) unsigned NOT NULL,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=251046 DEFAULT CHARSET=utf8;
CREATE TABLE `childTable` (
`parentId` int(10) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`description` text
PRIMARY KEY (`parentId`),
CONSTRAINT `childtable_parentid_foreign` FOREIGN KEY (`parentId`) REFERENCES `parentTable` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
As is the child record in childTable is hard deleted when the corresponding record in the parentTable is hard deleted.
Without using a trigger, is it possible to set this up so the record in childTable is hard deleted when the corresponding record in parentTable is soft deleted (IE: when the parentTable.deleted column is updated with a value so is it no longer NULL)?

Related

On Cascade Delete does not seem to be applying in my DB

I don't know what I am doing wrong as I've been looking at previous answers on this site concerning ON CASCADE DELETE.
Basically this is my table:
CREATE TABLE `directorycolumntags` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`directorycolumn_id` INT(11) NOT NULL,
`tag_id` INT(11) NOT NULL,
`description` TEXT,
`created` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`directorycolumn_id`) REFERENCES directorycolumn(id),
CONSTRAINT FOREIGN KEY (`tag_id`) REFERENCES tag(id)
ON DELETE CASCADE
) ENGINE=MYISAM AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
The Foreign key references the id of the tag table:
CREATE TABLE `tag` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) DEFAULT NULL,
`description` TEXT,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
Now, If I perform this query to INSERT some data into the directorycolumntags table it works:
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,32);
However, when I DELETE the entry from the tag table with the id of 32 it does not remove the row from the directorycolumntags table. Can anyone point out where I am going wrong?
It's because your table directorycolumntags is MYISAM, not INNODB. MyISAM doesn't support foreign keys. You can write your foreign key statements, but MySQL silently ignores them.
Try this:
ALTER TABLE `directorycolumntags` ENGINE = 'InnoDB';

Use some kind of inheritance with database tables

Is it possible (and how can I achieve it) to get some kind of inheritance with database tables?
I intend to have a parent table X
CREATE TABLE `X` (
`xId` int(11) NOT NULL AUTO_INCREMENT,
`addressId` int(11) NOT NULL,
`poiType` enum('ParkingPOI','ChargingPOI') NOT NULL,
`status` enum('AVAILABLE','NOT_AVAILABLE') NOT NULL
PRIMARY KEY (`aId`),
KEY `fk_x_address_idx` (`addressId`),
CONSTRAINT `fk_address` FOREIGN KEY (`addressId`) REFERENCES `addresses` (`addressId`)
ON DELETE NO ACTION ON UPDATE CASCADE) ENGINE=InnoDB AUTO_INCREMENT=217 DEFAULT CHARSET=utf8;
and a child table B
CREATE TABLE `B` (
`bId` int(11) NOT NULL AUTO_INCREMENT,
`xId` int(11) NOT NULL',
`status` enum('AVAILABLE','NOT_AVAILABLE','PARTLY_AVAILABLE') NOT NULL
PRIMARY KEY (`bId`),
KEY `aId` (`xId`),
CONSTRAINT `fk_a` FOREIGN KEY (`xId`) REFERENCES `X` (`xId`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
In table X I want to have something like an ENUM with values being inherited from the child table, for instance: AVAILABLE, NOT_AVAILABLE. In this table/column of the parent table (X) only these values shall be allowed.
In the child table, however, this ENUM should be extendend so that the values AVAILABE, NOT_AVAILABLE, PARTLY_AVAILABLE shall be possible.
How can I achieve this?

mysql - foreign key cascade update

I have a question about how to update a field on cascade with a second field as constraint.
The structure is this (I removed the unnecessary columns):
Table nodes with columns idNode and idDimension (together they form the primary key).
Table forces with columns idForce (PK), idNode (foreign key to nodes.idNode) and idDimension.
Cascade update and delete on everything.
The problem in this structure that it seems to appear is this:
If in nodes I have an entry like (1, 1) and one like (1, 2) and in forces (1, 1, 1) and (1, 1, 2) and I update or delete first entry from nodes both entries in forces will be affected.
I need to affect only the one that also has the corresponding idDimension. How can I modify current structure to do that?
Edit: Tables - Nodes:
CREATE TABLE IF NOT EXISTS `nodes` (
`idNode` varchar(11) NOT NULL,
`idDimension` int(10) unsigned NOT NULL,
`idNetwork` int(10) unsigned NOT NULL DEFAULT '0',
`level` int(11) unsigned NOT NULL DEFAULT '0',
`energy` bigint(20) DEFAULT NULL,
`resources` bigint(20) unsigned NOT NULL DEFAULT '0',
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`name` varchar(20) DEFAULT NULL,
`order` tinyint(3) DEFAULT '0' COMMENT 'energy 0\nassemble 1\nupgrade 2',
`core` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`idNode`,`idDimension`),
KEY `network_dimension` (`idDimension`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Node table';
Forces:
CREATE TABLE IF NOT EXISTS `forces` (
`idForce` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`idNode` varchar(11) NOT NULL,
`idDimension` int(10) unsigned NOT NULL,
`drones` bigint(20) DEFAULT NULL,
`stance` tinyint(3) DEFAULT NULL COMMENT '0 - defense\n1 - neutral\n2 - attack \n\nIf planet is parano and you are not allied to owner you can only be in attack.\n\nIf owner is allied you can only be in defense or neutral.\n\nIf you are owner you can only be in defense.',
`order` tinyint(3) DEFAULT '0' COMMENT 'extract energy 1\nbuild node 2\nreplicate 3\nmove 4',
`value` text,
PRIMARY KEY (`idForce`),
KEY `idNode` (`idNode`,`idDimension`),
KEY `idDimension` (`idDimension`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
--
-- Constraints for table forces
ALTER TABLE `forces`
ADD CONSTRAINT `forces_ibfk_2` FOREIGN KEY (`idDimension`) REFERENCES `nodes` (`idDimension`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_forces_nodes1` FOREIGN KEY (`idNode`, `idDimension`) REFERENCES `nodes` (`idNode`, `idDimension`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `forces_ibfk_1` FOREIGN KEY (`idNode`) REFERENCES `nodes` (`idNode`) ON DELETE CASCADE ON UPDATE CASCADE;
My constraints are not working as I would like so feel free to ignore them :).
There are two strange foreign key (forces_ibfk_1 and forces_ibfk_2) which refers to non unique fields. Remove them -
ALTER TABLE forces DROP FOREIGN KEY forces_ibfk_1;
ALTER TABLE forces DROP FOREIGN KEY forces_ibfk_2;
Then recreate fk_forces_nodes1 that refers to unique pair of fields with CASCADE action option -
ALTER TABLE forces
DROP FOREIGN KEY fk_forces_nodes1;
ALTER TABLE orces
ADD CONSTRAINT fk_forces_nodes1 FOREIGN KEY (idNode, idDimension)
REFERENCES nodes(idNode, idDimension) ON DELETE CASCADE ON UPDATE CASCADE;

Change master table PK and update related table FK (changing PK from Autoincrement to UUID on Mysql)

I have two related tables: Groups and Clients. Clients belongs to Groups so I have a foreign key "group_id" that references the group a client belongs to.
I'm changing the Group id from an autoincrement to a UUID. So what I need is to generate a UUID for each Group and update the Clients table at once to reflect the changes and keep the records related.
Is there a way to do this with multiple-table update on MySQL?
Adding tables definitions for clarification.
CREATE TABLE `groups` (
`id` char(36) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
CREATE TABLE `clients` (
`id` char(36) NOT NULL,
`name` varchar(255) NOT NULL,
`group_id` char(36) DEFAULT NULL,
`active` tinyint(1) DEFAULT '1'
PRIMARY KEY (`id`),
KEY `fkgp` (`group_id`),
CONSTRAINT `fkgp` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`)
ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

MYSQL: Cannot add or update a child row: a foreign key constraint fails

I am getting the error:
Cannot add or update a child row: a foreign key constraint fails (mydb/requests, CONSTRAINT requests_ibfk_5 FOREIGN KEY (fixture_id) REFERENCES fixtures (fix_id) ON UPDATE CASCADE ON DELETE CASCADE)
I have the following table structure:
CREATE TABLE IF NOT EXISTS `requests` (
`request_id` int(11) unsigned NOT NULL auto_increment,
`fixture_id` int(11) unsigned NOT NULL,
`user_id` int(11) unsigned NOT NULL,
`date_added` datetime NOT NULL,
`date_modified` datetime default NULL,
PRIMARY KEY (`request_id`),
UNIQUE KEY `fixture_id_2` (`fixture_id`,`user_id`),
KEY `user_id` (`user_id`),
KEY `date_added` (`date_added`),
KEY `fixture_id` (`fixture_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=17 ;
CREATE TABLE IF NOT EXISTS `fixtures` (
`id` int(11) unsigned NOT NULL auto_increment,
`fix_id` int(11) unsigned NOT NULL default '0',
`fixture_date` date default NULL,
`kickoff` time default NULL,
`venue` varchar(35) default NULL,
`home_score` tinyint(4) default NULL,
`away_score` tinyint(4) default NULL,
`date_added` datetime default NULL,
`date_modified` datetime default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `fix_id` (`fix_id`),
KEY `fixture_date` (`fixture_date`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=383 ;
ALTER TABLE `requests`
ADD CONSTRAINT `requests_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE,
ADD CONSTRAINT `requests_ibfk_5` FOREIGN KEY (`fixture_id`) REFERENCES `fixtures` (`fix_id`) ON DELETE CASCADE ON UPDATE CASCADE;
If I update a record on the fix_id field the parent table (fixtures), that has a shared id (fixture_id) in the child table (requests) I get the above error.
I cannot see why this integrity constraint is failing. Both tables already have the correct data it should cascade through?
Any help greatly appreciated.
This was all my own error. I had two foreign constraints on the same field in reality. I just needed to take one off.
This error occurs due to the reference of other table, in both tables same id's/data should exist. If not please use where conditions to remove not existing data.
example
update tablename a set = 'field' (select field from othertable b) where a.data = b.data;