条件 table 更新
Conditional table updates
考虑以下 table。
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
其中:
Id, INT (11) PRIMARY
responseA, TEXT utf8_unicode_ci
responseB, TEXT utf8_unicode_ci
假设我想有条件地用一些外部数据更新table。条件是:
• 如果 responseA
中没有任何内容,则用外部数据填充它,否则
• 如果 是 responseA
中的某些内容,请保持原样,并填充 responseB
与外部数据
我非常确信我可以通过这样做来获得我想要的东西:
UPDATE myTable
SET
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA)),
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB))
WHERE Id = 1
但是,这会将 responseA
和 responseB
更新为相同的值 - foo
,从而使 table:
myTable
+----+-----------+-----------+
| Id | responseA | responseB |
+----+-----------+-----------+
| 1 | foo | foo |
+----+-----------+-----------+
我希望我的 table 在更新后看起来像这样:
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | foo | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
我误解了什么,我怎样才能实现这个条件更新?更新是按顺序发生的吗?如果是这样,我想这可以解释为什么这两个字段都被更新了。
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
;
responseA 的值似乎在评估 responseB 的 IF()
之前发生了变化。
一个可能的解决方案是进行简单的更新:
UPDATE mytable SET responseA = ? WHERE id = 1
然后调整触发器中的列,您可以在其中访问列的原始值和新值:
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
(我没有测试过这个。)
我还假设您对 ''
(空字符串)而不是 NULL 的测试是故意的,并且您知道 NULL 与 ''
.
不同
UPDATE
语句中的关键点是您应该首先更新列 responseB
,以便列 responseA
保留其原始值,您可以在尝试时再次检查更新它:
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;
此处是您更改后的查询
UPDATE myTable
SET
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB)),
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA))
WHERE Id = 1
考虑以下 table。
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
其中:
Id, INT (11) PRIMARY
responseA, TEXT utf8_unicode_ci
responseB, TEXT utf8_unicode_ci
假设我想有条件地用一些外部数据更新table。条件是:
• 如果 responseA
中没有任何内容,则用外部数据填充它,否则
• 如果 是 responseA
中的某些内容,请保持原样,并填充 responseB
与外部数据
我非常确信我可以通过这样做来获得我想要的东西:
UPDATE myTable
SET
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA)),
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB))
WHERE Id = 1
但是,这会将 responseA
和 responseB
更新为相同的值 - foo
,从而使 table:
myTable
+----+-----------+-----------+
| Id | responseA | responseB |
+----+-----------+-----------+
| 1 | foo | foo |
+----+-----------+-----------+
我希望我的 table 在更新后看起来像这样:
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | foo | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
我误解了什么,我怎样才能实现这个条件更新?更新是按顺序发生的吗?如果是这样,我想这可以解释为什么这两个字段都被更新了。
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
;
responseA 的值似乎在评估 responseB 的 IF()
之前发生了变化。
一个可能的解决方案是进行简单的更新:
UPDATE mytable SET responseA = ? WHERE id = 1
然后调整触发器中的列,您可以在其中访问列的原始值和新值:
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
(我没有测试过这个。)
我还假设您对 ''
(空字符串)而不是 NULL 的测试是故意的,并且您知道 NULL 与 ''
.
UPDATE
语句中的关键点是您应该首先更新列 responseB
,以便列 responseA
保留其原始值,您可以在尝试时再次检查更新它:
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;
此处是您更改后的查询
UPDATE myTable
SET
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB)),
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA))
WHERE Id = 1