从动态SQL打开游标时出错

时间:2016-04-07 13:58:20

标签: oracle plsql cursor

我正在使用Oracle PL / SQL游标。我创建了一个游标,但我无法打开它。我收到的错误如下:

  

错误(51,13):PLS-00320:此表达式类型的声明不完整或格式错误

我也会因打开游标语句而出错。

这是我的代码:

DECLARE

   uldid uldlog.uldid%type;
   flightlegid uldlog.flightlegid%type;  
   TYPE rec IS RECORD (uldid number, uldlog number);
   --CURSOR some_cursor RETURN rec;
   CURSOR distUld return rec;  
   ress rec;


BEGIN

      MainQuery1 :='select uldlog.uldid, uldlog.flightlegid 
      from uldlog
      INTO distUld
      INNER JOIN flightulds ON uldlog.uldid = flightulds.flightuldsid 
      INNER JOIN M_ULDTYP ON FLIGHTULDS.ULDTYPEID = M_ULDTYP.ULDTYPID 
      INNER JOIN FLIGHTLEG ON FLIGHTLEG.FLIGHTLEGID = FLIGHTULDS.INFLIGHTLEGID
      INNER JOIN FLIGHTS ON FLIGHTLEG.FLIGHTID = FLIGHTS.FLIGHTID
      INNER JOIN M_AIRLINE A on A.AIRLINEID = FLIGHTS.AIRLINEID
      INNER JOIN m_flighttyp on m_flighttyp.Id=FLIGHTLEG.SERVICETYPEID  
      INNER JOIN m_pax_fr on m_pax_fr.id=m_flighttyp.pax_fr_id
      where flightulds.uldtypeid IN (3,4,5,8,9)';          

      FinalQuery1 := MainQuery1 || CommonFilterCluase || ' GROUP BY uldlog.uldid, uldlog.flightlegid';
      EXECUTE IMMEDIATE FinalQuery1;          

   OPEN distUld;
   LOOP 
      FETCH distUld into ress;
      EXIT WHEN distUld%notfound;
      NumberOfUldsDistinctEntires := NumberOfUldsDistinctEntires +1;   
      IF fn_bdtimedifference(uldid,flightlegid,FlightTypeIds,CargoType,CargoPriority,UldTypes,SlaStatusCommaSeparatedNumbers) is null then
      Bd_Avg_Time := Bd_Avg_Time + 0;
      Else 
      Bd_Avg_Time := Bd_Avg_Time + fn_bdtimedifference(uldid,flightlegid,FlightTypeIds,CargoType,CargoPriority,UldTypes,SlaStatusCommaSeparatedNumbers);
    END IF;
   END LOOP;
   CLOSE distUld; 
END;

我做错了什么?

1 个答案:

答案 0 :(得分:2)

您的游标声明CURSOR distUld return rec错误。看起来你正试图这样做:

TYPE distUld IS REF CURSOR return rec

但是you can't use a strongly-typed ref cursor with dynamic SQL。所以你不能有回报。您还需要一个该类型的实例,而不是execute immediate - 它不应该有into子句 - 您可以动态打开引用游标:

DECLARE
  ...
  TYPE distUldType IS REF CURSOR;
  distUld distUldType;
BEGIN
   MainQuery1 :='select uldlog.uldid, uldlog.flightlegid 
      from uldlog
      INNER JOIN flightulds ON uldlog.uldid = flightulds.flightuldsid 
      ...';
   FinalQuery1 := ...;

   OPEN distUld FOR FinalQuery1;
   LOOP 
      FETCH distUld into ress;
      EXIT WHEN distUld%notfound;
      NumberOfUldsDistinctEntires := NumberOfUldsDistinctEntires +1;   
      IF fn_bdtimedifference(ress.uldid, ress.flightlegid,
         ress.FlightTypeIds, ...) is null then
      ...
   END LOOP;
   CLOSE distUld;
END;

还有其他问题超出原始错误的范围,但实质上rec必须为您在游标查询中选择的每个列都有字段,并且游标查询必须选择您想要的每一列作为参数传递给您的函数,并且这些调用必须使用ress记录变量限定字段名称。因此,您的查询必须从相应的表中获取FlightTypeIds等;并且rec需要字段来保存这些列。

您还缺少MainQuery1FinalQuery1CommonFilterCluaseNumberOfUldsDistinctEntires的声明 - 尽管您可能没有在问题中显示这些声明。根据{{​​1}}包含的内容,您可能需要在连接中添加另一个空格。您没有使用CommonFilterCluaseuldid个变量。等等。