代码之家  ›  专栏  ›  技术社区  ›  P Prad

在表中找不到给定记录时,如何处理游标中的异常

  •  2
  • P Prad  · 技术社区  · 6 年前

    我正在更新 emp3 (与emp表相同)使用游标进行循环,

    DECLARE 
       CURSOR incr_cur IS SELECT * FROM emp3 FOR UPDATE OF sal;
       v_job emp3.job%TYPE := '&ENTER_Job';
       v_cnt INTEGER := 0;
    BEGIN
      FOR r_l IN incr_cur LOOP
        IF v_job IN (r_l.job) THEN
          UPDATE emp3 SET sal = sal + 100 WHERE CURRENT OF incr_cur;
        END IF;
     END LOOP;
    
     FOR r_l IN incr_cur LOOP
        IF v_job IN (r_l.job) THEN
          v_cnt := v_cnt + 1;
          DBMS_OUTPUT.PUT_LINE('The Salary of ' || r_l.ename || ' is Incremented by 100 and the Updated Salary is: $' || r_l.sal);
        END IF;
     END LOOP;
    
         DBMS_OUTPUT.PUT_LINE('The Salary of '|| v_cnt ||' Employees are Updated');
    END;
    

    当执行PL/SQL块时,它将请求作业, 我给 MANAGER ,然后是 经理 增加100。 这个 emp3 表有5个工作类别 CLERK ,则, 经理 ,则, ANALYST ,则, SALESMAN PRESIDENT 。 然后如何显示消息 作业未列出,因此无法更新。 ,如果用户输入的作业不在表中,例如 DEVELOPER 。 我尝试了异常处理,但无法使其正常工作。

    2 回复  |  直到 6 年前
        1
  •  1
  •   William Robertson    6 年前

    不需要单独的步骤。只需尝试更新,如果没有行被更新,请这样说。如果您希望它是一个例外,那么使用 raise_application_error

    假设这是一个学习练习,这就是为什么你不想做一个普通的 update ,您可以这样做:

    declare 
        k_job constant emp3.job%type := '&JOB';
    
        cursor employees_cur is
            select * from emp3
            where  job = k_job
            for update of sal;
    
        v_update_count integer := 0;
        v_payroll_increase integer := 0;
    begin
        for r in employees_cur loop
            update emp3 set sal = sal + 100 where current of employees_cur;
            dbms_output.put_line('Salary for ' || r.ename || ' is incremented by $100 from $' || r.sal || ' to $' || (r.sal +100));
            v_update_count := v_update_count + 1;
            v_payroll_increase := v_payroll_increase + 100;
        end loop;
    
        if v_update_count = 0 then
            dbms_output.put_line('No staff are currently employed as ' || k_job ||'. Payroll is unchanged.');
        else
            dbms_output.put_line('Updated salary of '|| v_update_count ||' employee' || case when v_update_count <> 1 then 's' end||'.');
            dbms_output.put_line('Payroll increased by $'||v_payroll_increase||'.');
        end if;
    end;
    /
    
    Enter value for job: SALESMAN
    Salary for ALLEN is incremented by $100 from $1600 to $1700
    Salary for WARD is incremented by $100 from $1250 to $1350
    Salary for MARTIN is incremented by $100 from $1250 to $1350
    Salary for TURNER is incremented by $100 from $1500 to $1600
    Updated salary of 4 employees.
    Payroll increased by $400.
    
    PL/SQL procedure successfully completed.
    

    对于一个不存在的工作,您可以得到:

    Enter value for job: ASTRONAUT
    No staff are currently employed as ASTRONAUT. Payroll is unchanged.
    

    (在本例中, v_payroll_increase 总是100次 v_update_count ,但如果你想加薪10%或按部门等不同的幅度加薪,可能会更有用。)

        2
  •  1
  •   Littlefoot    6 年前

    这里有一个选项:检查这样的工作是否存在;否则,查询将返回 NO_DATA_FOUND 您可以使用适当的消息处理并引发异常。否则,请继续 UPDATE

    SQL> declare
      2    l_job emp.job%type;
      3  begin
      4    begin
      5      select job
      6        into l_job
      7        from emp
      8        where job = '&ENTER_Job'
      9          and rownum = 1;
     10    exception
     11      when no_data_found then
     12        raise_application_error(-20000, 'That job does not exist');
     13    end;
     14
     15    -- Job exists, so - go on with the update
     16  end;
     17  /
    Enter value for enter_job: MANAGER
    
    PL/SQL procedure successfully completed.
    
    SQL> /
    Enter value for enter_job: DEVELOPER
    declare
    *
    ERROR at line 1:
    ORA-20000: That job does not exist
    ORA-06512: at line 12
    
    
    SQL>
    

    P、 我更喜欢通过存储过程(接受作业名称作为参数)而不是匿名PL/SQL块来完成这样的工作。