可以在SET中包含IF语句吗?

时间:2018-07-06 07:55:46

标签: sql oracle

我在Oracle中有一个表,该表的列名为ERROR_CODE(这是VARCHAR2),每个值最初都设置为NULL。我想用UPDATE语句更新它,如以下语句所示:

UPDATE SNAPSHOT_TEST
SET ERROR_CODE = 
  IF(...) THEN NVL2(ERROR_CODE, CONCAT(ERROR_CODE, ',8'), '9')
    ELIF(...) THEN NVL2(ERROR_CODE, CONCAT(ERROR_CODE, ',9'), '9') 
    ELIF(...) ...
  END IF;

我尝试使用CASE语句来实现此结果,并且它可以正常工作,但这不是我所需要的,因为可以同时匹配多个条件,并且如果发生这种情况,我需要连接错误代码,如下所示:例如,我之前插入的语句,末尾有“ 8,9”。 在Oracle中有没有办法实现这一目标?

4 个答案:

答案 0 :(得分:2)

您可以使用CASE表达式:

UPDATE SNAPSHOT_TEST
SET ERROR_CODE = 
    CASE  WHEN ... THEN NVL2(ERROR_CODE, CONCAT(ERROR_CODE, ',8'), '9')
          WHEN ... THEN NVL2(ERROR_CODE, CONCAT(ERROR_CODE, ',9'), '9') 
          ELSE ...
    END;

  

最后有'8,9'

UPDATE SNAPSHOT_TEST
SET ERROR_CODE =
  ERROR_CODE || CASE WHEN ... THEN '8' END || CASE WHEN ... THEN '9' END

答案 1 :(得分:1)

正如其他回答者所说,我们需要一些最少的样本数据和样本条件来推荐解决方案。

例如,阅读“ ...多个条件...最后有8,9 ...”,使我想到了LISTAGG,但是我不能将其表达为答案,因为我没有关于情况的丝毫线索。

答案 2 :(得分:1)

  

多个条件可以同时匹配,如果发生这种情况,我需要串联错误代码

因此,连接错误代码,并用一个case表达式确定是否需要每个错误代码:

update snapshot_test
set error_code = 
  ltrim(
    case when (...) then ',8' end
    || case when (...) then ',9' end
    || case when (...) then ',10' end
    ...
    , ',');

当它们全部添加逗号时,ltrim会删除由第一个匹配项创建的多余的逗号。

db<>fiddle demo,具有完全任意的和人为的条件,因为我们没有什么可以处理的。

(迟来的是,我意识到这几乎是@LukaszSzozda所做的编辑;除了这包括逗号)。

答案 3 :(得分:0)

我设法自己找到了一个解决方案:即使卢卡兹(Lukasz)的问题在编辑后可能确实有效,但在这种情况下,如下面的代码片段所示,级联使用单独的UPDATE会更有效:< / p>

UPDATE SNAPSHOT_TEST
SET ERROR_CODE = NVL2(ERROR_CODE, CONCAT(ERROR_CODE, ',8'), '8')
WHERE (...);

UPDATE SNAPSHOT_TEST
SET ERROR_CODE = NVL2(ERROR_CODE, CONCAT(ERROR_CODE, ',9'), '9')
WHERE (...);

通过这种方式,如果ERROR_CODENULL,则会在第一个值匹配的情况下进行首次设置,否则将以逗号添加另一个错误代码。