WITH子句中的PL/SQL
Posted
技术标签:
【中文标题】WITH子句中的PL/SQL【英文标题】:PL/SQL inside WITH clause 【发布时间】:2017-02-10 15:38:59 【问题描述】:不行,在WITH
子句里不行吗?
WITH start1 AS
(
BEGIN
EXECUTE immediate 'Select 1 from dual';
END;
)
SELECT * FROM start1
【问题讨论】:
您正试图在一段 SQL 代码中使用 PLSQL 块,而不管 WITH。这行不通。你需要做什么? 您使用的是哪个版本的 Oracle?我相信 12c 可以做到这一点。请参阅此oracle.com/technetwork/database/features/plsql/… 的第 9 页。 看起来您使用的是 Oracle 12,它允许 WITH 子句中的函数和过程。但是你在这里想要做什么还不清楚。start1
似乎是一个过程(反正语法是错误的); select * from start1
是什么意思?从程序中选择是什么意思?这没有任何意义。
“它不起作用”是什么意思 - 至少告诉我们会发生什么,以及您的预期。除了已经提到的事情之外,您的动态查询无论如何都不会执行,因为它没有选择 into 任何东西。但是你似乎在尝试的东西无论如何都没有意义。
【参考方案1】:
如果您尝试在 WITH
子句中使用允许 PL/SQL 的 Oracle 12c 功能,则说明您没有正确使用它。
请记住,您提交的每个 SQL 语句都必须有一组明确定义的列,它将返回。牢记这一点,您将有两种选择来完成您所追求的目标。
选项 1 -- 在 SELECT 结果中返回一个游标
此选项不要求您知道动态 SQL 语句的行类型,但无论谁/什么消耗您的查询结果,都需要获取和处理游标。像这样:
with function start1 return sys_refcursor is
l_rc SYS_REFCURSOR;
BEGIN
OPEN l_rc FOR 'SELECT 1 FROM DUAL';
RETURN l_rc;
END;
select start1 from dual;
START1
----------------
(Cursor)
The (cursor) value in the result set is the result set of the dynamic SQL statement (i.e., `SELECT 1 FROM DUAL`).
选项2——提前了解和使用动态SQL的rowtype
此选项要求您为动态 SQL 的行类型创建一个对象类型和一个行类型的表。
CREATE OR REPLACE TYPE rc_rowtype IS OBJECT ( val NUMBER );
CREATE OR REPLACE TYPE rc_tabtype IS TABLE OF rc_rowtype;
with function start1 return rc_tabtype is
l_results rc_tabtype;
l_rc SYS_REFCURSOR;
BEGIN
OPEN l_rc FOR 'SELECT rc_rowtype(1) FROM DUAL';
FETCH l_rc BULK COLLECT INTO l_results;
CLOSE l_rc;
DBMS_OUTPUT.PUT_LINE('l_results.COUNT = ' || l_results.count);
RETURN l_results;
END;
select * FROM table(start1);
VAL
---
1
【讨论】:
可以构建返回动态结果集的 SQL 语句,例如我的回答 here。但在实践中,这几乎不是人们想要做的。除非 OP 有一些极端情况,否则他几乎肯定应该使用您的建议之一。以上是关于WITH子句中的PL/SQL的主要内容,如果未能解决你的问题,请参考以下文章
oracle(sql)基础篇系列——PLSQL游标存储过程触发器