Exception 在plsql中未调用异常

Exception 在plsql中未调用异常,exception,plsql,oracle11g,spl,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

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

我建议您阅读PL/SQL中的游标。 游标for循环将遍历游标中检索到的每个记录。如果找不到数据,执行将永远不会在循环内继续,因此在循环内不会引发“找不到数据”异常。您的代码应该是这样的

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;

使用FOR循环时,不需要使用游标属性。你可以查询记录,然后再做决定。下面是一个运行示例,我没有employees表,所以创建了一个存根。FOR循环的便利之处在于,您不必担心关闭光标

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

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

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

这段代码有很多问题。如果查询未返回任何行,则永远不会进入循环。c1%rowcount是到目前为止已提取的行数,而不是将提取的行数。c1%notfound在这种情况下永远不会为真。我猜这是一个家庭作业,我不确定你到底想完成什么。也许您希望执行“选择到”操作,然后处理找不到的数据和太多的行执行。不要忘记关闭光标。在“打开c1&t”和“关闭光标”中有这些小错误。我确实删除了for循环并尝试了,但仍然不起作用。我是一个初学者,所以可能我需要大量的阅读和练习。谢谢你的回答@DineshYes PLSQL并不难学。练习可以让你变得更好。祝你一切顺利。请共享仍不适用于您的代码