2017-08-30 86 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。 我無法弄清楚什麼是錯的 –

相關問題