I am working on a trigger that I though is quite easy and should work but it is not working.
Here is the (abstract) table structure:
PK_id | FK1_id | FK2_id | status
1 | 12 | 15 | 'ok'
status
column is defined as enum('ok', 'ok_2', 'not_ok') NUT NULL
with no default value.
The trigger should verify that a combination of both FKx_id
values already exists and if yes it should set the status
to 'ok_2', otherwise to 'ok' and if the status
is set in the INSERT INTO
it is not touched.
The trigger I have right now (only body!):
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt > 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
Unfortunately this trigger sets the status
always to 'ok'
- please notice that the status
is not part of the INSERT
query (thus considered as NULL
). I have previously tried this trigger body with the same result:
BEGIN
IF (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id) > 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
and also this (with the very same result):
BEGIN
IF EXISTS(SELECT * FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id LIMIT 1) AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
Can anyone tell me why the first condition is never met even if I am inserting the same FKx_id
combination that is already present in the table?
EDIT : I switched the condition and the result is also the same - no 'ok_2' status set:
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt = 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
END IF;
END
Got it.
The problem was this declaration of the status
column:
status enum('ok', 'ok_2', 'not_ok') NOT NULL
which leads into status
being pre-filled with the first enum's value if the status
is not set in the INSERT
statement. So the solution is next trigger body:
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt = 0 THEN
SET NEW.status = 'ok';
ELSEIF NEW.status = 'ok' THEN
SET NEW.status = 'ok_2';
END IF;
END
Now if I do this insert for the first time
INSERT INTO table (FK_1, FK_2) VALUES (100, 150)
the status is 'ok'
, if I insert this for the second time
INSERT INTO table (FK_1, FK_2) VALUES (100, 150)
the status is 'ok_2'
and if I set the status explicitly like this:
INSERT INTO table (FK_1, FK_2, status) VALUES (100, 150, 'not_ok')
the status is 'not_ok'
.
so, when working with enums that have no default value while are set as NOT NULL
- do not expect them to be NULL on insert when omitted. The will be pre-filled probably with the first enums's value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.