我有一个更新查询,比如
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';
有人知道原因吗?
如果薪资值中包含一些空值,它会更新空值吗?(我知道它不会,因为内部查询返回一个数字值)。
如果我硬编码内部查询的值,它可以正常工作,但如果我使用绑定参数,则会失败。(但是,无论是硬编码时还是使用bind参数时,都会返回一个数值。)
我似乎不知道这个简单的问题出了什么问题。
发布于 2015-04-02 05:04:44
薪资-(选择sum(工资).
如果salary
或sub-query
返回空,则整个表达式将产生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值进行更新,因为表达式导致了空。让我们使用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>
https://stackoverflow.com/questions/29405052
复制相似问题