从表中选择所有的 Oracle 函数
Posted
技术标签:
【中文标题】从表中选择所有的 Oracle 函数【英文标题】:Oracle function with select all from tables 【发布时间】:2018-04-06 10:15:36 【问题描述】: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 中返回所有内容的函数。
谢谢
【问题讨论】:
没有加入条件?该查询没有多大意义...... 它给出了什么错误?? @jarlh 当我运行选择时,我得到了结果,所以选择很好。但我想要它的功能.. @NishantGupta sql 语句被忽略,qouted 标识符行尾,缺少双引号 抱歉,以下链接不是来自 SO,但绝对可以帮助您解决问题-sqljana.wordpress.com/2017/01/22/… 【参考方案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),您可以使用打印命令显示光标的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 developer 和 Toad 中作为脚本运行,您可以使用它获得结果。
VARIABLE r REFCURSOR;
EXEC getSoccerLists (:r);
PRINT r;
另一种选择是通过在包中定义结果记录类型的集合来使用 TABLE 函数。
参考Create an Oracle function that returns a table
【讨论】:
DBMS_SQL.RETURN_RESULT
仅适用于 Oracle 12c。
@Kaushik Nayak 当我像你写的那样我得到错误请 00302 必须声明组件 Return_result
@civesuas_sine:你应该使用 11g 吗?请参阅我的更新答案。【参考方案2】:
我猜这个问题是对您之前提出的问题的重复,您希望在其中获取表格的所有列但放入单独的列中。我已经回答说如果您通过SELECT
语句调用您的函数,您将无法做到这一点。如果你在匿名块中调用你的函数,你可以在单独的列中显示它。
这里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 个字符,那么您将再次丢失数据。
编辑:
来自你的 cmets
我希望它返回一组结果。
然后您需要创建一个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);
【讨论】:
@civesuas_sine。您需要放置实际的列。我不会为您提供现成的代码。这只是一个帮助您解决问题的演示。只需替换表的所有列,通过,
或|
将其分隔。
精确提取返回的行数超过了请求的行数
@civesuas_sine 这意味着您的查询在您的过滤子句中返回多行。如果是这种情况,那么您需要确保您的查询返回单行,或者您需要使用sys_refcursor
或贴花object
来返回结果集表
ORA-00955:名称已被现有对象使用,当我尝试运行语句时
@civesuas_sine 不确定您执行的是什么以及如何执行。我向您展示了一个工作演示。同样如前所述,您不能像图片中显示的那样做。最多可以使用,
或|
分隔结果并在单个列中显示结果,因为您要返回一个varchar 表。或者您需要创建一个表类型的对象然后使用它。见编辑2【参考方案3】:
这不是关于如何为此构建函数的答案,因为我建议将其设为视图:
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
子句放在最终查询中。)
【讨论】:
@ThorstenKettnerDont need view,你能用这个选择创建函数吗? 好吧,我只是觉得让一个函数做同样的事情是没有意义的。视图的唯一区别是它的速度较慢。如果你还是想写一个函数,你可能想查找流水线函数:oracle-base.com/articles/misc/pipelined-table-functions以上是关于从表中选择所有的 Oracle 函数的主要内容,如果未能解决你的问题,请参考以下文章