Oracle [过程] - Sum 函数忽略 WHERE 子句

Posted

技术标签:

【中文标题】Oracle [过程] - Sum 函数忽略 WHERE 子句【英文标题】:Oracle [Procedure] - Sum function ignores WHERE clause 【发布时间】:2020-02-01 23:07:01 【问题描述】:

我在使用 ORACLE 过程时遇到问题,似乎 SELECT SUM 忽略了我的 WHERE 子句,并且汇总了所有列,而不仅仅是我想要的列(deptno)。 但是,如果我使用这样的功能之一,例如:

select SUM(SAL) AS SALSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = 10;

它显示正确的 SUM。 可能是什么问题?感谢您的帮助。

CREATE OR REPLACE PROCEDURE PROCEDURE1(numerdept IN number, money OUT number) IS
    SALSUM NUMBER;
    COMMSUM NUMBER;
WYJATEK EXCEPTION;
BEGIN
    IF numerdept IN (10, 20, 30) THEN
    BEGIN
        select SUM(SAL) INTO SALSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = numerdept;
        select SUM(COMM) INTO COMMSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = numerdept;
        money := SALSUM + COMMSUM;
    END;
    ELSE RAISE WYJATEK;
    END IF;

    EXCEPTION 
    WHEN WYJATEK THEN
    BEGIN
    dbms_output.put_line('Wrong deptno');
    money := NULL; 
    END;
END;
-- checking -- 
SET SERVEROUTPUT ON;
DECLARE
    pension number;
BEGIN
    PROCEDURE1(10, pension);
    dbms_output.put_line(pension);
END;

[编辑 3] 解决方案

select NVL(SUM(SAL), 0) INTO SALSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = numerdept;
select NVL(SUM(COMM), 0) INTO COMMSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = numerdept;

 BEGIN
    dbms_output.put_line('Wrong deptno');
    money := 10; 
END;

【问题讨论】:

WHERE 过滤行,而不是列。一行是一个数据记录。一列显示记录的一个字段。 一旦您解决了第一个问题,请停止与其他人一起编辑您的问题。它污染了线程并使其他人难以理解发布的答案。如果您还有其他问题,您应该提出一个新问题 【参考方案1】:

你的问题是你的输入参数和你的列同名,所以当查询看到

WHERE SCOTT.EMP.DEPTNO = deptno

它将deptno 解释为SCOTT.EMP.DEPTNO,这意味着deptno 的所有值都为真。更改输入参数的名称,查询将按预期工作。

您还应该使用NVL 来确保各个SUM 值不是NULL,就好像它们中的任何一个是NULL 一样,它们的总和也是NULL,即

select NVL(SUM(SAL), 0) INTO SALSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = numerdept;
select NVL(SUM(COMM), 0) INTO COMMSUM FROM SCOTT.EMP WHERE SCOTT.EMP.DEPTNO = numerdept;

【讨论】:

您需要在dbms_output.put_line('Wrong deptno'); money := NULL; 周围使用BEGIN ... END,否则即使程序成功,您也总是将money 设置为NULL @Nick:我认为你错了。异常块属于过程的开始和结束。 @Mr Robot:你的问题可能是空值。试试NVL(SUM(SAL), 0)NVL(SUM(COMM), 0) @Mr Robot:至于变量名,决定一些你一直遵循的命名约定。我说的是前缀,例如in_deptovi_deptnoout_moneyvo_money @MrRobot 但如果任一值(SALSUMCOMMSUM)是 NULL,那么总和将为 NULL

以上是关于Oracle [过程] - Sum 函数忽略 WHERE 子句的主要内容,如果未能解决你的问题,请参考以下文章

Oracle——分组函数

Oracle数据库—— 分组函数

JDBC:像过程一样调用 Oracle 函数

如何让SQL语句中的聚集函数sum不忽略NULL值

Oracle————存储过程与函数

Oracle————存储过程与函数