函数中的 Oracle Sys Refcurser

Oracle Sys Refcurser in a function

我在返回指向查询的指针时遇到了一些问题。

这是我当前的代码:

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;

可以找到 CREATE PROCEDURE 语法的 Oracle 文档 here

CREATE PROCEDURE 没有 return 子句(即 FUNCTIONs);您应该改用 OUT 参数并删除末尾的 return 语句。

您还需要使用OPEN cursor_name FOR执行SELECT查询并将其与游标相关联。

此外 - 您不需要 : 在过程的 header 中声明的变量前面。 :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;
/

或者如果你想使用绑定变量(在 PL/SQL 块之外):

VARIABLE route VARCHAR2;
VARIABLE routeday VARCHAR2;
VARIABLE rc REFCURSOR;

BEGIN
  route := 'abc';
  routeday := 'Tuesday';
END;
/    

BEGIN
  getRoute(
    in_route    => :route,
    in_routeday => :routeday,
    out_cursor  => :rc
  );
END;
/

PRINT :rc;