Как определить другую временную переменную и извлечь ее? - PullRequest
1 голос
/ 22 апреля 2020

Вот мой код; -

CREATE OR REPLACE PROCEDURE GetDeails
    (c_name    VARCHAR2,
    calories   NUMBER)


DECLARE
    CURSOR cur IS SELECT CATEGORY.Name FROM  CATEGORY INNER JOIN  FILLING ON CATEGORY.CategoryID = FILLING.CategoryID
    WHERE c_name=FillING.Name AND calories=GramCalories;
    fil cur%ROWTYPE;
BEGIN

    OPEN cur;
    LOOP
    FETCH cur INTO fil;
    EXIT WHEN (cur%NOTFOUND);
    IF fil%NOTFOUND THEN
        DBMS_OUTPUT.PUTLINE('NotFound');
    ELSE
        DBMS_OUTPUT.PUTLINE(fil.c_name, fil.calories);
    END IF;
    END LOOP;
    CLOSE cur;
END GetDetails;
/

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Ответ @Barbaros решает большую часть вашей проблемы, но может быть уточнен.

Оператор IF в l oop совершенно не нужен, так как он никогда не вернет True при выполнении. Если бы это было верно, оператор выхода, предшествующий ему, вышел бы из цикла; Таким образом, нет сообщений. Это избыточно; сделать тест, где результат уже известен. Вы можете изменить порядок и поставить выход после IF ... END IF. Но тогда сообщение «не найдено» всегда будет выдаваться. Вы можете использовать cur% rowcount после l oop, чтобы правильно сгенерировать сообщение. В dbms_output_put_line (fil.name, fil.calories) есть 2 ошибки.

  • переменная fil.calories не существует. GramCalories не был выбран в оригинале (как указано) и не был добавлен в ревизию. Поэтому не является частью курсора и, следовательно, не является частью типа строки курсора.
  • Требуется один строковый параметр, поскольку есть 2 параметра.

Принимая это во внимание, мы получаем:

create or replace procedure getdetails( c_name varchar2, calories number ) is

    cursor cur is 
    select f.name, c.gramcalories 
      from category c
      join filling f
        on f.categoryid = c.categoryid
     where c_name=f.name 
       and calories=gramcalories;
    fil cur%rowtype;

 begin
    open cur;

    loop
    fetch cur into fil;
    exit when (cur%notfound);
        dbms_output.put_line(fil.name || ' ' || fil..gramcalories);
    end loop;

    if cur%rowcount = 0 then 
          dbms_output.put_line('Not Found');
    end if;

    close cur;
end getdetails;
/

Как вопрос стиля :

  • Избегайте соглашения о присвоении имен CamelCase. Oracle всегда складывает имена объектов в верхний регистр . Таким образом, это просто затрудняет чтение Oracle сгенерированных ссылок. Вместо этого используйте слова, разделенные Underscore (_).
  • В отличие от Barbaros, я не считаю использование имени процедуры (function, package, ...) на завершающем конце избыточным, а скорее закрытием, а не «конец, если». Да, это синтаксически необязательный, но необязательный не является избыточным. Я всегда использую этот вариант. Итак, разработайте свой стиль (с учетом институциональных / клиентских стандартов), но соблюдайте его.
0 голосов
/ 23 апреля 2020

В основном ваше PROCEDURE утверждение хорошо, но имеет некоторые небольшие проблемы, такие как:

  • Преобразуйте имя GetDeails в GetDetails, чтобы получить соответствующее имя с указанным в конце после последнего ключевого слова END. Действительно, использование имени PROCEDURE дважды является избыточным, поэтому не нужно.

  • Должно быть ключевое слово IS или AS сразу после списка параметров IN, и ключевое слово DECLARE должно быть удалено.

  • DBMS_OUTPUT.PUTLINE следует преобразовать в DBMS_OUTPUT.PUT_LINE, и в столбце должны быть указаны два соответствующих столбца (Name и GramCalories). CURSOR SELECT список.

  • атрибут курсора может применяться не к некурсору FIL, а к CUR

    SQL> SET serveroutput ON
    SQL> CREATE OR REPLACE PROCEDURE GetDetails( c_name VARCHAR2, calories NUMBER ) IS
    
        CURSOR cur IS 
        SELECT f.Name, c.GramCalories 
          FROM CATEGORY c
          JOIN FILLING f
            ON f.CategoryID = c.CategoryID
         WHERE c_name=f.Name 
           AND calories=GramCalories;     
    
        fil cur%ROWTYPE;
    BEGIN
    
        OPEN cur;
        LOOP
        FETCH cur INTO fil;
        EXIT WHEN (cur%NOTFOUND);
        IF cur%NOTFOUND THEN
            DBMS_OUTPUT.PUT_LINE('NotFound');
        ELSE
            DBMS_OUTPUT.PUT_LINE(fil.name, fil.calories);
        END IF;
        END LOOP;
        CLOSE cur;
    END;
    /
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...