多次调用Oracle对象类型构造函数

时间:2014-12-09 17:00:27

标签: oracle

我有一个带有自定义构造函数的对象类型。在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

1 个答案:

答案 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

Oracle Object Type Constructor Called Multiple Times