2015-04-02 36 views
2

我有一個更新查詢類似更新NULL而不是值的Oracle更新?

update employees 
set salary = salary - (select sum(salary) from employees where manager_id in (101,102)) 
where employee_id = 105; 

上面的SQL工作正常,但下面的SQL是更新的NULL值來代替。

UPDATE table1 a 
SET a.col1 = a.col1 - (SELECT SUM(b.col2) 
          FROM table2 b 
          WHERE b.col3 = 'AA' 
           AND b.col4 = '1234' 
           AND b.col5 = '123456789' 
           AND b.col6 = 'O' 
           AND b.col7 IN (1, 2, 3, 4)) 
WHERE a.col3 = 'AA' 
     AND a.col4 = '2313' 
     AND a.col5 = '987654321'; 

有人知道原因嗎?

如果工資值中有一些NULL值,它會更新NULL嗎? (我知道它不會因爲內部查詢返回一個數字值)。

它工作正常,如果我硬編碼的內部查詢的值,但失敗,如果我使用綁定參數。 (但是,當硬編碼或使用綁定參數時,都會返回一個數值。)

我只是不知道這個簡單的查詢有什麼問題。

+0

順便提一下原來這裏是'SQL UPDATE TABLE1一個SET = a.COL1 a.COL1 - (SELECT SUM(b.COL2) FROM TABLE2 b WHERE b.COL3 = 'AA' AND b.COL4 = '1234' AND b.COL5 = '123456789' AND b.COL6 = 'O' AND b.COL7 IN(1,2,3,4) ) WHERE a.COL3 ='AA' AND a.COL4 ='2313' AND a.COL5 ='987654321';' – 2015-04-02 04:43:21

+0

更好地在問題本身中添加這些細節而不是評論。我已編輯你的問題,並且這次爲你添加了它。 – 2015-04-02 04:54:07

+0

謝謝你的幫忙。我會牢記這一點。 – 2015-04-02 04:59:10

回答

1

工資 - (SELECT SUM(工資)...

如果salarysub-query回報NULL,則整個表達導致NULL 因此,將更新和設置列值爲NULL

要避免這種情況,請在整個表達式中使用NVL

例如,

SQL> CREATE TABLE t AS SELECT 1 A FROM dual; 

Table created. 

SQL> 
SQL> SELECT * FROM t; 

     A 
---------- 
     1 

SQL> 
SQL> UPDATE t SET A = A - (SELECT NULL FROM dual); 

1 row updated. 

SQL> 
SQL> SELECT * FROM t; 

     A 
---------- 


SQL> 

因此,它與NULL值進行更新,因爲表達導致NULL。讓我們用NVL避免更新時NULL:

SQL> ROLLBACK; 

Rollback complete. 

SQL> UPDATE t SET A = NVL(A - (SELECT NULL FROM dual), A); 

1 row updated. 

SQL> 
SQL> SELECT * FROM t; 

     A 
---------- 
     1 

SQL> 

問題解決了!

爲了更詳細

以上NVL方法就像IF NULL THEN REPLACE_VALUE

所以,你可以寫一個CASE表達式來關注一下吧更詳細的,它只是擴大了NVL表達:

SQL> SELECT * FROM t; 

     A 
---------- 
     1 

SQL> UPDATE t 
    2 SET A = 
    3 CASE 
    4  WHEN (A - 
    5  (SELECT NULL FROM dual 
    6  )) IS NULL 
    7  THEN A 
    8  ELSE (A - 
    9  (SELECT NULL FROM dual 
10  )) 
11 END; 

1 row updated. 

SQL> SELECT * FROM t; 

     A 
---------- 
     1 

SQL>