我有以下UPDATE语句
UPDATE PAYMENT_HISTORY
SET request_status_id =
CASE
WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN NULL
ELSE PHP.request_status_id
END,
is_changed =
CASE
WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN 0
ELSE 1
END
是否可以使用单个case语句更新两列?
答案 0 :(得分:2)
是否可以使用单个case语句更新两列?
没有。 CASE
表达式具有单个原子值。单个CASE
表达式不能包含两个字段的值。您只能使用request_status_id
来同时设置is_changed
和CASE ... END
。
可以在同一UPDATE
语句中更新这两个字段,但不能更新CASE
表达式。
但是,您的表达式不有问题,而且此处的分配不会相互衔接。语句开始执行时,锁定的数据将被锁定。它使用在语句运行之前存在的表。
考虑:
CREATE TABLE TestTable (
Odd TINYINT NOT NULL,
Even TINYINT NOT NULL,
PRIMARY KEY (Odd, Even)
);
INSERT INTO TestTable (Odd, Even) VALUES (1, 2);
INSERT INTO TestTable (Odd, Even) VALUES (3, 4);
INSERT INTO TestTable (Odd, Even) VALUES (5, 6);
INSERT INTO TestTable (Odd, Even) VALUES (7, 8);
SELECT * FROM TestTable;
UPDATE TestTable SET Odd = Even, Even = Odd;
SELECT * FROM TestTable;
除非你做的事情像递归CTE一样奇怪,否则数据几乎都是在语句执行之前设置的。
答案 1 :(得分:1)
基本上不可能。您可以将CASE..END移动到功能并以这种方式调用它,但影响是可记录的......
UPDATE PAYMENT_HISTORY
SET
request_status_id = dbo.fnCalc(PHP.request_status_id, PHP.prevRequest_status_id, 1),
is_changed = dbo.fnCalc(PHP.request_status_id, PHP.prevRequest_status_id, 2)
答案 2 :(得分:1)
请参阅BOL for update子句:https://msdn.microsoft.com/en-us/library/ms177523.aspx
具体为column_name = { expression | DEFAULT | NULL }
只允许在右侧表达式,因此您无法编写表达式来选择要更新的列。
答案 3 :(得分:1)
或者如果逻辑如此简单,您可以使用2次更新来完成,第二次更新基于第一次更新的结果。但同样,你需要有理由这样做。
UPDATE PAYMENT_HISTORY
SET request_status_id =
CASE
WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN NULL
ELSE PHP.request_status_id
END
UPDATE PAYMENT_HISTORY SET
is_changed =
CASE
WHEN request_status_id is NULL THEN 0
ELSE 1
END
OR执行效率更高(第二次更新只会更新需要更新的行)
UPDATE PAYMENT_HISTORY
SET
request_status_id =
CASE
WHEN PHP.request_status_id = PHP.prevRequest_status_id THEN NULL
ELSE PHP.request_status_id
END,
is_changed=0
UPDATE PAYMENT_HISTORY SET
is_changed = 1
WHERE
request_status_id is not NULL
答案 4 :(得分:0)
是的,可以使用变量。
UPDATE PAYMENT_HISTORY
SET request_status_id =
CASE
WHEN PHP.request_status_id = PHP.prevRequest_status_id
THEN coalesce((@ischanged:=0)+null,NULL)
ELSE coalesce((@ischanged:=1)+null,PHP.request_status_id)
END,
is_changed = @ischanged
一般来说:
UPDATE mytable
SET
a = CASE
WHEN [condition1]
THEN coalesce((@b:= [b expression]) +null, (@c:= [c expression]) +null, [a expression])
WHEN [condition2]
THEN coalesce((@b:= [b expression]) +null, (@c:= [c expression]) +null, [a expression])
ELSE coalesce((@b:= [b expression]) +null, (@c:= [c expression]) +null, [a expression])
END,
b = @b,
c = @c
附加到coalesce'+ null'的每个输入参数,以确保执行表达式并将结果存储在变量中,但是coalesce函数不返回表达式的结果。
在MySQL上测试。