【问题标题】:PL/SQL for implode function on custom typesPL/SQL 用于自定义类型的内爆函数
【发布时间】:2011-10-19 05:32:59
【问题描述】:

有没有办法在 PL/SQL 中创建一个内爆例程,该例程将任何自定义数据类型作为参数并连接其成员,由某个指定的字符串分隔?

例如,假设我有以下类型:

CREATE TYPE myPerson AS OBJECT(
  forename VARCHAR2(50),
  surname  VARCHAR2(50),
  age      NUMBER
);

然后,假设一个函数返回一个 myPerson 类型的对象,但我希望将列连接在一起:

SELECT implode(getPerson(1234),'$$') from dual;

返回(假设这个人为示例中的数据已设置):

John$$Doe$$55

其中分隔符可以指定为可选参数,但第一个参数的类型可以是任何类型(不一定是myPerson)。

【问题讨论】:

    标签: oracle object plsql concatenation sql-types


    【解决方案1】:

    可以通过使用继承和多态来构建处理这些字符串的通用方法。如果我们要使用对象,我们应该利用面向对象编程的能力。

    首先我们需要一个根对象。此 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-)

    【讨论】:

    • 对象类型的伟大继承示例!
    【解决方案2】:

    您的自定义数据类型可以支持方法并且方法可以有参数。

    CREATE TYPE myPerson AS OBJECT(   
      forename VARCHAR2(50),   
      surname  VARCHAR2(50),   
      age      NUMBER,
    
      MEMBER FUNCTION
      get_record(pGlue IN varchar2)   RETURN VARCHAR2 );
    
    CREATE TYPE BODY myPerson 
    AS 
       MEMBER FUNCTION get_record(pGlue varchar2) RETURN VARCHAR2
    
     IS
    BEGIN
     RETURN forename || pGlue  || surname  || pGlue || age ;
    END get_record;
    
    END;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      相关资源
      最近更新 更多