如何在“流水线表函数”、视图和显式游标之间进行选择
Posted
技术标签:
【中文标题】如何在“流水线表函数”、视图和显式游标之间进行选择【英文标题】:How to choose between "pipelined table function" , view , and explicit cusor 【发布时间】:2020-06-14 12:25:39 【问题描述】:我会先说我认为我理解的内容。
使用显式游标是因为我们需要稍后重用查询。
如果使用非显式游标(即cs in (select .........)
),则每次使用游标时都会重新执行请求。因此使用显式游标以提高效率。
为了分解代码,我们可以使用“流水线表函数”或“视图”来创建游标。 我想知道为什么我应该使用一种解决方案而不是另一种解决方案。
以下是我了解的这些解决方案的优缺点:
既不赞成也不反对
我可以使用 select 语句提取视图或流水线表函数的一部分。
骗局
必须声明“流水线表”使用的记录类型和表类型。需要时间
专业人士: 我们可以在流水线表(例如循环)中使用 pl/sql 语句的所有可能性
我所说的都是真的吗? 还有其他我应该知道的事情吗?
【问题讨论】:
【参考方案1】:对于这两种游标类型,数据库在打开时都会执行其中的语句。如果游标保持打开状态,您可以稍后从中获取结果而无需重新运行它。所以在这方面两者都同样有效。
显式游标是您可以控制其整个生命周期的游标:打开、获取和关闭。使用隐式游标,PL/SQL 会为您处理。
当您想要完全控制提取过程时,您可以使用显式游标。这个bulk collection with a limit的主要用例。
如果您想在应用程序的许多地方使用相同的查询,显式游标也很方便。在包级别声明它,你可以在任何你喜欢的地方引用它:
create or replace package pkg as
cursor common_cursor is
select ...
end;
这为查询提供了一个单一的定义,这可以使您的代码更易于维护。这样做的问题是,无论您在哪里使用它,您都需要打开、获取和关闭它。在大多数情况下,这会产生更多的代码,而收益却很小。
这给我们带来了意见。您可以将公共查询放在视图中,而不是声明公共游标:
create or replace view common_query as
select ...;
然后您可以在任何其他 SQL 语句中使用它,就像在常规表中一样。所以你可以加入它,等等。你不能直接使用显式游标来做到这一点。您必须将其包装在 (pipelined) table function:
create or replace function pipetf
return ...
pipelined
as
retvals ...;
begin
open pkg.common_cursor;
loop
fetch pkg.common_cursor
bulk collect into retvals limit 100;
exit when retvals.count = 0;
for i in 1 .. retvals.count loop
pipe row ( retvals ( i ) ) ;
end loop;
end loop;
close pkg.common_cursor ;
return;
end pipetf;
/
这允许您在另一个 SQL 语句(如视图)中使用游标:
select * from pipetf;
在这一点上,流水线表函数似乎比视图要复杂得多。那何必呢?
它可以让你做一些视图不能做的事情(很容易):
以程序方式生成新行或操作结果集 创建参数化查询一般来说,您不能将变量传递给像这样的查询(有一些方法,但它们带有陷阱):
select c2 from ...
where c1 = :var
group by c2;
而您可以在显式光标中:
cursor common_cursor ( var int ) is
select c2 from ...
where c1 = var
group by c2;
因此您可以在 PTF 中使用它来创建可重用的参数化查询:
create or replace function pipetf ( var int )
return ...
pipelined
as
retvals ...;
begin
open pkg.common_cursor ( var );
loop
fetch pkg.common_cursor
bulk collect into retvals limit 100;
exit when retvals.count = 0;
for i in 1 .. retvals.count loop
pipe row ( retvals ( i ) ) ;
end loop;
end loop;
close pkg.common_cursor ;
return;
end pipetf;
/
因此,如果您需要使用 PL/SQL 来创建新行、操作查询结果或想要可重用的参数化查询,那么流水线表函数是可行的方法.
为什么?
Oracle Database 18c 添加了polymorphic table functions,它涵盖了许多行生成/结果操作示例。从 19.6 开始,您可以创建 SQL 宏,您可以将其用于emulate parameterized views。这些功能涵盖了流水线表函数(以及更多)的大部分(全部?)用例。
如果您只需要一个无需额外处理的可重用查询,我会坚持使用视图。
【讨论】:
很好的答案和解释! 这很有趣。以上是关于如何在“流水线表函数”、视图和显式游标之间进行选择的主要内容,如果未能解决你的问题,请参考以下文章