Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 如何重用子查询_Oracle_Oracle11g_Subquery - Fatal编程技术网

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进行索引。