可以通过使用继承和多态来构建处理这些字符串的通用方法。如果我们要使用对象,我们应该利用面向对象编程的能力。
首先我们需要一个根对象。此 TYPE 不可实例化,这意味着我们实际上无法声明它的实例。请注意,TO_STRING() 成员函数也被声明为 NOT INSTANTIABLE。这意味着任何继承自 STRINGABLE_TYPE 的 TYPE 都必须有自己的方法实现。
SQL> create or replace type stringable_type as object
2 ( id number(7,0)
3 , NOT INSTANTIABLE member function to_string
4 return varchar2
5 )
6 not final not instantiable
7 /
Type created.
SQL>
这是一种继承自 STRINGABLE_TYPE 的类型。 OVERRIDING 关键字是强制性的,即使父类型的声明迫使我们实现它。
SQL> create or replace type emp_type under stringable_type
2 ( empno number(7,0)
3 , ename varchar2(20)
4 , sal number(7,2)
5 , OVERRIDING member function to_string
6 return varchar2
7 );
8 /
Type created.
SQL> create or replace type body emp_type
2 is
3 OVERRIDING member function to_string
4 return varchar2
5 is
6 begin
7 return 'EMP>>'||self.id||'='||self.empno||'::'||self.ename||'::'||self.sal;
8 end;
9 end;
10 /
Type body created.
SQL>
这是另一种类型...
SQL> create or replace type dept_type under stringable_type
2 ( deptno number(2,0)
3 , dname varchar2(30)
4 , OVERRIDING member function to_string
5 return varchar2
6 );
7 /
Type created.
SQL> create or replace type body dept_type
2 is
3 OVERRIDING member function to_string
4 return varchar2
5 is
6 begin
7 return 'DEPT>>'||self.id||'='||self.deptno||'::'||self.dname;
8 end;
9 end;
10 /
Type body created.
SQL>
现在,我们可以创建一个接受泛型类型并调用泛型方法的函数:
SQL> create or replace function type_to_string
2 (p_obj in stringable_type)
3 return varchar2
4 is
5 begin
6 return p_obj.to_string();
7 end;
8 /
Function created.
SQL>
通过多态的奇迹,我们可以将两个不同的对象传递给函数,它实际上将执行覆盖方法:
SQL> set serveroutput on
SQL> declare
2 obj1 emp_type;
3 obj2 dept_type;
4 begin
5 obj1 := emp_type(1, 8000, 'VAN WIJK', 3500);
6 obj2 := dept_type(2, 20, 'COMMUNICATIONS');
7 dbms_output.put_line(type_to_string(obj1));
8 dbms_output.put_line(type_to_string(obj2));
9 end;
10 /
EMP>>1=8000::VAN WIJK::3500
DEPT>>2=20::COMMUNICATIONS
PL/SQL procedure successfully completed.
SQL>
要达到这一点需要做很多工作。如果 Oracle 的 TYPE 至少有一个抽象的 TO_STRING() ,我们可以直接覆盖它,那就太好了。但这只是他们的对象实现中许多松散的结局之一 8-)