Consider the following table.
myTable
---- ----------- ------------------------------------
| Id | responseA | responseB |
---- ----------- ------------------------------------
| 1 | | {"foo":"bar","lvl2":{"key":"val"}} |
---- ----------- ------------------------------------
where:
Id, INT (11) PRIMARY
responseA, TEXT utf8_unicode_ci
responseB, TEXT utf8_unicode_ci
Let's say that I want to conditionally update the table with some outside data. The conditions are:
• if there's nothing in responseA
, populate it with the outside data, otherwise
• if there is something in responseA
, leave it as it is, and populate responseB
with the outside data
I was pretty much convinced that I could just do this to get what I want:
UPDATE myTable
SET
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA)),
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB))
WHERE Id = 1
However, this updates both responseA
and responseB
to the same value - foo
, making the table:
myTable
---- ----------- -----------
| Id | responseA | responseB |
---- ----------- -----------
| 1 | foo | foo |
---- ----------- -----------
I was expecting my table to look like this after the update:
myTable
---- ----------- ------------------------------------
| Id | responseA | responseB |
---- ----------- ------------------------------------
| 1 | foo | {"foo":"bar","lvl2":{"key":"val"}} |
---- ----------- ------------------------------------
What am I misunderstanding, and how can I achieve this conditional update? Do the updates happen sequentially? If so, I guess that would explain why both of the fields are updated.
CodePudding user response:
UPDATE TABLE
SET responseA = CASE WHEN responseA IS NULL
THEN @data
ELSE responseA
END,
responseB = CASE WHEN responseA IS NULL
THEN responseB
ELSE @data
END
;
CodePudding user response:
It seems the value of responseA is changed before the IF()
for responseB is evaluated.
One possible solution is to do a simple UPDATE:
UPDATE mytable SET responseA = ? WHERE id = 1
Then adjust the columns in a trigger, where you have access to both the original and the new value of the columns:
CREATE TRIGGER t BEFORE UPDATE ON mytable
FOR EACH ROW BEGIN
IF TRIM(OLD.responseA) != '' THEN
SET NEW.responseB = NEW.responseA;
SET NEW.responseA = OLD.responseA;
END IF;
END
(I have not tested this.)
I am also assuming that your test for ''
(empty string) instead of NULL is deliberate, and that you know that NULL is not the same as ''
.
CodePudding user response:
The key point in the UPDATE
statement is that you should update first the column responseB
, so that column responseA
retains its original value which can be checked again when you try to update it:
UPDATE myTable
SET responseB = CASE WHEN TRIM(responseA) = '' THEN responseB ELSE 'foo' END,
responseA = CASE WHEN TRIM(responseA) = '' THEN 'foo' ELSE responseA END
WHERE Id = 1;
CodePudding user response:
here your changed query
UPDATE myTable
SET
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB)),
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA))
WHERE Id = 1