функция не возвращает значение ни для каких возвращаемых строк - PullRequest
0 голосов
/ 24 апреля 2019

Я создал функцию, которая принимает идентификатор фильма в качестве входных данных и возвращает информацию о наличии на основе этого идентификатора. Функция в основном работает, но если я хочу получить информацию из фильма, которого нет в базе данных (не возвращает строк), ничего не возвращается. Не можете понять, почему?

не выдает ошибку, когда я вызываю идентификатор, который не возвращает строк, поэтому обработка исключений не будет работать.

create or replace function stock_info 
    (p_id IN NUMBER
    )
return VARCHAR2
IS 
    cursor c1 is 
        select movie_id, movie_title, movie_qty
        from mm_movie
        where p_id = movie_id;
    lv_movie_info VARCHAR2(100);
BEGIN

    for i in c1 loop
        if p_id = i.movie_id then 
            lv_movie_info := i.movie_title || ' is available: ' || i.movie_qty || ' on the shelf';
        else
            lv_movie_info := 'no data found';
        end if;
    end loop;

    return lv_movie_info;   
END STOCK_INFO;
/

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Причина, по которой вы ничего не получаете, когда нет данных, заключается в том, что цикл не выполняется. Логически выражение For говорит «выполнить следующий цикл для каждой строки, возвращаемой в курсоре», но в курсоре нет строк, поэтому он никогда не выполняет цикл. Кроме того, структура фактически указывает на то, что вы ожидаете несколько для данного p_id. Если это не так, вы можете удалить курсор все вместе. Предполагая, что p_id является первичным ключом, у вас есть либо 0, либо 1 строка, поэтому:

create or replace function stock_info (p_id in number)
return text
is
    lv_movie_info varchar2(100);
begin
    select i.movie_title || ' is available: ' || i.movie_qty || ' on the shelf'
      into lv_movie_info 
      from mm_movie i 
     where p_id = movie_id;

    return lv_movie_info;
exceptions 
   when no_data_found 
   then return 'no data found';
end stock_info; 

Конечно, если вы ожидаете больше, чем 1 строка, необходим курсор, но IF не так, как условие were гарантирует, что это правда. Тем не менее, с 0 строками цикл не будет выполнен, поэтому сообщение «данные не найдены» должно идти после «Завершить цикл».

Страховщик

0 голосов
/ 24 апреля 2019

оператор курсора, который вы использовали, извлекает данные из параметра in.т. е. в выбранном курсоре ограничение, которое вы ограничиваете на основе переданного идентификатора фильма.

при передаче идентификатора фильма, которого нет в базе данных, оператор выбора курсора не будет извлекать какие-либо записи, и поэтому поток выиграл 'даже не заходите в цикл for.

, если вы хотите вернуть не найденные данные - при передаче идентификатора фильма, которого нет в базе данных, два способа решить 1. перед циклом, нужно выбрать оператор selectфлаг Y или N, если существует в соответствии с вашим требованием.2. если курсор не используется, есть опция проверки не найден ... пример:

declare
cursor c1 is select * from table_sample; -- empty table
c_rec c1%rowtype;
begin
open c1;
fetch c1 into c_rec;
  if c1%notfound then
      dbms_output.put_line('not found');
   end if;
close c1;
end;

-- output
not found
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...