从动态 SQL 打开游标时出错
Posted
技术标签:
【中文标题】从动态 SQL 打开游标时出错【英文标题】:Error opening cursor from dynamic SQL 【发布时间】:2016-04-07 13:58:19 【问题描述】:我正在使用 Oracle PL/SQL 游标。我创建了一个光标,但我无法打开它。我收到如下错误:
Error(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】:您的光标声明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
需要字段来保存这些列。
您还缺少MainQuery1
、FinalQuery1
、CommonFilterCluase
、NumberOfUldsDistinctEntires
的声明 - 尽管您可能没有在问题中显示这些声明。根据 CommonFilterCluase
包含的内容,您可能需要在串联中使用另一个空格。您没有使用 uldid
或 flightlegid
变量。以此类推。
【讨论】:
以上是关于从动态 SQL 打开游标时出错的主要内容,如果未能解决你的问题,请参考以下文章
连接数据库时出错:(使用类org.gjt.mm.mysql.Driver)语句(1)没有打开游标