PL / SQL过程错误,异常

时间:2015-07-13 09:11:14

标签: plsql procedures

我的桌子名为"玩家"像这样

 Name        Country
---------- ------------
Sachin       India
Ponting      Australia

我写了一个PL/SQL程序,通过给出" name"来执行它。作为参数。 这是代码 -

CREATE OR REPLACE PROCEDURE NEW_TEST (  player IN players.name%type, place IN players.country%type ) IS
countri players.country%type;
BEGIN
SELECT country into countri from players where name = player;
END;

DECLARE
player players.name%type; 
place players.country%type;
CURSOR cu_new0 is
SELECT name, country from players where name=player; 

BEGIN
player:='Sachin' ;
FOR pl_all in cu_new0 

LOOP
NEW_TEST (player, place);
dbms_output.put_line ('The player ' || player || ' play for ' || pl_all.country);
END LOOP;

EXCEPTION
   WHEN NO_DATA_FOUND THEN 
      dbms_output.put_line('No such player!');
   WHEN OTHERS THEN
      dbms_output.put_line('Error!');
END;

现在当我把球员放进去时:=' Sachin'它正在给出输出,但是当我给予玩家时:=' Sachin1'没有显示任何输出,更重要的是,它甚至没有例外的' NO_DATA_FoUND'。在这方面你能帮我吗? Thanx

5 个答案:

答案 0 :(得分:0)

如果编写循环代码,如果没有返回数据,Oracle不会抛出异常(就像它返回多行时不会抛出TOO_MANY_ROWS异常一样)。

答案 1 :(得分:0)

您的select子句之一未处理异常;你在该代码中消耗异常。

您的原始代码:

BEGIN
SELECT country into countri from players where name = player;
END;

使用以下代码进行修改 -

BEGIN
SELECT country into countri from players where name = player;
exception when no_data_found then 
raise_application_error(......);
END;

答案 2 :(得分:0)

DECLARE
player players.name%type; 
place players.country%type;
CURSOR cu_new0 is
SELECT name, country from players where name=player; 

type l_cu_new0 is table of cu_new0%rowtype; 
v_cu_new0 l_cu_new0; 
BEGIN
player:='Sachin' ;

open cu_new0;
  fetch cu_new0 bulk collect into v_cu_new0;
close cu_new0;
if v_cu_new0.count = 0 then 
  raise NO_DATA_FOUND;
end; 

FOR i  in v_cu_new0.first .. v_cu_new0.last   
LOOP
... 
END LOOP;

EXCEPTION
   WHEN NO_DATA_FOUND THEN 
      dbms_output.put_line('No such player!');
   WHEN OTHERS THEN
      dbms_output.put_line('Error!');
END;

答案 3 :(得分:0)

您的光标是 NULL 。因为; 临时代码块:

select name ,country from players where name = :player;

运行代码块:

select name ,country from players where name = 'Schin1';

运行代码块返回 NULL ,光标的值为 NULL 。 然后你的for循环代码块不起作用。

您可以解决此问题,例如;

CURSOR cu_new0 is SELECT name, country from players;

嗨@ Warrior92 进行编辑, 也许你可以尝试一下;

for pl_all in cu_new0 loop
new_test(player
        ,place);     
if pl_all.name = player then
  dbms_output.put_line('The player ' || player || ' play for ' || pl_all.country);
end if;
end loop;

答案 4 :(得分:0)

如果你真的想使用游标,for循环和异常,你可以尝试以下代码:

DECLARE
    -- create table type of players
    TYPE t_players_tab IS TABLE OF players%ROWTYPE;
    -- declare variable / array which will contain the result of cursor's select
    l_players_arr   t_players_tab := NEW t_players_tab();

    CURSOR c_fetch_player IS
    SELECT
        *
    FROM
        players
    WHERE
        name = player;

    -- declare exception which is to be caught within the EXCEPTION block
    EXCEPTION e_player_not_found;
    -- init the exception giving it the sqlcode -20001 (valid numbers for custom exceptions are in range from -20000 to -20999)
    PRAGMA EXCEPTION_INIT(e_player_not_found, -20001);

BEGIN
    -- fetch the cursor result into the array
    OPEN c_fetch_player;
    FETCH c_fetch_player BULK COLLECT INTO l_players_arr;
    CLOSE c_fetch_player;

    -- check if the array contains any results
    IF l_players_arr.COUNT > 0 THEN
        -- iterate through the rows in the array
        FOR idx l_players_arr.FIRST .. l_players_arr.LAST
        LOOP
            dbms_output.put_line ('The player ' || player || ' play for ' || l_players_arr(idx).country);
        END LOOP;
    ELSE -- if the array has no rows, raise application arror with the same sqlcode as defined in EXCEPTION_INIT
        raise_application_error(-20001,'Player ' || player || 'not found');
    END IF;

    EXCEPTION
        -- catch the exception
        WHEN e_player_not_found THEN
            dbms_output.put_line(sqlcode || ': ' || sqlerrm);
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_CALL_STACK);
            DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);          
            DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);

END;
/