【问题标题】:Exact fetch returns more than requested number of rows精确提取返回超过请求的行数
【发布时间】:2013-11-12 18:40:41
【问题描述】:

我正在尝试创建一个程序来传递客户编号并返回去年的购买次数和购买总额。如果没有购买,则返回数量和总数为零,并返回销售人员在去年与该客户的联系次数。

我这样称呼它:

DECLARE 
      a_Var NUMBER;
      b_Var NUMBER;
      C_Var NUMBER;
      D_Var NUMBER;    
BEGIN
      three_pr(001116,a_Var, b_Var);

    IF a_Var > 0 THEN
        DBMS_OUTPUT.PUT_LINE('the number of purchases :' || a_Var);
        DBMS_OUTPUT.PUT_LINE('the total value of purchase :' || b_Var);

    ELSE

        SELECT ContactID,Count(contactID)
        INTO
             C_Var,D_Var
        FROM    DD_Contacts
        WHERE  DateofContact  between to_date ('2012/01/01', 'yyyy/mm/dd')
               AND to_date ('2012/12/31', 'yyyy/mm/dd')
      Group By ContactID;

       DBMS_OUTPUT.PUT_LINE (C_Var||D_Var);

    END IF;

END;
/

使用上面的代码时出现错误:

ORA-01422:精确提取返回的行数超过了请求的行数 ORA-06512:在第 16 行

这是程序:

CREATE or REPLACE PROCEDURE three_pr

(par_CustomerID IN NUMBER, par_sumpurchase OUT Number,par_totalvalue OUT Number)
IS
BEGIN

        SELECT 
            COUNT(O.OrderID),SUM(Price*Quantity)
        INTO par_sumpurchase,par_totalvalue
            FROM DD_Orders O JOIN DD_OrderLine OL ON O.OrderID = OL.OrderID
            WHERE  DatePurchase  between to_date ('2012/01/01', 'yyyy/mm/dd')
            AND to_date ('2012/12/31', 'yyyy/mm/dd')
            AND CustomerID = par_CustomerID;

END;
/

【问题讨论】:

  • 嗨,欢迎来到 Stack Overflow。请始终准确说明问题所在,包括错误消息等。建议您留在身边并回答人们可能提出的任何问题;事情发生在这里。还请尝试创建一个有意义的标题...
  • 虽然您没有(根本)没有给出任何可能不正确的指示,但我猜您的匿名块引发了 TOO_MANY_ROWS(或 NO_DATA_FOUND)异常。您按CONTACT_ID 分组,这意味着可以返回不止一行,但您将返回的数据放入标准数字而不是某种描述的数组中。
  • 所以正如我所建议的那样,在您的匿名块中,您正在使用精确提取来选择多行...您希望从查询中返回多少行?

标签: oracle plsql


【解决方案1】:

当查询没有返回结果时,过程three_pr 没有正确处理NO_DATA_FOUND 异常。

    CREATE or REPLACE PROCEDURE three_pr

    (par_CustomerID IN NUMBER, par_sumpurchase OUT Number,par_totalvalue OUT Number)
    IS
    BEGIN
        BEGIN
            SELECT 
                COUNT(O.OrderID),SUM(Price*Quantity)
            INTO par_sumpurchase,par_totalvalue
                FROM DD_Orders O JOIN DD_OrderLine OL ON O.OrderID = OL.OrderID
                WHERE  DatePurchase  between to_date ('2012/01/01', 'yyyy/mm/dd')
                AND to_date ('2012/12/31', 'yyyy/mm/dd')
                AND CustomerID = par_CustomerID;
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                par_sumpurchase := 0;
                par_totalvalue := 0;
        END;

    END;
    /

【讨论】:

  • 聚合函数将总是返回结果;这里不需要处理 no_data_found 异常。第二个SELECT... INTO... 可能是另一个故事。
  • 我觉得我们俩都可能有点不对劲。 NO_DATA_FOUND 只有在存在 group by 子句时才会发生 - 而且它不存在于第一个查询中。但是,我认为 COUNT 应该返回 0 表示没有记录,但 SUM 不会为 NULL 表示没有记录?
  • SUM 可能为 NULL 但仍返回一行,这意味着您可以在此处使用它。如果存在 GROUP BY,则它有可能返回任意数量的行,这意味着可能会引发 NO_DATA_FOUND TOO_MANY_ROWS 异常(这可能是第二个 OP 查询中发生的情况)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
相关资源
最近更新 更多