T-SQL:在UPDATE语句中使用CASE根据条件更新某些列


108

我想知道这是否有可能。如果条件为真,我想更新x列,否则y列将被更新

UPDATE table SET
     (CASE (CONDITION) WHEN TRUE THEN columnx
                       ELSE columny
      END)
= 25

我到处搜索,尝试了一些操作,但找不到解决方案。我认为这是不可能的,但是我想在这里问一下,看看是否有人做过。提前致谢。


假设所有都在同一个表中,是的。您总是可以在事务中运行它,并在出错时回滚以亲自查看。
OMG小马

我不确定你是什么意思。我试图为列设置条件,但它不起作用。它适用于select语句,但不适用于update语句。(从myTable中选择(大小写(条件),然后为columnx else列结尾))。更新不起作用,我明白为什么了。 t似乎是完成这项工作的一种方式
pqsk 2011年

Answers:


188

您不能使用条件来更改查询的结构,只能使用所涉及的数据。您可以这样做:

update table set
    columnx = (case when condition then 25 else columnx end),
    columny = (case when condition then columny else 25 end)

从语义上讲这是相同的,但请记住,这两列将始终被更新。这可能不会给您带来任何问题,但是如果您的事务量很大,那么可能会导致并发问题。

专门执行您所要求的唯一方法是使用动态SQL。但是,这是我鼓励您远离的事物。上面的解决方案几乎可以满足您的需求。


我同意动态SQL。那么我的数据会受到影响吗?我的意思是我不希望它在某些情况下发生变化。因此,它将只是重新插入其中已经存在的内容?命中数据库的数量可能还不错。
pqsk 2011年

@pqsk:这不会影响您的数据,它应该重新插入对于应该影响的任何列而言已经存在的内容。
亚当·罗宾逊

谢谢。我要去与此。如此简单,即使是穴居人也可以做到。哈哈。
pqsk 2011年

1
@AdamRobinson1.5年传递你知道一些更有效的方式来更新只有一列

@Somebodyisintrouble:更新一列的唯一方法是使用其他查询。
亚当·罗宾逊

23
UPDATE  table
SET     columnx = CASE WHEN condition THEN 25 ELSE columnx END,
        columny = CASE WHEN condition THEN columny ELSE 25 END

1
您只是复制亚当的回应,还是从其他地方获取?哈哈。只是注意到了。
pqsk 2011年

1
@pqsk:我们的回复间隔约1分钟,所以我想我点击提交的速度更快了;)
Adam Robinson

23
@pqsk:是的,我刚刚复制了亚当的回复,距23他发表评论只有几秒钟时间。我是一个快速的模仿者!
Quassnoi

2
@pqsk:如果将光标放在上* min ago,它将显示确切的发布时间。
Quassnoi

2
公平地说,即使两者都是一样的:如果亚当的故事会在你的故事之后出现,他会详细说明。这就是为什么我将他标记为答案。不过谢谢
pqsk 2011年

4

在此处输入图片说明

我想使用Case语句将ContactNo更改或更新为8018070999(其中有8018070777)

update [Contacts] set contactNo=(case 
when contactNo=8018070777 then 8018070999
else
contactNo
end)

在此处输入图片说明


1
为此,为什么不使用此查询UPDATE [Contacts] SET contactNo = 8018070999 WHERE contactNo = 8018070777
NewGuy

4

我知道这是一个非常老的问题,但这对我有用:

UPDATE TABLE SET FIELD1 =
CASE 
WHEN FIELD1 = Condition1 THEN 'Result1'
WHEN FIELD1 = Condition2 THEN 'Result2'
WHEN FIELD1 = Condition3 THEN 'Result3'
END;

问候


1

我知道这是一个非常老的问题,该问题被标记为已修复。但是,如果像我这样的人在表上触发了更新事件的数据记录触发器,这将引起问题。两列都将获取更新,日志将进行无用的输入。我的方式

IF (CONDITION) IS TRUE
BEGIN
    UPDATE table SET columnx = 25
END
ELSE
BEGIN
    UPDATE table SET columny = 25
END

现在,这还有另一个好处,就是不需要像上面的解决方案那样在表上进行不必要的写操作。


这是一个好点,也是一个很好的选择!我不再使用导致该线程的原始代码了,但是t总是很高兴拥有不同的解决方案,我认为这是一个很好的解决方案
pqsk

-1

我相信您可以通过调整以下其他答案来省略更新“不需要的”列:
update table set columnx = (case when condition1 then 25 end), columny = (case when condition2 then 25 end)

据我了解,这仅在满足条件时才会更新。

阅读所有评论后,这是最有效的:
Update table set ColumnX = 25 where Condition1 Update table set ColumnY = 25 where Condition1

示例表:
CREATE TABLE [dbo].[tblTest]( [ColX] [int] NULL, [ColY] [int] NULL, [ColConditional] [bit] NULL, [id] [int] IDENTITY(1,1) NOT NULL ) ON [PRIMARY]
示例数据:
Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 0) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 0) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 1) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 1) Insert into tblTest (ColX, ColY, ColConditional) values (1, null, null) Insert into tblTest (ColX, ColY, ColConditional) values (2, null, null) Insert into tblTest (ColX, ColY, ColConditional) values (null, 1, null) Insert into tblTest (ColX, ColY, ColConditional) values (null, 2, null)

现在,我假设您可以编写一个处理空值的条件。对于我的示例,我假设您编写了这样的条件,其结果为True,False或Null。如果您需要帮助,请告诉我,我会尽力而为。

现在,如果并且仅当ColConditional为True(1)时,运行这两行代码确实会将X更改为25,并且仅当ColConditional为False(0)时,Y才更改为25

Update tblTest set ColX = 25 where ColConditional = 1 Update tblTest set ColY = 25 where ColConditional = 0

PS在原始问题或问题的任何更新中都没有提到空值情况,但是如您所见,这个非常简单的答案仍然可以处理它们。


1
这实际上是行不通的。例如,如果该列允许为空,则当不满足条件时,将分配一个空值。如果不允许使用null,则更新将失败。您最终的“有效”查询至少在TSQL中是无效的sql。您是否在特定引擎上对此进行了测试,并且对您有用?
pqsk 2015年

我在SQL Server 2005上对此进行了测试,它如图所示完美运行。我肯定想知道为什么它被否决,并显示一个显示NULL值被更新的示例,因为在我上面的测试中,NULL值没有被更新。我一直认为最简单的答案就是最好的答案,如果我要处理的数据库包含数百万条记录,我肯定不想更新不必要的行。
John Greiner 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.