假设我有
student
表,其中有一列 name
。name
列的值为“studenttone”、“studenttwo”、“student Three”对于单个更换来说非常简单:
update student set name = replace(name, 'one', '1')
但是多次替换呢?有什么想法吗?
我只会使用多个更新语句,但如果您绝对必须在一个语句中执行此操作,只需嵌套替换调用即可:
update student set
name = replace(replace(replace(name, 'one', '1'), 'two', '2'), 'three', '3')
这是有效的,因为(尽管效率低下)如果未找到搜索词,则对
replace()
的调用无效。
REPLACE
虽然您可以将所有内容打包到一个语句中,但如果没有匹配的
WHERE
条件来排除未受影响的行,效率会很低。
UPDATE student SET name = replace(name, 'one', '1') WHERE name LIKE '%one';
UPDATE student SET name = replace(name, 'two', '2') WHERE name LIKE '%two';
UPDATE student SET name = replace(name, 'three', '3') WHERE name LIKE '%three';
这只查找并更新实际更改的行。根据您的示例匹配字符串的末尾。
最有效的方法是将其与类似 @Bohemian 建议的东西结合起来:
UPDATE student
SET name = replace(replace(replace(
name
, 'one' , '1')
, 'two' , '2')
, 'three', '3')
WHERE name ~ '(one|two|three)$';
但要确保一个替换不会影响下一个。
实际上,几个 OR 运算的
LIKE
表达式通常比单个
正则表达式更快,所以:
WHERE (name LIKE '%one' OR
name LIKE '%two' OR
name LIKE '%three');
CASE
SET name = CASE WHEN name LIKE '%one' THEN replace(name, 'one', '1')
WHEN name LIKE '%two' THEN replace(name, 'two', '2')
WHEN name LIKE '%three' THEN replace(name, 'three', '3')
ELSE name
END
根据具体
情况,这可能会被优化。举个例子:
SET name = CASE right(name, -7)
WHEN 'one' THEN student || '1'
WHEN 'two' THEN student || '2'
WHEN 'three' THEN student || '3'
ELSE name
END
ELSE name
子句对于返回尚未被替换的原始值(如果有)非常重要。如果省略
ELSE
子句,您将得到 NULL
而不是尚未替换的原始值。