我有一个带有自定义构造函数的对象类型。在SQL中,当我引用属性时,构造函数被多次调用。
我目前的工作是引用属性并使用/ * + materialize * / hint。
问题设置
create or replace type Foo as object
(
Bar1 NUMBER,
Bar2 NUMBER,
Bar3 NUMBER,
CONSTRUCTOR FUNCTION Foo(p_Bar1 NUMBER, p_Bar2 NUMBER, p_Bar3 NUMBER)
RETURN SELF AS RESULT
DETERMINISTIC
)
create or replace type body Foo is
-- Member procedures and functions
CONSTRUCTOR FUNCTION Foo(p_Bar1 NUMBER, p_Bar2 NUMBER, p_Bar3 NUMBER)
RETURN SELF AS RESULT
DETERMINISTIC
AS
BEGIN
SELF.Bar1 := p_Bar1;
SELF.Bar2 := p_Bar2;
SELF.Bar3 := p_Bar3;
dbms_output.put_line('Foo Constructor Called');
RETURN;
END;
end;
问题
-- Constructor is called 6 times!
-- Once for each column and once for each predicate in the where clause.
SELECT x.f.bar1 AS bar1, x.f.bar2 AS bar2, x.f.bar3 AS bar3, f
FROM (
SELECT foo(p_Bar1 => 1, p_Bar2 => 2, p_Bar3 => 3) f
FROM dual d
) x
WHERE x.f.bar1 = x.f.bar1 AND x.f.bar2 = x.f.bar2
解决方法
-- Work Around
-- Constructor is called 3 times
-- Once for each column in the inline view.
-- Note, I removed column f (the object type) because it's not compatible with the materialize hint.
WITH y AS (
SELECT /*+ materialize */ x.f.bar1 AS bar1, x.f.bar2 AS bar2, x.f.bar3 AS bar3
FROM (
SELECT foo(p_Bar1 => 1, p_Bar2 => 2, p_Bar3 => 3) f
FROM dual d
) x
)
SELECT y.bar1, y.bar2, y.bar3
FROM y
WHERE y.bar1 = y.bar1 AND y.bar2 = y.bar2
答案 0 :(得分:0)
使用与表格运算符相结合的集合类型。
create or replace type FooTable as table of Foo;
SELECT x.bar1 AS bar1, x.bar2 AS bar2, x.bar3 AS bar3, value(x) f
FROM table(FooTable(
foo(p_Bar1 => 1, p_Bar2 => 2, p_Bar3 => 3)
)) x
WHERE x.bar1 = x.bar1 AND x.bar2 = x.bar2
;
BAR1 BAR2 BAR2 F
1 2 3 (1, 2, 3)
Foo Constructor Called
来自Oracle论坛的gaverill。