如何在Oracle中转发声明?

时间:2011-04-23 01:06:40

标签: oracle user-defined-types

这是我的情况:类型A希望有一个方法返回一个类型为A条目的表的类型。我可以这样做吗?

1 个答案:

答案 0 :(得分:6)

这是一对SQL Type声明:

SQL> create or replace type a as object
  2      ( attr1 number
  3        , attr2 date )
  4  /

Type created.

SQL> create or replace type a_nt as table of a
  2  /

Type created.

SQL>

现在我们想要的是一个返回A_NT()的方法。嗯,让我们看看:

SQL> alter type a
  2      add member function getme (p1 number) return a_nt
  3  /
alter type a
*
ERROR at line 1:
ORA-04055: Aborted: "A" formed a non-REF mutually-dependent cycle with "A_NT".


SQL>

糟糕,我们需要另一种方法。这是我们应该使用继承的那种场合。

SQL> create or replace type abstract_a as object
  2      ( attr1 number
  3        , attr2 date )
  4  not final not instantiable
  5  /

Type created.

SQL> create or replace type a_nt as table of abstract_a
  2  /

Type created.

SQL> create or replace type a under abstract_a
  2      ( member function getme (p1 number) return a_nt )
  3  instantiable
  4  /

Type created.

SQL>

看起来不错。因此,我们将添加一个实现,然后尝试一下:

SQL> create or replace type body a as
  2      member function getme (p1 number) return a_nt
  3      is
  4          l_nt a_nt;
  5      begin
  6          select a(empno, hiredate)
  7          bulk collect into l_nt
  8          from emp
  9          where deptno = p1;
 10          return l_nt;
 11      end;
 12  end;
 13  /

Type body created.

SQL>

让我们滚!

SQL> set serveroutput on
SQL> declare
  2      v a := a(null, null);
  3      n a_nt;
  4  begin
  5      n := v.getme(50);
  6
  7      for i in n.first()..n.last() loop
  8          dbms_output.put_line(n(i).attr1 ||'::'||to_char(n(i).attr2, 'DD-MON-YYYY'));
  9      end loop;
 10  end;
 11  /
8085::08-APR-2010
8060::08-APR-2008
8061::27-FEB-2010
8100::

PL/SQL procedure successfully completed.

SQL>

引导很麻烦,但它很有效。这可能是Oracle的OOP实现不完整的另一个领域。但也许这只是一个事实的反映,这不是一个好主意。我花了一段时间才弄清楚,因为底层模型并没有真正有意义。虽然可能有真实世界的名字,但它会变得很明显:)