【问题标题】:UPDATE statement not working in stored procedure; the error is ORU-10027: buffer overflow, limit of 20000 bytesUPDATE 语句在存储过程中不起作用;错误是 ORU-10027:缓冲区溢出,限制为 20000 字节
【发布时间】:2021-07-30 21:21:33
【问题描述】:

我正在使用 oracle sql developer 并且代码工作得非常好,但突然现在它不工作了.. 当我运行执行行时,它给出“ORU-10027:缓冲区溢出,20000 字节限制”错误。这是我的代码

create or replace procedure update_painting_price
is
   CURSOR c_painting is  SELECT painting_id, painting_price FROM painting;
   c_paintingid painting.painting_id%type;   
   c_paintingprice painting.painting_price%type;
   total_rows number(2);
BEGIN  
   OPEN c_painting;  
   LOOP  
      FETCH c_painting into c_paintingid, c_paintingprice;  
      UPDATE  painting  
   SET painting_price = painting_price + 50;  
   IF sql%notfound THEN  
      dbms_output.put_line('no painting updated');  
   ELSIF sql%found THEN  
      total_rows := sql%rowcount;  
      dbms_output.put_line( total_rows || ' paintings price updated ');  
   END IF;  
   END LOOP;  
   CLOSE c_painting;  
END;  

 execute  update_painting_price

【问题讨论】:

  • 在遇到错误/异常之前,您没有条件结束循环
  • 该过程在每幅画的价格上增加 50,对于每个循环迭代。更新应该有一些where 条件吗?这是什么意思?
  • 即使我添加where 条件我仍然得到同样的错误@GaryMyers
  • 没有where 条件。表中的每个价格都应该增加 50。@WilliamRobertson
  • @maramSt 但它更新行,次。如果这确实是要求,那么您不妨只计算行数,然后将所有画作的价格提高 50 * 计数。 (我认为这不是要求。)而且循环永远不会结束,这就是你最大化输出缓冲区的原因。

标签: oracle plsql


【解决方案1】:

对我来说,它似乎会突然开始工作——就像它突然停止一样——只有当你删除DBMS_OUTPUT.PUT_LINE因为超出了缓冲区大小,所以调用了循环。

查看以下基于 Scott 的示例架构的示例。它使用交叉(自)连接:

SQL> begin
  2    dbms_output.enable(2000);
  3    for cur_r in (select a.ename
  4                  from emp a cross join emp b
  5                  )
  6    loop
  7      dbms_output.put_line(cur_r.ename);
  8    end loop;
  9  end;
 10  /
SMITH
SMITH
SMITH
SMITH
<snip>
MILLER
MILLER
MILLER

PL/SQL procedure successfully completed.

SQL>

但是,如果我再添加一个emp 表,将超出缓冲区限制(2000 字节):

SQL> begin
  2    dbms_output.enable(2000);
  3    for cur_r in (select a.ename
  4                  from emp a cross join emp b cross join emp c
  5                  )                           ----------------
  6    loop                                      -- newly added
  7      dbms_output.put_line(cur_r.ename);
  8    end loop;
  9  end;
 10  /
SMITH
SMITH
SMITH
<snip>
WARD
WARD
begin
*
ERROR at line 1:
ORA-20000: ORU-10027: buffer overflow, limit of 2000 bytes
ORA-06512: at "SYS.DBMS_OUTPUT", line 32
ORA-06512: at "SYS.DBMS_OUTPUT", line 97
ORA-06512: at "SYS.DBMS_OUTPUT", line 112
ORA-06512: at line 7


SQL>

看到了吗?我的缓冲区设置为 low(仅 2000 字节),而您的缓冲区更高,但还不够高。如果你提出它会有帮助吗?可能,但这对我接下来要写的内容没有帮助。


您的代码似乎错误。您正在遍历整个 painting 表(没关系),但 update 在每次循环迭代中更新 所有行,因此 total_rows 始终等于表中的行数并且再次显示相同的消息。请考虑这样的事情:

create or replace procedure update_painting_price is
  l_total number := 0;
begin
  for cur_r in (select painting_id, painting_price
                from painting
               )
 loop
   update painting set
     painting_price = painting_price + 50
     where painting_id = cur_r.painting_id;
   l_total := l_total + sql%rowcount;
  end loop;
  
  dbms_output.put_line('Updated ' || l_total || ' row(s)');
end;
/

不过,对于你正在做的事情,你只需要一个简单的 SQL 语句:

update painting set
  painting_price = painting_price + 50;

结果将与该 PL/SQL 过程的结果相同。

【讨论】:

    猜你喜欢
    • 2021-04-01
    • 2012-12-18
    • 2011-12-19
    • 2017-05-12
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多