2016-03-02 96 views
1

我是plsql的初学者。下面的代码运行时没有任何编译错误,但notFoundException没有被调用。任何帮助将被appriciated。异常没有在plsql中调用

declare 
    abc exception; 
    notFoundException exception; 
    cursor c1(dd number) is select first_name from employees where salary = dd; 

begin 
    for i in c1(&t) 
    loop 
     if(c1%rowcount!=1) then 
      raise abc; 
     elsif(c1%notfound) then 
      raise notFoundException; 
     else 
      dbms_output.put_line(i.first_name); 
     end if; 
end loop; 
Exception 
     when abc then 
      dbms_output.put_line('abc'); 
      insert into messages values('too many rows exception');   
     when notFoundException then 
      dbms_output.put_line('notFoundException'); 
      insert into messages values('Nobody with this salary : '); 
end; 
/
+2

有很多与此代码的问题。如果查询不返回任何行,则不会进入循环。 'c1%rowcount'是到目前为止获取的行数,而不是将获取多少行。在这种情况下'c1%notfound'永远不会是'true'。我猜这是一项家庭作业,我不确定你实际上想要完成什么。也许你想做一个'select into',然后处理'no_data_found'和'too_many_rows'执行选项。 –

回答

0

我建议你阅读PL/SQL中的游标。 游标循环将遍历游标中检索到的每条记录。如果没有找到数据,执行永远不会在循环内部进行,因此在循环内部不会发现发现异常的数据。您的代码应该是这样的

declare 
    abc exception; 
    notFoundException exception; 
    lv_first_name varchar2(240); 
    cursor c1(dd number) is select first_name from employees where salary = dd; 

begin 

    open c1; 
    fetch c1 into lv_first_name; 
    if(c1%rowcount > 1) then 
     raise abc; 
    elsif(c1%notfound) then 
     raise notFoundException; 
    else 
     dbms_output.put_line(lv_first_name); 
    end if; 
    close c1; 

Exception 
     when abc then 
      dbms_output.put_line('abc'); 
      insert into messages values('too many rows exception');   
     when notFoundException then 
      dbms_output.put_line('notFoundException'); 
      insert into messages values('Nobody with this salary : '); 
end; 
+0

不要忘记关闭光标。 –

+0

在open c1(&t)和关闭游标时出现这些小错误。我确实删除了for循环并尝试了,但仍然无法正常工作。我是初学者,所以也许我需要大量的阅读和练习。感谢你的回答。 @Dinesh – Dudupoo

+0

是PLSQL不难学。练习可以让你更好。祝一切顺利。请分享仍然不适合您的代码 –

0

使用FOR LOOP时不需要使用游标属性。你可以查询记录,然后做出决定。这是一个正在运行的例子(我没有雇员表,所以编写了一个存根)。关于FOR LOOP的便利之处在于您不必担心关闭光标。

DECLARE 
    abc    EXCEPTION; 
    notfoundexception EXCEPTION; 
    CURSOR c1(dd NUMBER) IS 
    SELECT * 
     FROM (SELECT MOD(rownum, 3) salary 
        ,rownum first_name 
       FROM dual 
      CONNECT BY LEVEL < 10) 
    WHERE salary = dd; 

    v_count NUMBER := 0; 
BEGIN 
    FOR i IN c1(2) LOOP 
    v_count := v_count + 1; 

    IF (v_count > 1) THEN 
     RAISE abc; 
    END IF; 

    dbms_output.put_line(i.first_name); 
    END LOOP; 

    IF (v_count = 0) THEN 
    RAISE notfoundexception; 
    END IF; 

EXCEPTION 
    WHEN abc THEN 
    dbms_output.put_line('abc'); 
    --insert into messages values('too many rows exception');   
    WHEN notfoundexception THEN 
    dbms_output.put_line('notFoundException'); 
    --insert into messages values('Nobody with this salary : '); 
END; 
/
2

您可以使用下面的匿名块,并尝试

`SET SERVEROUTPUT ON; 

DECLARE 

first_name_in employees.first_name%ROWTYPE; 
Salary_in  employees.salary%ROWTYPE; 

BEGIN 

Salary_in:=&Salary; 

SELECT first_name 
INTO first_name_in 
FROM employees 
WHERE salary = Salary_in; 

EXCEPTION 
WHEN NO_DATA_FOUND THEN 
DBMS_OUTPUT.PUT_LINE('Nobody with this salary :'||Salary_in); 
INSERT 
INTO messages 
VALUES ('NO_DATA_FOUND exception'); 

WHEN TOO_MANY_ROWS THEN 
DBMS_OUTPUT.PUT_LINE('Too many with this salary :'||Salary_in); 
INSERT 
INTO messages 
VALUES ('TOO_MANY_ROWS exception'); 

WHEN OTHERS THEN 
DBMS_OUTPUT.PUT_LINE('select failed with error'||SUBSTR(SQLERRM,1,100)) 
INSERT 
INTO messages 
VALUES (SUBSTR(SQLERRM,1,100)); 

COMMIT; 
END; 
/`