2011-01-31 53 views
2

我使用的是Oracle 11g,和我有很多的使用相同的SELECT语句(而是一个复杂的一个)存储过程的代码,只是在不同的输入where子句:使用表变量/全局临时表实现代码PL/SQL函数

select ... where ancestor = X 

这SELECT语句现在被复制/粘贴在数以百计的这些,我需要重构,以便它们使用相同的SELECT语句建设。因为所有这些存储的特效已经存在,重构必须与当前的代码很好地工作,它看起来像这样:

create or replace procedure Foo 
begin 
    select quantity, amount from TBRawData, (select ... where ancestor = X) temp, where TBRAWData.StoreID = temp.StoreID; 
end; 

概括地说,我需要规范一个SELECT的PL/SQL的手段,而是一个参考游标,数组类型,集合等将不起作用,因为它们不像表格一样处理(因此不能将它们内联到TBRAWData中)。全球临时表会在这里工作吗?还是其他什么东西?

请帮忙!

回答

4

查看是很好的答案(感谢加里),但还有另一种可能性。

您可以创建数据库模式和表型对象类型中引用它:

create or replace type TFooDataRecord as object (
    quantity number, 
    amount number 
); 

create or replace type TFooDataList as table of TFooDataRecord; 

然后,声明函数返回所需的结果:

create or replace function GetFoo(pAncestor in number) return TFooDataList 
as 
    vResult TFooDataList; 
begin 

    select TFooDataRecord(quantity, amount) 
    bulk collect into vResult 
    from TBRawData, (select ... where ancestor = pAncestor) temp, 
    where TBRAWData.StoreID = temp.StoreID; 

    return vResult; 

end; 

然后,你可以在SELECT语句中使用的功能和加入:

select foo_func.amount 
from 
    table(GetFoo(123)) foo_func, 
    some_another_table foo2 
where 
    foo_func.quantity < foo2.quantity 

当然,您可以将函数放入pac卡格。 但不是对象和表类型声明。

适用,如果函数返回的行数是不是太大该解决方案(取决于服务器硬件,但一般不超过1000-2000记录)。

它不是使用的观点,因为甲骨文将维持参数化查询单编译和高速缓存的计划,不重建它对于每个查询,如与View解决方案的情况下更好。

+0

这正是我需要的。非常感谢!由于过去的性能问题,我有点害怕,所以这是一个很好的解决方案。 – Echiban 2011-02-04 22:51:24

2

以何种方式复杂?

如果您在讨论SELECTed表达式,请看virtual columns 视图可以是封装查询复杂性的好方法。我通常会将选定的列放入连接谓词中,并将过滤器谓词留给调用查询。

例如,如果我有

SELECT a.col_a1, a.col_a2, b.col_b3 
FROM table_a a join table_b b on a.col_a1 = b.col_b1 
WHERE b.col_b4 = 'Blue' 

我会

CREATE VIEW v_1 AS 
SELECT a.col_a1, a.col_a2, b.col_b3, b.col_b4 
FROM table_a a join table_b b on a.col_a1 = b.col_b1 

SELECT v_1.col_a1, v_1.col_a2, v_1.col_b3 
FROM v_1 
WHERE v_1.col_b4 = 'Blue' 

有时意见,可以复杂,迷惑优化器(和我有非常不好的经验结合视图和数据库链接)。