有没有一种方法将多个更新查询合并为一个查询?

6

我需要更新Provinces表中每个省份代码的描述信息。我的操作步骤如下:

update Provinces
set Description='Mississippi'
where Code = 'MS'

update Provinces
set Description = 'Maryland'
where Code = 'MD'

.... --around 100 more update queries like that.

这样做会有一些重复的代码,我感觉不太好看。不知道是否有更好、更专业的方式来完成相同的任务。欢迎提供任何帮助或建议。

3个回答

12
你可以使用 CASE
update Provinces
set Description= CASE code WHEN 'MS' THEN 'Mississippi'
                           WHEN 'MD' THEN 'Maryland' 
                           -- ELSE 'some default value' --otherwise NULL
                 END
where Code IN('MS', 'MD');

另一种方法是创建表变量,使用UPDATE FROM JOIN语法:

DECLARE @t AS (code VARCHAR(10), desc VARCHAR(1000));
INSERT INTO @t(code, desc) VALUES ('MS','Mississippi'), ('MD', 'Maryland');

UPDATE p
SET desc = t.desc
FROM Provinces p
JOIN @t t
  ON p.Code = t.code;

第一种选项中的WHERE子句实际上是做什么的?它看起来是多余的吗? - l008com
如果不定义WHERE条件,那么您必须处理其他情况。例如,对于Code ='CA',您必须提供某些值或将其设置为ELSE Description。这似乎很好,但没有进行身份转换的意义。第二个性能,如果您的表有100万行,则MS/MD都有约20k行,更新其余的980k行1:1有何意义。 - Lukasz Szozda

7

除了使用case表达式外,还可以使用公用表达式表值构造函数来连接到cte

;with ProvinceDescription as (
  select Description, Code
  from (values 
      ('Mississippi','MS')
     ,('Maryland','MD')
    ) v (Description, Code)
)
update p
  set p.Description = pd.Description
from Provinces p
  inner join ProvinceDescription pd
    on p.Code = pd.Code
where p.Description <> pd.Description;  

1
跳过CTE,直接使用“inner join ( values ( 'Mississippi', 'MS' ), ( 'Maryland', 'MD' ) ) as ProvinceDescription ( Description, Code ) on ProvinceDescription.Code = p.Code”。 - HABO
@Habo 确实,我只是更喜欢使用cte,因为我认为它可以提高可读性。 - SqlZim

0
如果您已经正确设置了自己的独特约束条件,您可以使用以下代码:
INSERT INTO Provinces (Description, Code)
VALUES ('Maryland', 'MD'), ('Mississippi', 'MS')
ON DUPLICATE KEY UPDATE Description=VALUES(Description), Code=VALUES(Code)

2
“Microsoft SQL Server” 不等于 “MySQL”,同时也无法解决 OP 的问题。 - Lukasz Szozda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接