Reputation: 9583
Is it possible to use foreign key constrains to prevent update of parent row when the index is in use by a child row?
Here is the schema of the parent table:
create table if not exists incident_options (
id int not null auto_increment primary key,
idx int not null,
field int not null ,
value varchar(50));
ALTER TABLE `incident_options` ADD unique (`idx`, field);
And the child table:
create table if not exists incident_values (
optn int,
value varchar(1000));
ALTER TABLE `incident_values` ADD INDEX (`optn`);
Here is the constraint that I have tried:
ALTER TABLE `incident_values`
ADD FOREIGN KEY (`optn`) REFERENCES `incident_options`(`id`)
ON DELETE NO ACTION ON UPDATE RESTRICT;
Supposing I have the the following data:
incident_options
__________________________
|id | idx | field | value |
| 1 | 0 | 1 | foo |
| 2 | 1 | 1 | bar |
--------------------------
incident_values
______________
| optn | value |
| 1 | baz |
--------------
What I'm trying to achieve is to prevent 'foo' from being updated because the row is in use in incident_values
To update 'bar' would be fine
Here is the query I'm using to modify the row:
insert into incident_options (`idx`,`field`,`value`)
values ('0','1','test')
on duplicate key update
`idx` = values(`idx`),
`field` = values(`field`),
`value` = values(`value`)
At present 'foo' will be updated to 'test'
Upvotes: 0
Views: 552
Reputation: 9583
With a bit of hackery I did actually achieve what I wanted.
By forcing an increment of 'id' when 'value' has changed, the update of 'id' will not be permitted if there is a relationship
on duplicate key update
idx = values(idx),
field = values(field),
id = if(
values(`value`)=`value`,
id,
(SELECT Auto_increment FROM information_schema.tables WHERE table_name='incident_options')
),
values= values(value)
Though I'll see if there is any advice against using this solution before implementing it in my application
Upvotes: 1
Reputation: 16691
The problem is that you've set the constraint on the wrong table. You have put ON UPDATE RESTRICT
on the incident_values
table, but when you are doing the insert and update this is all happening on incident_options
.
Unfortunately, you can't set this constraint inside the incident_options
table because you may not always have a reference back to the incident_values
table, so I do not think this is possible using a constraint. As Barmar mentioned in the comments, you may be able to implement a trigger in some way to preform verification before updating a field.
Upvotes: 1