Oracle函数,从表

时间:2018-04-06 10:15:36

标签: sql oracle

SELECT DISTINCT L.* FROM LABALES L , MATCHES M 
WHERE M.LIST LIKE '%ENG' 
ORDER BY L.ID

我需要使用此选择创建函数,我尝试了这个但它不起作用。

CREATE OR REPLACE FUNCTION getSoccerLists
RETURN varchar2  IS 
list varchar2(2000);
BEGIN
   SELECT DISTINCT L.* FROM LABALES L , MATCHES M 
   WHERE M.LIST LIKE '%ENG' 
   ORDER BY L.ID
   return list;
END;

如何创建从表L返回所有内容的函数。

由于

3 个答案:

答案 0 :(得分:1)

您可以在使用游标指向查询的过程中使用DBMS_SQL.RETURN_RESULT(Oracle12c及更高版本)使用隐式结果。

CREATE OR REPLACE PROCEDURE getSoccerLists 
AS
x SYS_REFCURSOR;
BEGIN
  OPEN x FOR SELECT DISTINCT L.* FROM LABALES L 
   JOIN  MATCHES M  ON ( 1=1 ) -- join condition
       WHERE M.LIST LIKE '%ENG' 
       ORDER BY L.ID; 
   DBMS_SQL.RETURN_RESULT(x);
END;
/

然后只需调用程序

EXEC getSoccerLists;

对于较低版本(Oracle 11g),您可以使用print命令显示光标的o / p,将ref cursor作为out参数传递。

CREATE OR REPLACE PROCEDURE getSoccerLists (x OUT SYS_REFCURSOR) 
AS
BEGIN
  OPEN x FOR SELECT DISTINCT L.* FROM LABALES L 
   JOIN  MATCHES M  ON ( 1=1 ) -- join condition
       WHERE M.LIST LIKE '%ENG' 
       ORDER BY L.ID; 
END;
/

然后,在SQL * Plus中或在SQL开发人员和Toad中作为脚本运行,您可以使用它来获得结果。

VARIABLE r REFCURSOR;
EXEC  getSoccerLists (:r);

PRINT r;

另一个选择是通过在包中定义结果的记录类型的集合来使用TABLE函数。

参考Create an Oracle function that returns a table

答案 1 :(得分:0)

我想这些问题是您之前提出的问题的重复,您想要获取表格的所有列,而不是单独的列。我已经回答说过如果你通过SELECT声明调用你的函数你不能这样做。如果您在Anoymous块中调用函数,则可以在单独的列中显示它。

此处Oracle function returning all columns from tables

或者,您可以使用逗号(,)或竖线(|)分隔结果,如下所示:

CREATE OR REPLACE
  FUNCTION getSoccerLists
    RETURN VARCHAR2
  IS
    list VARCHAR2(2000);
  BEGIN
    SELECT col1
      ||','
      ||col2
      ||','
      ||col2
    INTO LIST
    FROM SOCCER_PREMATCH_LISTS L ,
      SOCCER_PREMATCH_MATCHES M
    WHERE M.LIST LIKE '%' || (L.SUB_LIST)  || '%'
    AND (TO_TIMESTAMP((M.M_DATE      || ' '      || M.M_TIME), 'DD.MM.YYYY HH24:MI') >
      (SELECT SYSTIMESTAMP AT TIME ZONE 'CET' FROM DUAL
      ))
    ORDER BY L.ID");
  Return list;
  End;

请注意,如果列大小增加了2000个字符,那么您将再次丢失数据。

编辑:

来自您的评论

  

我希望它返回一组表格结果。

然后,您需要创建一个varchar表,然后从该函数返回它。见下文:

CREATE TYPE var IS  TABLE OF VARCHAR2(2000);
/

CREATE OR REPLACE
FUNCTION getSoccerLists
  RETURN var
IS
  --Initialization
  list VAR :=var();
BEGIN
  SELECT NSO ||',' ||NAME BULK COLLECT INTO LIST FROM TEST;
  RETURN list;
END;

执行:

select * from table(getSoccerLists);

注意:在函数中我使用了一个名为test的表及其列。用表名替换表。

编辑2:

--Create a object with columns same as your select statement
CREATE   TYPE v_var IS  OBJECT
(
col1 NUMBER,
col2 VARCHAR2(10)
)
/
--Create a table of your object
CREATE OR REPLACE TYPE var IS TABLE OF v_var;
/

CREATE OR REPLACE FUNCTION getSoccerLists
  RETURN var
IS
  --Initialization
  list VAR :=var();
BEGIN
   --You above object should have same columns with same data type as you are selecting here 
  SELECT v_var( NSO ,NAME) BULK COLLECT INTO LIST FROM TEST;
  RETURN list;
END;

执行:

select * from table(getSoccerLists);

答案 2 :(得分:0)

这不是关于如何为此构建函数的答案,因为我建议将其改为视图:

CREATE OR REPLACE VIEW view_soccer_list AS
  SELECT * 
  FROM soccer_prematch_lists l
  WHERE EXISTS
  (
    SELECT *
    FROM soccer_prematch_matches m 
    WHERE m.list LIKE '%' || (l.sub_list) || '%' 
      AND TO_TIMESTAMP((m.m_date || ' ' || m.m_time), 'DD.MM.YYYY HH24:MI') > 
            (SELECT SYSTIMESTAMP AT TIME ZONE 'CET' FROM DUAL)
  );

然后在查询中调用它:

SELECT * FROM view_soccer_list ORDER BY id;

(在视图中放置ORDER BY子句是没有意义的,因为您像表一样访问视图,并且表数据被认为是无序的,因此您不能依赖该顺序。同样如此对于使用FROM TABLE (getSoccerLists)访问的流水线函数。请始终将ORDER BY子句放在最终查询中。)