【问题标题】:PL/SQL Error - exact fetch returns more than requested number of rowsPL/SQL 错误 - 精确提取返回的行数超过了请求的行数
【发布时间】:2018-01-15 10:29:52
【问题描述】:

我目前正在尝试编写一个 PL/SQL 脚本,该脚本将从我的 saleinv 表中收集与用户输入的序列号匹配的信息。目前,我的代码正在返回错误错误消息是 ORA-01422:精确提取返回的行数超过了请求的行数。如果有人可以向我解释如何解决该问题,将不胜感激。我的代码如下。

    ACCEPT p_saleinv PROMPT 'Enter sales invoice number: '
    VARIABLE g_output VARCHAR2(4000)

    DECLARE

 v_ABC NUMBER(4);
 v_DEF EXCEPTION;
 v_freightcost car.freightcost%TYPE;
 v_totalcost car.totalcost%TYPE;

CURSOR saleinvoicelist IS
SELECT *
FROM saleinv
WHERE saleinv = '&p_saleinv';

BEGIN

SELECT COUNT(*)
INTO v_ABC  
FROM saleinv
WHERE saleinv = '&p_saleinv';

SELECT freightcost,totalcost
INTO  v_freightcost,v_totalcost
FROM car c, saleinv si
WHERE  c.serial = si.serial
AND   c.cname  = si.cname;


IF v_ABC = '0' THEN

  RAISE v_DEF;

ELSE 

   FOR v_saleinv IN saleinvoicelist LOOP
      :g_output := :g_output||TRIM(v_saleinv.saleinv)||' ';
      :g_output := :g_output||TRIM(v_saleinv.cname)||' ';
      :g_output := :g_output||TRIM(v_saleinv.saledate)||' ';
      :g_output := :g_output||TRIM(v_saleinv.serial)||' ';
      :g_output := :g_output||TO_CHAR(v_freightcost,'122345.69')||CHR(10);
      :g_output := :g_output||TO_CHAR(v_saleinv.tax,'12345.99')||' ';
      :g_output := :g_output||TO_CHAR(v_saleinv.licfee,'123.76')||' ';
      :g_output := :g_output||TO_CHAR(v_saleinv.commission,'1234.59')||' ';
      :g_output := :g_output||TO_CHAR(v_totalcost,'123489.97')||CHR(10);
      :g_output := :g_output||TO_CHAR(v_saleinv.totalprice,'12345.45')||' ';

   END LOOP;

END IF;

EXCEPTION

 WHEN v_DEF THEN

  ROLLBACK WORK;

  :g_output := 'Such data does not exist.';

  WHEN OTHERS THEN

   ROLLBACK WORK;

   -- check error message
   :g_output := 'Error'||CHR(10);
   :g_output := :g_output||'Error code is '||SQLCODE||CHR(10);
   :g_output := :g_output||'Error message is '||SQLERRM;

  END;
   /
   PRINT g_output

【问题讨论】:

  • 你需要一个GROUP BY someField 以及你有Count(*)的地方
  • @Ofisora - 仅当查询的投影包含一些非聚合列时。这不是这里的情况,所以不需要 GROUP BY。

标签: mysql sql oracle plsql


【解决方案1】:

这个错误最可能的原因是下面的选择

SELECT freightcost,totalcost
INTO  v_freightcost,v_totalcost
FROM car c, saleinv si
WHERE  c.serial = si.serial
AND   c.cname  = si.cname;

因为您要选择变量,所以选择只能返回一行。我假设您使用的序列号将从该选择返回多行。您需要确保它返回一个唯一的行。

【讨论】:

    【解决方案2】:

    下面的 SELECT INTO 语句只要求单数变量中的单数输出。您需要处理异常或修改代码,如果您期望更多输出然后使用 FOR LOOP。 希望下面的 sn-p 有所帮助。

    ACCEPT p_saleinv PROMPT 'Enter sales invoice number: '
    VARIABLE g_output VARCHAR2(4000)
    DECLARE
      v_ABC NUMBER(4);
      v_DEF EXCEPTION;
      v_freightcost car.freightcost%TYPE;
      v_totalcost car.totalcost%TYPE;
      CURSOR saleinvoicelist
      IS
        SELECT * FROM saleinv WHERE saleinv = '&p_saleinv';
    BEGIN
      SELECT COUNT(*) INTO v_ABC FROM saleinv WHERE saleinv = '&p_saleinv';
    
    
      BEGIN
      SELECT freightcost,
        totalcost
      INTO v_freightcost,
        v_totalcost
      FROM car c,
        saleinv si
      WHERE c.serial = si.serial
      AND c.cname    = si.cname;
      EXCEPTION 
         WHEN TOO_MANY_ROWS THEN
      dbms_output.put_line('Too many rows fetched');
         RETURN;
         WHEN NO_DATA_FOUND THEN
      dbms_output.put_line('No rows fetched');
        RETURN;
      IF v_ABC       = '0' THEN
        RAISE v_DEF;
      ELSE
        FOR v_saleinv IN saleinvoicelist
        LOOP
          :g_output := :g_output||TRIM(v_saleinv.saleinv)||' ';
          :g_output := :g_output||TRIM(v_saleinv.cname)||' ';
          :g_output := :g_output||TRIM(v_saleinv.saledate)||' ';
          :g_output := :g_output||TRIM(v_saleinv.serial)||' ';
          :g_output := :g_output||TO_CHAR(v_freightcost,'122345.69')||CHR(10);
          :g_output := :g_output||TO_CHAR(v_saleinv.tax,'12345.99')||' ';
          :g_output := :g_output||TO_CHAR(v_saleinv.licfee,'123.76')||' ';
          :g_output := :g_output||TO_CHAR(v_saleinv.commission,'1234.59')||' ';
          :g_output := :g_output||TO_CHAR(v_totalcost,'123489.97')||CHR(10);
          :g_output := :g_output||TO_CHAR(v_saleinv.totalprice,'12345.45')||' ';
        END LOOP;
      END IF;
    EXCEPTION
    WHEN v_DEF THEN
      ROLLBACK WORK;
      :g_output := 'Such data does not exist.';
    WHEN OTHERS THEN
      ROLLBACK WORK;
      -- check error message
      :g_output := 'Error'||CHR(10);
      :g_output := :g_output||'Error code is '||SQLCODE||CHR(10);
      :g_output := :g_output||'Error message is '||SQLERRM;
    END;
    /
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      • 2013-11-15
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多