用于解决使用多值循环但出现错误的问题

时间:2019-06-20 05:02:45

标签: oracle plsql

  

ORA-06550:第10行,第89栏:
      PLS-00103:遇到符号“;”当期望以下之一时:

        *&-+ /在mod余数rem .. ||          多集年份的天

    CREATE OR REPLACE PROCEDURE SALE
    (OUTLETID  IN number,itemCod IN number,START_Date IN DATE, END_DATE IN DATE,OUTLETID1  out number,itemCod1 out number,AMOUNT OUT NUMBER,Quantity OUT NUMBER,Entry_Date out date )IS 
    BEGIN 
      select l.OUTLET_ID,itemCode,
             Sum(Amount)Amount,sum(quantity)Quantity,
             i.Entry_Date  
    INTO OUTLETID1,itemCod1,
         AMOUNT,Quantity,
         Entry_Date 
    from IDSTRANSACTION i 
    join lup_outlet l on l.OUTLET_ID=i.outlet_id 
    JOIN LUP Z ON Z.ZONE_ID=L.ZONE_ID 
    join prod p on p.serial =itemCode 
    join lup_master m on  m.sup_id = p.Supplier_ID 
    where l.OUTLET_ID in (OUTLETID ) 
    and  itemCode in (itemCod) 
    and to_date(i.Entry_Date) between START_Date and END_DATE 
    group by l.OUTLET_ID,itemCode,i.Entry_Date
     END;
    ----------
    declare 
       var number; 
       var1 number; 
       var2 number;
       var3 number;
       var4 date;
    begin 
      for c in (SALE( OUTLETID  => 809,itemCod  => 128169, START_Date=>DATE '2018-01-01',end_Date=>DATE '2019-01-01',  AMOUNT => var,Quantity => var1,OUTLETID1 => var2,itemCod1 => var3,Entry_Date => var4));
     loop 
       var:=c.AMOUNT; 
       var1:=c.Quantity; 
       var2:=c.OUTLETID1; 
       var3:=c.itemCod1; 
       var4:=c.Entry_Date; 
       dbms_output.enable; 
       dbms_output.put_line(var); 
       dbms_output.enable;  
       dbms_output.put_line(var1);  
       dbms_output.enable;  
       dbms_output.put_line(var2);  
       dbms_output.enable;  
       dbms_output.put_line(var3); 
       dbms_output.enable;  
       dbms_output.put_line(var4);   
    end loop;
  End;

2 个答案:

答案 0 :(得分:1)

您缺少分号,而在第二个过程中又添加了一个分号,这就是为什么代码格式很重要的原因:

      CREATE OR REPLACE PROCEDURE sale (
        outletid     IN           NUMBER,
        itemcod      IN           NUMBER,
        start_date   IN           DATE,
        end_date     IN           DATE,
        outletid1    OUT          NUMBER,
        itemcod1     OUT          NUMBER,
        amount       OUT          NUMBER,
        quantity     OUT          NUMBER,
        entry_date   OUT          DATE
      ) IS
      BEGIN
        SELECT
          l.outlet_id,
          itemcode,
          SUM(amount) amount,
          SUM(quantity) quantity,
          i.entry_date
        INTO
          outletid1,
          itemcod1,
          amount,
          quantity,
          entry_date
        FROM
          idstransaction   i
          JOIN lup_outlet       l ON l.outlet_id = i.outlet_id
          JOIN lup              z ON z.zone_id = l.zone_id
          JOIN prod             p ON p.serial = itemcode
          JOIN lup_master       m ON m.sup_id = p.supplier_id
        WHERE
          l.outlet_id IN (
            outletid
          )
          AND itemcode IN (
            itemcod
          )
          AND TO_DATE(i.entry_date) BETWEEN start_date AND end_date
        GROUP BY
          l.outlet_id,
          itemcode,
          i.entry_date; -- THE SEMICOLON MISSING HERE

      END;
        ----------

      DECLARE
        var    NUMBER;
        var1   NUMBER;
        var2   NUMBER;
        var3   NUMBER;
        var4   DATE;
      begin for c
      in(sale(outletid => 809, itemcod => 128169, start_date => DATE '2018-01-01', end_date => DATE '2019-01-01', amount => var, quantity
      => var1, outletid1 => var2, itemcod1 => var3, entry_date => var4)) -- ; REMOVE THE SEMICOLON HERE

      LOOP
        var := c.amount;
        var1 := c.quantity;
        var2 := c.outletid1;
        var3 := c.itemcod1;
        var4 := c.entry_date;
        dbms_output.enable;
        dbms_output.put_line(var);
        dbms_output.enable;
        dbms_output.put_line(var1);
        dbms_output.enable;
        dbms_output.put_line(var2);
        dbms_output.enable;
        dbms_output.put_line(var3);
        dbms_output.enable;
        dbms_output.put_line(var4);
      END LOOP;

      end;

答案 1 :(得分:0)

我将其重写如下:

  • 一切都在SALE过程中
    • SELECT语句将在游标FOR循环中使用
  • 仅需要IN参数(因为您不再返回任何内容)
    • p_为前缀,这样它们的名称和列名之间就不会混淆
  • 您不需要声明的变量;光标返回的参考值
  • 在引用列时使用表别名。例如,在sum(amount)中,amount列属于哪个表?只要您可能知道,任何人(将继承您的代码)都将面临一场噩梦,试图找出答案
  • i.entry_date看起来像它的数据类型是DATE(是的,它应该是DATE)。如果要将日期存储到varchar2(或number?)列中,请不要这样做-如有可能,请切换到DATE。如果没有,请对to_date函数应用格式掩码。 Oracle将尝试将一种数据类型隐式转换为另一种数据类型,现在它甚至可以工作,但是-如果环境发生变化,此类代码将失败

create or replace procedure sale
  (p_outletid    in number,    --> use prefixes for parameters so that they ...
   p_itemcod     in number,    --> ... are easy to distinguish between column names
   p_start_date  in date, 
   p_end_date    in date,
  ) 
is 
begin           
  for c in (select l.outlet_id,
                   itemcode,               --> include table aliases, wherever they ...
                   sum(amount) amount,     --> ... are missing
                   sum(quantity) quantity,
                   i.entry_date  
            from idstransaction i 
              join lup_outlet l on l.outlet_id = i.outlet_id 
              join lup z on z.zone_id = l.zone_id 
              join prod p on p.serial = itemcode 
              join lup_master m on m.sup_id = p.supplier_id 
            where l.outlet_id = p_outletid
              and itemcode = p_itemcod 
              and to_date(i.entry_date) between p_start_date   --> if I.ENTRY_DATE is DATE, then ...
                                            and p_end_date     --> ... remove TO_DATE. Otherwise, ...
            group by l.outlet_id,                              --> ... apply correct format mask
                     itemcode,
                     i.entry_date
           )
  loop
    dbms_output.put_line(c.outlet_id); 
    dbms_output.put_line(c.itemcode);  
    dbms_output.put_line(c.amount);  
    dbms_output.put_line(c.quantity); 
    dbms_output.put_line(c.entry_date);   
  end loop;
end;