Sql 函数中的Oracle Sys Refcurser

Sql 函数中的Oracle Sys Refcurser,sql,oracle,plsql,sys-refcursor,Sql,Oracle,Plsql,Sys Refcursor,返回指向查询的指针时遇到问题 这是我目前的代码: create or replace procedure getRoute(route IN varchar, routeday IN varchar) return sys_refcursor is v_rc sys_refcursor; begin select DISTINCT BBT_JOURNEYSTOPS.SERVICE "Service", BBT_JOURNEYSTOPS.STOP_REFERENCE "StopNo

返回指向查询的指针时遇到问题

这是我目前的代码:

create or replace procedure getRoute(route IN varchar, routeday IN varchar)
  return sys_refcursor is
  v_rc sys_refcursor;
begin
    select DISTINCT BBT_JOURNEYSTOPS.SERVICE "Service", BBT_JOURNEYSTOPS.STOP_REFERENCE "StopNo", 
  STOP_NAME "Near", BBT_STOPS.ROAD_NAME "On", BBT_JOURNEYSTOPS.JOURNEYTIME "Duration"    
    from BBT_JOURNEYSTOPS
    inner join BBT_WEEKLYSCHEDULE
    on BBT_WEEKLYSCHEDULE.SERVICE = BBT_JOURNEYSTOPS.SERVICE
    inner join BBT_STOPS
    on BBT_JOURNEYSTOPS.STOP_REFERENCE = BBT_STOPS.STOPREF
    where  (UPPER(BBT_JOURNEYSTOPS.SERVICE) LIKE UPPER('%'|| :route || '%')) AND 
      (TO_NUMBER(SUBSTR(BBT_WEEKLYSCHEDULE.TIMEUNTIL, 1, 2)) > TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')))
    ORDER BY BBT_JOURNEYSTOPS.SERVICE, BBT_JOURNEYSTOPS.JOURNEYTIME;


  return timetable;
end;
/

DECLARE
 rc refcursor;
BEGIN
  exec :rc := getRoute(:route, :routeday);
END;

我在第一行看到一个语法错误,说“Expected AUTHID,EXTERNAL”,但是我也不确定我编写的代码是否也能正确执行。任何提示或提示都将不胜感激。

您应该使用
OPEN FOR
语法和函数,而不是过程,也可以使用
正文代码中不需要的参数

create or replace function getRoute(route IN varchar, routeday IN varchar)
  return sys_refcursor is
  v_rc sys_refcursor;
begin
    open v_rc  FOR
    select DISTINCT BBT_JOURNEYSTOPS.SERVICE "Service", BBT_JOURNEYSTOPS.STOP_REFERENCE "StopNo", 
  STOP_NAME "Near", BBT_STOPS.ROAD_NAME "On", BBT_JOURNEYSTOPS.JOURNEYTIME "Duration"    
    from BBT_JOURNEYSTOPS
    inner join BBT_WEEKLYSCHEDULE
    on BBT_WEEKLYSCHEDULE.SERVICE = BBT_JOURNEYSTOPS.SERVICE
    inner join BBT_STOPS
    on BBT_JOURNEYSTOPS.STOP_REFERENCE = BBT_STOPS.STOPREF
    where  (UPPER(BBT_JOURNEYSTOPS.SERVICE) LIKE UPPER('%'|| route || '%')) AND 
      (TO_NUMBER(SUBSTR(BBT_WEEKLYSCHEDULE.TIMEUNTIL, 1, 2)) > TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')))
    ORDER BY BBT_JOURNEYSTOPS.SERVICE, BBT_JOURNEYSTOPS.JOURNEYTIME;


  return v_rc ;
end;
/

此外,您不能在pl\sql代码中使用
EXEC

DECLARE
 rc refcursor;
BEGIN
  :rc := getRoute(:route, :routeday);
END;

可以找到有关
创建过程
语法的Oracle文档

创建过程
没有返回子句(即用于
函数
s);您应该改用
OUT
参数,并删除末尾的return语句

您还需要使用
opencursor\u name FOR
执行
SELECT
查询并将其与光标关联

另外-在过程头中声明的变量前面不需要
:name
语法用于SQL中的绑定变量-PL/SQL在不使用该语法的情况下自动处理变量绑定

(您似乎没有使用
routeday
参数,因此如果将来不使用它,可以将其删除)

大概是这样的:

create or replace procedure getRoute(
  in_route      IN  varchar,
  in_routeday   IN  varchar,
  out_cursor    OUT SYS_REFCURSOR
)
is
begin
    OPEN out_cursor FOR
    select DISTINCT BBT_JOURNEYSTOPS.SERVICE "Service",
                    BBT_JOURNEYSTOPS.STOP_REFERENCE "StopNo",
                    STOP_NAME "Near",
                    BBT_STOPS.ROAD_NAME "On",
                    BBT_JOURNEYSTOPS.JOURNEYTIME "Duration"    
    from BBT_JOURNEYSTOPS
         inner join BBT_WEEKLYSCHEDULE
         on BBT_WEEKLYSCHEDULE.SERVICE = BBT_JOURNEYSTOPS.SERVICE
         inner join BBT_STOPS
         on BBT_JOURNEYSTOPS.STOP_REFERENCE = BBT_STOPS.STOPREF
    where  (UPPER(BBT_JOURNEYSTOPS.SERVICE) LIKE UPPER('%'|| in_route || '%'))
    AND    (TO_NUMBER(SUBSTR(BBT_WEEKLYSCHEDULE.TIMEUNTIL, 1, 2)) > TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')))
    ORDER BY BBT_JOURNEYSTOPS.SERVICE, BBT_JOURNEYSTOPS.JOURNEYTIME;
end;
/
DECLARE
  route VARCHAR2 := 'abc';
  routeday VARCHAR2 := 'Tuesday';
  rc SYS_REFCURSOR;
BEGIN
  getRoute(
    in_route    => route,
    in_routeday => routeday,
    out_cursor  => rc
  );
END;
/

您也可以考虑使用强类型游标代替弱光标。< /P> 你可以这样称呼它:

create or replace procedure getRoute(
  in_route      IN  varchar,
  in_routeday   IN  varchar,
  out_cursor    OUT SYS_REFCURSOR
)
is
begin
    OPEN out_cursor FOR
    select DISTINCT BBT_JOURNEYSTOPS.SERVICE "Service",
                    BBT_JOURNEYSTOPS.STOP_REFERENCE "StopNo",
                    STOP_NAME "Near",
                    BBT_STOPS.ROAD_NAME "On",
                    BBT_JOURNEYSTOPS.JOURNEYTIME "Duration"    
    from BBT_JOURNEYSTOPS
         inner join BBT_WEEKLYSCHEDULE
         on BBT_WEEKLYSCHEDULE.SERVICE = BBT_JOURNEYSTOPS.SERVICE
         inner join BBT_STOPS
         on BBT_JOURNEYSTOPS.STOP_REFERENCE = BBT_STOPS.STOPREF
    where  (UPPER(BBT_JOURNEYSTOPS.SERVICE) LIKE UPPER('%'|| in_route || '%'))
    AND    (TO_NUMBER(SUBSTR(BBT_WEEKLYSCHEDULE.TIMEUNTIL, 1, 2)) > TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')))
    ORDER BY BBT_JOURNEYSTOPS.SERVICE, BBT_JOURNEYSTOPS.JOURNEYTIME;
end;
/
DECLARE
  route VARCHAR2 := 'abc';
  routeday VARCHAR2 := 'Tuesday';
  rc SYS_REFCURSOR;
BEGIN
  getRoute(
    in_route    => route,
    in_routeday => routeday,
    out_cursor  => rc
  );
END;
/
或者如果您确实希望使用绑定变量(在PL/SQL块之外):


感谢您的帮助,但不幸的是,我仍然得到了语法错误,正如前面在Oracle SQL Developer中提到的那样。我想回答这个问题的另一个人把它分类了——这是因为我使用的是程序,但使用的是返回线!正如我在回答中所说,您应该将
函数
返回一起使用。并删除PLSQL代码中的
exec
,这真是太棒了,非常有用!非常感谢:)当我尝试调用该过程时,我收到一条错误消息,其中有:错误报告-ORA-06550:第4行,第9列:PLS-00222:此范围内不存在名为“GETROUTE”的函数ORA-06550:第4行,第3列:PL/SQL:语句忽略06550。00000-“行%s,列%s:\n%s”*原因:通常是PL/SQL编译错误*操作:我使用此代码调用以下过程:DECLARE rc SYS\u REFCURSOR;开始rc:=getRoute(:route,:routeday,rc);终止知道为什么它说找不到程序吗?它编译时没有错误吗?(在
创建过程之后运行
显示错误
进行检查)。否则,您是从同一个用户调用它吗?可能的重复是将一个过程与一个函数混合在一起。创建一个返回ref游标的函数,或者创建一个以ref游标作为OUT参数的过程。