PL/SQL中編寫數據查詢存儲過程,調用時出現“ORA-01422:實際返回行數超過請求行數”錯誤的解決辦法


用PL/SQL創建數據查詢過程的時候,存儲過程創建並調式都成功,但是調用存儲過程查詢數據的時候顯示“ORA-01422:實際返回行數超過請求行數”。於是我先運行了"select ...... from .....;"語句,這段語句運行成功。存儲過程里的查詢語句形式為“select ....... into ....... from .....;”。這兩種語句中的過濾條件一樣,那么為什么第一個語句成功運行,反而第二種語句報錯呢?

下面用scott用戶自帶的emp表為例,跟大家分享我怎么跳出這個坑。

我的目的是通過emp表中的deptno為過濾條件查詢emp表中empno,ename,job,sal四個字段,於是我寫了第一次的存儲過程,代碼如下:

create or replace procedure sp_emp1(p_deptno in emp.deptno%type)
is
    v_no     emp.empno%type;
    v_name   emp.ename%type;
    v_job    emp.job%type;
    v_sal    emp.sal%type;
begin
  select empno,ename,job,sal into v_no,v_name,v_job,v_sal from emp where deptno=p_deptno;
  dbms_output.put_line(v_no||'-----'||v_name||'-----'||v_job||'------'||v_sal);
end;

上面的存儲過程調式成功,然后我調用了sp_emp1存儲過程,這時候報錯了

--調用sp_emp1
declare
  v_deptno emp.deptno%type:=&部門號;
begin
  sp_emp1(v_deptno);
end;

 

這里的過濾條件為deptno=30。

於是我運行了

select empno,ename,job,sal from emp where deptno=30;

結果為:

  最后比較兩個查詢語句好像發現了問題在哪兒,select ........ into ..... from ..... ;這段語句中into關鍵詞好像是問題的來源,於是百度一下了這個語句。終於有了答案,本來“select .... int ...... from ....;”語句只能返回單行數據,要是過濾條件后查詢出的結果是多行的話,這個語句會報錯。

  於是,我把存儲過程中用游標實現了遍歷emp表,使用游標后的存儲過程如下:

create or replace procedure sp_emp1(p_deptno in emp.deptno%type) is
begin
  declare
    cursor cur_emp is
      select * from emp where deptno = p_deptno;
    e_cur cur_emp%rowtype;
  begin
    dbms_output.put_line('工號' || '-----' || '姓名' || '-----' || '職位' ||'-----' || '薪資');
    for e_cur in cur_emp loop
      dbms_output.put_line(e_cur.empno || '-----' || e_cur.ename ||'-----' || e_cur.job || '-----' || e_cur.sal);
    end loop;
  end;
end;

調用修改后的存儲過程,查詢結果如下:

 

其實出現“ORA-01422:ORA-01422:實際返回行數超過請求行數”的原因不止這一種,可能還有其他的錯誤也導致同樣的錯誤代碼,以上是我以前遇到的一個情況而已。這個問題說明我們在編寫代碼的時候要熟悉語句運行的先后循序、返回方式等細節。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM