Oracle 如何重用子查询
我有一个很长的存储过程。在存储过程中,括号中的子查询多次重复Oracle 如何重用子查询,oracle,oracle11g,subquery,Oracle,Oracle11g,Subquery,我有一个很长的存储过程。在存储过程中,括号中的子查询多次重复 and datasetid IN (select datasetid from Reportingdatasetmembers where ReportingDatasetID = param_in_ReportingDataSetID) 既然代码重复了,我可以合并它吗?也就是说,在SQL Server中,我会声明一个表变量。然后将行插入表变量。然后查询表变量。至少,这有助于应用干燥原理 在Oracle中是否有类似的
and datasetid IN
(select datasetid from Reportingdatasetmembers
where ReportingDatasetID = param_in_ReportingDataSetID)
既然代码重复了,我可以合并它吗?也就是说,在SQL Server中,我会声明一个表变量。然后将行插入表变量。然后查询表变量。至少,这有助于应用干燥原理
在Oracle中是否有类似的方法来整合此功能?Oracle表集合似乎不是减少代码基础的关键
我认为CTE是不可能的,因为它们不能重复使用?在其他数据库平台中也称为CTE是您所需要的,例如:
with dataset as (select datasetid
from Reportingdatasetmembers
where ReportingDatasetID = param_in_ReportingDataSetID)
select ...
from some_table_1
where ...
and datasetid in (select datasetid from dataset)
union all
select ...
from some_table_2
where ...
and datasetid in (select datasetid from dataset);
创建变量v_查询long; 和 然后宣布 v_query:='从Reportingdatasetmembers中选择datasetid 其中ReportingDatasetID='ReportingDatasetID中的参数' 然后调用v_查询
虽然没有尝试过,但在Oracle中已经运行了好几次在SQL Server中确实可以做到这一点。声明类型为定义记录表的变量。比如:
type my_rec_type is record (v_datasetid number(20))
type my_table_type is table of my_rec_type index by pls_integer;
my_table_var my_table_type;
。。。定义光标的参数
v_paramReportingDataSetID number(20);
fetch my_cursor bulk collect into my_table_var;
。。。在代码中,您将把它设置为一个特定的ID
v_paramReportingDataSetID:= 12345;
。。。将游标与语句一起使用
open my_cursor for (select datasetid from Reportingdatasetmembers
where ReportingDatasetID = :v_paramReportingDataSetID);
。。。从光标填充表格变量
v_paramReportingDataSetID number(20);
fetch my_cursor bulk collect into my_table_var;
。。。现在,table/array/data位于my_table\u var变量中,可用于代码的其余部分。@Boneist的方法是正确的,但我认为您应该向select添加materialize提示。所以它来得更快
with dataset as (select /*+ materialize */
datasetid
from Reportingdatasetmembers
where ReportingDatasetID = param_in_ReportingDataSetID)
select ...
from some_table_1
where ...
and datasetid in (select datasetid from dataset)
union all
select ...
from some_table_2
where ...
and datasetid in (select datasetid from dataset);
ReportingDataSetID中的param_是一个动态值,还是一个固定值?它是动态的一个数字参数可能是重用代码的一个很好的方法,但我认为它们不接受参数。有没有理由不在FROM子句中加入Reportingdatasetmembers?这仅仅是一个简化的例子吗?也许可以将其加入到每个查询中。但是正在寻找一种减少冗余代码的方法,要小心;Materialize是一个未记录的提示,因此它的行为可能会改变。我不建议在生产代码中使用它。我遇到了一个由这个提示引起的错误,所以我格外小心!此外,如果子查询在查询中的多个位置使用,Oracle很可能会决定具体化它。有没有一种不用支付罚金的方法来实现它?我希望在不强制oracle首先独立执行的情况下使用子查询将时间乘以。有“内联”提示,但请记住,它不是一个有文档记录的提示,而且它不太可能有文档记录我在最近的UKOUG tech18会议上向我确认的一个事实,对此我很难过,所以在你的产品代码中要小心。另一种选择是使用全局临时表GTT来保存数据,如果不需要具体化子查询,则可以对GTT进行索引。