Ошибка процедуры PL/SQL с исключением

У меня есть таблица с именем "игроков", как это

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

Я написал процедуру PL/SQL для ее выполнения, указав «имя» в качестве параметра. Вот код-

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', он не показывает никакого вывода и, что более важно, он даже не попадает в исключение 'NO_DATA_FoUND'. Не могли бы вы помочь мне в этом отношении. спасибо


person Warrior92    schedule 13.07.2015    source источник
comment
какое исключение? также предоставьте структуру таблицы   -  person Ravi    schedule 13.07.2015
comment
Он уже предоставлен. Пожалуйста, посмотрите сверху.   -  person Warrior92    schedule 13.07.2015


Ответы (5)


Если вы кодируете цикл, Oracle не генерирует исключение, если данные не возвращаются (точно так же, как не генерирует исключение TOO_MANY_ROWS, если возвращается более одной строки).

person starko    schedule 13.07.2015
comment
Так неужели нет другого способа сделать это? Потому что я хочу, чтобы пришло исключение - person Warrior92; 13.07.2015
comment
Попробуйте использовать этот пример (java2s.com/Tutorial/Oracle/0480__PL -SQL-программирование/). Я думаю, это может помочь вам. - person starko; 13.07.2015
comment
Привет Старко! Я просмотрел ваш и обнаружил, что он мне бесполезен, потому что в нем не упоминается цикл. Без цикла я также могу получить вывод. Этот код выглядит следующим образом: DECLARE p_name player.name%type := 'Sachin'; P_country player.country%type; НАЧАЛО ВЫБЕРИТЕ имя, страну В p_name, P_country ОТ игроков, ГДЕ p_name = имя; DBMS_OUTPUT.PUT_LINE('Имя: '|| p_name); DBMS_OUTPUT.PUT_LINE('Страна: ' || p_country); ИСКЛЮЧЕНИЕ КОГДА no_data_found THEN dbms_output.put_line('Нет такого игрока!'); КОГДА другие ТОГДА dbms_output.put_line('Ошибка!'); КОНЕЦ; - person Warrior92; 13.07.2015

Ваше одно из предложений 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;
person Ashish Patil    schedule 13.07.2015
comment
Я попробовал вашу модификацию кода, но безуспешно: \ - person Warrior92; 13.07.2015

Ваш курсор 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;
person ilhan kaya    schedule 14.07.2015
comment
@ Ихан Кая Привет, Кая! ваши идеи были действительно полезны. Теперь, когда я помещаю «Sachin1», я показываю исключение. Как с отрицательной стороны, по умолчанию значение игрока принимается как Sachin, например, когда я помещаю player: = 'Sachin'. Он показал o / p как игрок Сачин, играющий за Индию, игрок Сачин, играющий за Австралию. Так что ему все равно, где другие игроки. Он просто перезаписывает Sachin для всех строк - person Warrior92; 14.07.2015
comment
Большое спасибо! Я так долго с этим боролся. Вы сделали мой день :). Хороший подход! - person Warrior92; 14.07.2015

Если вы действительно хотите использовать курсор, цикл 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;
/
person AndrewMcCoist    schedule 16.07.2015

person    schedule
comment
Привет! Я выполнил ваш запрос в разработчике pl/sql, и он выдал следующую ошибку. 1) ORA-06550: строка 14, столбец 14: PLS-00103 Обнаружен символ COLLECT при ожидании одного из следующих событий: . навалом. Символ . был заменен на COLLECT для продолжения; 2) ORA-06550: строка 18, столбец 4: PLS-00103 Обнаружен символ ; при ожидании одного из следующих событий: if. Если было заменено на ; продолжить; 3) ORA-06550: строка 22, столбец 1: PLS-00103 Обнаружен символ . при ожидании одного из следующих: (начало случая объявить выход для перехода, если прагма цикла мод нулевая поднять возврат выбрать - person Warrior92; 13.07.2015
comment
Я забыл об имени курсора после выборки. Мой код не тестировался в Oracle, это единственный пример. - person Arkadiusz Łukasiewicz; 13.07.2015