如何定义另一个临时变量并获取它?



这是我的代码;-

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;
/

基本上你的PROCEDURE语句很好,但有一些小问题,例如:

  • 将名称GetDeails转换为GetDetails,以便 将名称与最后一个END后末尾给出的名称匹配 关键词。事实上,两次使用PROCEDURE的名字是多余的,所以, 不需要。

  • IN参数列表后面应该有ISAS关键字,并且应该删除关键字DECLARE

  • DBMS_OUTPUT.PUTLINE应转换为DBMS_OUTPUT.PUT_LINE, 并且应该在CURSORSELECT列表中提供两个匹配的列(NameGramCalories)。

  • 游标
  • 属性不能应用于非游标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;
    /
    

@Barbaros的答案解决了您的大部分问题,但可以进一步完善。

循环中的 IF 语句是完全不必要的,因为它在执行时永远不会返回 True。如果这是真的,退出 它前面的语句将退出循环;因此没有消息。这是多余的;在结果已知的情况下进行测试。 您可以颠倒顺序并将退出放在 IF...如果结束。但是,始终会生成"未找到"消息。您可以在循环后使用 cur%rowcount 来正确生成消息。

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;
/

作为风格问题

  • 避免驼峰命名约定。Oracle 始终将对象名称折叠为大写。因此,它只会使 Oracle 生成的引用难以阅读。请改用下划线 (_) 分隔的单词。
  • 与巴巴罗斯不同,我不考虑使用该程序(功能, 包装,...终止端的名称是多余的,但更像是一个 关闭和"结束如果"一样多。是的,它在语法上是可选的,但是 可选与冗余不同。我总是行使这个选择。 所以发展了你的风格(取决于机构/客户的要求) 标准),但要与之保持一致。

最新更新