2017-08-30 107 views
-3
UPDATE SCPOMGR.DFUVIEW D 
    SET D.UDC_NEWDFU = (SELECT (CASE WHEN D1.UDC_CREATIONDATE > ADD_MONTHS (TRUNC(SYSDATE),3) 
           THEN 1 
           ELSE 0 
            END) 
          FROM SCPOMGR.DFUVIEW D1, SCPOMGR.UDT_GEN_PARAM G 
         WHERE D.DMDUNIT = D1.DMDUNIT 
          AND D.DMDGROUP = D1.DMDGROUP 
          AND D.LOC = D1.LOC 
          AND G.REGION=VREGION 
          AND G.JDA_CODE=SUBSTR(D1.DMDUNIT,-2,2) 
          ); 

SELECT 0会做什么? 它会选择没有行,并更新与NULL的列?UPDATE TABLE T1 SET COLUMN = SELECT 0 FROM TABLE T1

+0

'NULL'与0不同。 –

+0

您能解释一下select语句实际在做什么吗? 因为我收到一条警告,说udc_newdfu不能设置为null。 –

+1

请正确标记。是一个Oracle或MySQL的问题?不要使用您看到的所有标签 – nacho

回答

0

在赋值的右侧(您想要更新的值),您有一个带有CASE表达式的SELECT语句。有一个子查询(带有几个附加过滤器的连接)。 SELECT语句将返回与连接中一样多的行并满足所有其他过滤器。对于其中的一些行的SELECT语句将返回1,为他人,为0

你想到的是,子查询(在具有多个连接WHERE条件)将返回一排,然后你检查CREATIONDATE和基于那你更新值为1或0?

原则,SELECT语句可能返回多行 - 在这种情况下,你会得到一个不同的错误信息,一些关于标量查询(一个是应该是标量,反正)返回不止一个行。

子查询也可能根本不返回任何行 - 在这种情况下,SELECT语句根本不会返回任何行,在这种情况下,UPDATE表示“将NULL分配给左侧的列分配”。这似乎发生在这里。

这是没有理由引发异常。但是,如果列(UDC_NEWDFU)具有NOT NULL约束,则会发生异常。

因为CASE表达式只能返回0或1,所以从不为NULL,NULL分配可能的唯一方式是子查询(包含多个条件的连接)不返回任何行。在其中一个评论中你说过,子查询确实会返回行。我不相信你。如果它返回行,那么我不相信你有更新到NULL尝试。

+0

嗨@mathguy,谢谢你这么好解释。我很高兴,我的理解与你所建议的相符。实际上,我想不出任何可能的原因,而不是上面提到的原因。选择肯定会返回行,大约20k。 udc_newdfu具有非空约束。 –

+0

@sahibathakral - 子查询是**相关的**,这意味着:它选择'D1'和'G'(使用你的别名)的连接中的行来匹配'D'上的每个连续行, WHERE条款。因此,对于'D'的每一行,结果集可能不同,对于'D'中的一些**行,结果可能是空的(无行)。所以,说“select返回大约20k行”没有任何意义 - 没有一个select语句,有'D'中有多少行。也许这条语句为'D'行返回20k行,但也许并非所有行都是! – mathguy

+0

,我真的很感谢你对此事的深入了解。我有一个问题,在结果可能为空的情况下,即没有行,它会更新为空吗? 20k是scpomgr.dfuview中的相关行数。 根据我的理解,D表和D表的每一次成功连接都会得到更新。我的理解是正确的吗? 此外,在这种情况下,udc_creationdate永远不会比SYSDATE3个月更大,尽管,udc_newdfu正在值1。 我无法弄清楚什么是错的 –

相关问题