执行视图的子查询

时间:2014-07-28 07:11:54

标签: sql oracle

我有一个相当大的视图使用" WITH"声明。我使用相互建立的小的,可理解的子查询来构建视图的逻辑。

结果是一个结构清晰的SQL,我相信即使你不是创造者也很好。

我的问题是将来调试问题。如果在某个阶段,同事想要了解如何计算视图的结果,那么执行某些子查询是一种很好的方法。

通常的做法是将视图的SQL复制到SQL编辑器(例如SQL-Developer),并将主语句替换为您感兴趣的子查询。

示例:

WITH 
all_orders AS (
   SELECT order, price ... FROM ...
),

all_customers AS (
    SELECT id, 
           last_name, 
           first_name, 
           first_order_date ... 
    FROM...
),

new_customers AS (
    SELECT id, 
           last_name, 
           first_name 
    FROM all_customers
    WHERE first_order_date > ...
)

-- main SQL
SELECT ... FROM all_orders a
INNER JOIN new_customers ON (...)

如果我觉得" new_customers"我会注释掉主SQL并将其替换为:

...
-- main SQL
-- SELECT ... FROM all_orders a
-- INNER JOIN new_customers ON (...)

SELECT * FROM new_customers;

如果我发现new_customers包含错误的数据,我想检查是否至少它的来源" all_customers"是的,我用

再次替换我的主SQL
...
-- main SQL
-- SELECT ... FROM all_orders a
-- INNER JOIN new_customers ON (...)

SELECT * FROM all_customers;

这非常有效但是只要SQL在视图中,我就只能访问主SQL的结果作为视图的正常输出。

但是,对于简单的调试(意思是没有进入SQL编辑器,查找视图定义并将SQL复制到SQL编辑器),我可以说有一些数据库函数非常有用:

SELECT * FROM RUN_SUBQUERY('my_view_name', 'new_customers');

我的问题:是否有这样的数据库函数或类似方法可以让我快速执行数据库视图的子查询而不将逻辑拆分为子视图?

请参阅下文,了解我对子视图的体验。

替代

  1. 在单独的较小视图中拆分大视图:
    • 我试过这个。 SQL的执行速度下降了10倍。由于速度太慢,我也在考虑一些可能的优化 - 但是,当它在一个语句中时,我已经看到它运行得很好/因此,很难证明这里的额外努力是正确的。同样,我只需要子查询结果进行调试。
  2. 保留大视图并将其拆分为较小的视图,这些视图仅用于调试:
    • 这可能是一种方法,但我们都知道在两个地方定义逻辑绝不是一个好主意(干)。

1 个答案:

答案 0 :(得分:0)

您可以使用返回记录表的函数。 在此函数中,您可以根据输入参数以不同方式构造sql并使用游标返回结果。

例如:

select * from table(cast(run_subquery('my_view_name','new_customers' as a_table_of_records_type));

并调用函数run_subquery:

function RUN_SUBQUERY (VNAME IN VARCHAR2,QNAME IN VARCHAR2)
return a_table_of_records_type is
    query_string varchar2(4000);
begin
  if VNAME = '...' then
    query_string := query_string || '....';
  end if;
  if VNAME = '...' then
    query_string := query_string || '....';
  end if;
  -- Execute string through refcursor and put the output in a_table_of_records_type
  return a_table_of_records_type;
end;