在plsql中没有调用异常

时间:2016-03-02 06:42:12

标签: exception plsql oracle11g spl

我是plsql的初学者。下面的代码运行时没有任何编译错误但是没有调用notFoundException。任何帮助都会得到满足。

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;
/

3 个答案:

答案 0 :(得分: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;
/`

答案 1 :(得分: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;

答案 2 :(得分: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;
/