【问题标题】:How do I define another temporary variable and fetch into it?如何定义另一个临时变量并获取它?
【发布时间】:2020-08-05 13:09:11
【问题描述】:

这是我的代码;-

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

【问题讨论】:

    标签: oracle stored-procedures plsql oracle11g


    【解决方案1】:

    基本上你的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;
      /
      

    【讨论】:

      【解决方案2】:

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

      循环中的 IF 语句是完全没有必要的,因为它在执行时永远不会返回 True。如果是真的退出 它前面的语句将退出循环;因此没有消息。这是多余的;在已知结果的情况下进行测试。您可以颠倒顺序并将退出放在 IF...END 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;
      /
      

      作为风格问题

      • 避免使用 CamelCase 命名约定。 Oracle 总是将对象名称折叠为大写。因此,它只会使 Oracle 生成的引用难以阅读。请改用下划线 (_) 分隔的单词。
      • 与巴巴罗斯不同,我不考虑使用过程(函数, package, ...) 终止端的名称是多余的,但更多的是 关闭与“结束如果”一样多。是的,它在语法上是可选的,但是 optional 不一样是多余的。我总是行使这个选项。 所以发展了你的风格(受制于机构/客户要求 标准),但要与之保持一致。

      【讨论】:

        猜你喜欢
        • 2020-07-21
        • 2020-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 2022-11-23
        • 1970-01-01
        • 2019-01-29
        相关资源
        最近更新 更多