Plsql PL/SQL过程错误,出现异常

Plsql PL/SQL过程错误,出现异常,plsql,procedures,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 co

我有这样一张名为“玩家”的桌子

 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;

现在,当我放置player:='Sachin'时,它会给出输出,但当我放置player:='Sachin1'时,它不会显示任何输出,更重要的是,它甚至不会出现“找不到数据”的异常。在这方面你能帮助我吗。Thanx

如果对循环进行编码,Oracle不会在没有返回数据的情况下引发异常(就像在返回多行时不会引发太多行异常一样)。

您的
select
子句之一没有处理异常;您正在使用该代码中的异常

您的原始代码:

BEGIN
SELECT country into countri from players where name = player;
END;
用下面的代码修改--


还有一个问题是,您的光标为空。因为 临时代码块:

选择名称
国
来自玩家
其中name=:player

运行代码块:

选择名称
国
来自玩家
其中name='Schin1'

运行代码块returnNULL,光标为haveNULLvalue。 那么for循环代码块就不起作用了

您可以通过以下方式解决此问题:

光标cu_new0为
从玩家中选择姓名、国家/地区

Hi@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;

如果确实要使用游标、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;
/

什么例外?同时提供您的表结构,它已经提供了。请看上面。那么没有其他方法了吗?因为我希望comeTry的异常使用这个示例()。我想它能帮你。嗨,斯塔科!我浏览了您的,发现它对我没有用处,因为在这里没有提到where循环。没有循环,我也可以得到输出。代码是这样的:声明p_name players.name%type:='Sachin';P_国家玩家。国家%类型;开始选择姓名,国家进入p_姓名,p_姓名=姓名的玩家的p_国家;DBMS_OUTPUT.PUT_行('Name:'|| p|u Name);DBMS|u OUTPUT.PUT_LINE('Country:'| | p| u Country);当找不到数据时出现异常,然后dbms_output.put_line('没有这样的播放器!');当其他人然后dbms_输出时。put_行('Error!');终止我尝试了你对代码的修改,但没有成功:\Hi!我在pl/SQLDeveloper中运行了您的查询,它给出了以下错误。1) ORA-06550:line14,column14:PLS-00103在预期以下情况之一时遇到符号“COLLECT”:。成块。符号“.”替换为“收集”以继续;2) ORA-06550:第18行第4列:PLS-00103在预期以下情况时遇到“;”符号:如果。“如果”替换为“继续”;3) ORA-06550:第22行第1列:PLS-00103在预期以下情况之一时遇到符号“.”:(begin case declare exit for goto if loop mod null pragma raise return selectI fetch后忘记了光标名称。我的代码还没有在Oracle中测试过,这是一个很好的例子。@ihan kaya Hi kaya!你的见解真的很有帮助。现在,当我放置“Sachin1”时,它显示了一个异常。在反面,它都将player值作为S默认情况下,achin就像我放置玩家时一样:='Sachin'。它显示了o/p,因为玩家Sachin为印度效力,玩家Sachin为澳大利亚效力。所以它不关心其他玩家在哪里。它只是覆盖了所有赛艇的Sachin谢谢!我为此奋斗了这么久。你让我的日子变得更好:)。很好的方法,耶!!
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;
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;
/