Oracle 如何定义另一个临时变量并将其提取?

Oracle 如何定义另一个临时变量并将其提取?,oracle,stored-procedures,plsql,oracle11g,Oracle,Stored Procedures,Plsql,Oracle11g,这是我的密码- 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.Nam

这是我的密码-

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

基本上,您的
过程
语句是好的,但有一些小问题,例如:

  • 将名称
    GetDeails
    转换为
    GetDetails
    ,以便 将名称与最后一个
    end
    end之后的末尾给出的名称匹配 关键词。实际上,两次使用
    过程的名称是多余的,因此,
    不需要

  • 在参数列表的后面应该有
    IS
    AS
    关键字,并且应该删除关键字
    DECLARE

  • DBMS\u OUTPUT.PUTLINE
    应转换为
    DBMS\u OUTPUT.PUT\u LINE
    , 在
    光标
    选择
    列表中应提供两个匹配列(
    Name
    GramCalories

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

基本上,您的
过程
语句是好的,但有一些小问题,例如:

  • 将名称
    GetDeails
    转换为
    GetDetails
    ,以便 将名称与最后一个
    end
    end之后的末尾给出的名称匹配 关键词。实际上,两次使用
    过程的名称是多余的,因此,
    不需要

  • 在参数列表的后面应该有
    IS
    AS
    关键字,并且应该删除关键字
    DECLARE

  • DBMS\u OUTPUT.PUTLINE
    应转换为
    DBMS\u OUTPUT.PUT\u LINE
    , 在
    光标
    选择
    列表中应提供两个匹配列(
    Name
    GramCalories

  • 游标属性不能应用于非游标
    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…END IF之后。但是“找不到”消息总是会产生的。您可以在循环后使用cur%rowcount来正确生成消息

      dbms输出输出行(fil.name,fil.carries)有2个错误

      • 不存在可变的热量。GramCalories在您的原始版本中未被选中(正如所指出的),在修订版中也没有别名。所以它不是游标的一部分,因此也不是 游标行类型
      • 它需要一个字符串参数,因为有两个参数
      考虑到这些因素,我们得到:

      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生成的引用难以读取。相反,请使用下划线(\)分隔的单词
      • 与Barbaros不同,我不考虑使用程序(函数), 包,…)终止端上的名称为冗余,但更多为 闭包与“如果结束”一样多。是的,它在语法上是可选的,但是 可选与冗余不同。我总是做这个选择。 因此形成了您的风格(取决于机构/客户要求 标准),但必须与之一致
          由@Barbaros提供的答案解决了您的大部分问题,但可以进一步完善

          循环中的IF语句完全没有必要,因为它在执行时永远不会返回True。如果这是真的,那就退出 它前面的语句将退出循环;因此没有任何信息。这是多余的;在已知结果的地方进行测试。你可以颠倒顺序,把出口放在IF…END IF之后。但是“找不到”消息总是会产生的。您可以在循环后使用cur%rowcount来正确生成消息

          dbms输出输出行(fil.name,fil.carries)有2个错误

          • 不存在可变的热量。GramCalories在您的原始版本中未被选中(正如所指出的),在修订版中也没有别名。所以它不是游标的一部分,因此也不是 游标行类型
          • 它需要一个字符串参数,因为有两个参数
          考虑到这些因素,我们得到:

          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生成的引用难以读取。相反,请使用下划线(\)分隔的单词
          • 与Barbaros不同,我不考虑使用程序(函数), 包,…)终止端上的名称为冗余,但更多为 闭包与“如果结束”一样多。是的,它在语法上是可选的,但是 可选与冗余不同。我总是做这个选择。 因此形成了您的风格(取决于机构/客户要求 标准),但必须与之一致