Как избежать исключения данных? - PullRequest
1 голос
/ 28 мая 2019

Я работаю над проектом, и у меня есть схема базы данных, написанная в Oracle db для библиотеки.У меня есть некоторые проблемы при попытке создать функцию, которая должна предоставлять некоторые рекомендации для пользователя.

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

    CREATE OR REPLACE FUNCTION getGenre(bookISBN IN VARCHAR2) RETURN VARCHAR2
    AS
      v_bookGenre VARCHAR2(100);
    BEGIN
      select genre into v_bookGenre from (select genre from books where bookISBN=isbn);
      return v_bookGenre;
    END getGenre;
    /
    CREATE OR REPLACE TYPE t IS TABLE OF varchar2(200);
    /
    create or replace type typeRecom is VARRAY(200) of VARCHAR2(200);
    /
    CREATE OR REPLACE FUNCTION topRecommandations(idUser IN VARCHAR2) 
    RETURN typeRecom
    AS

      lastGenres t :=t();
      readedBooks t:=t();
      topTen typeRecom;

      v_i NUMBER := 1;
      v_j NUMBER := 1;

      verifDateBook NUMBER:=0;
      verifDateLoan NUMBER:=0;

    BEGIN
      select count(*) into verifDateBook from books;
      if(verifDateBook = 0) then
        raise no_data_found;
      end if;

      select count(*) into verifDateLoan from loans;
      if(verifDateLoan = 0) then
        raise no_data_found;
      end if;

      lastGenres.extend();
      for i in (select genre from books join loans on books.isbn=loans.bookId where loanDate>add_months(sysdate,-1) and idUser=loans.regNo order by genre desc) loop
        DBMS_OUTPUT.PUT_LINE(i.genre);
        lastGenres.extend();
        lastGenres(lastGenres.count) := i.genre;
      end loop;
      /*select title into bookTitles from book join loan on book.isbn=loan.regNo;*/
       readedBooks.extend();
       for i in (select bookId from loans group by bookId order by count(bookId) desc) loop
        readedBooks.extend();
        readedBooks(readedBooks.count) := i.bookId;
      end loop;
      --select bookId into readedBooks from loan order by count(bookId) desc;

      for v_i IN 1..50 LOOP
        for v_j in 1..50 LOOP
          DBMS_OUTPUT.PUT_LINE(lastGenres(v_j));
          DBMS_OUTPUT.PUT_LINE(getGenre(readedBooks(v_i)));
          if(lastGenres(v_j)=getGenre(readedBooks(v_i))) then
            topTen(v_i) := getGenre(readedBooks(v_j));
          end if;
        EXIT WHEN topTen.count=10;
        END LOOP;
      EXIT WHEN topTen.count=10;
      end LOOP;
      for v_cont in 1..10 LOOP
            --if(topTen.count <= 10) then
            DBMS_OUTPUT.PUT_LINE(topTen(v_cont));
          --end if;
      end loop;
      return topTen;
      EXCEPTION
      WHEN no_data_found THEN 
        DBMS_OUTPUT.PUT_LINE('Nu exista valori.');

    END topRecommandations;

Ожидаемый результат: список из 10 рекомендуемых книг.Фактический результат: данные не найдены.

1 Ответ

1 голос
/ 29 мая 2019

Если я не ошибаюсь, единственное место, которое может вернуть NO_DATA_FOUND - это функция getGenre, поскольку она имеет SELECT некоторое значение в переменной, и никакие исключения не обрабатываются. Другие SELECT s используют агрегаты (которые будут возвращать 0, если там ничего нет).

Поэтому исправьте эту функцию, например,

CREATE OR REPLACE FUNCTION getGenre(bookISBN IN VARCHAR2) 
  RETURN VARCHAR2
AS
  v_bookGenre VARCHAR2(100);
BEGIN
  select genre 
    into v_bookGenre
    from books where bookISBN = isbn;

  return v_bookGenre;

EXCEPTION
  when no_data_found then
    return null;
END getGenre;

Кстати, почему вы использовали встроенный вид в этой функции? Почему вы просто не вернули genre с самого стола (как я)?

...