比较两种Oracle类型的每列中的值

比较两种Oracle类型的每列中的值,oracle,plsql,Oracle,Plsql,我今天一直在玩,我想用它把一些现有的功能放到一个测试工具中 我有很多这种规格的函数 FUNCTION DO_SOME_STUFF (pOldSchedule IN SCHEDULE_OBJ, pNewSchedule OUT SCHEDULE_OBJ, pLoggerContext IN OUT LOGGER_CONTE

我今天一直在玩,我想用它把一些现有的功能放到一个测试工具中

我有很多这种规格的函数

   FUNCTION DO_SOME_STUFF   (pOldSchedule       IN      SCHEDULE_OBJ,
                             pNewSchedule          OUT  SCHEDULE_OBJ,
                             pLoggerContext     IN OUT  LOGGER_CONTEXT_OBJ)
   RETURN NUMBER;
它接受pOldSchedule,对其执行一些操作,然后返回pNewSchedule。logger_上下文只做日志记录

作为测试的一部分,我希望能够比较类型的每个列中的值,而不必编写单独的IF语句

它需要返回布尔值来表示pOldSchedule和pNewSchedule是否匹配


有什么想法吗?

简单的相等性测试可用于嵌套表:

SQL> declare
  2      type nt is table of number;
  3      nt1 nt;
  4      nt2 nt;
  5      nt3 nt;
  6  begin
  7      nt1 := nt(1,2,3);
  8      nt2 := nt(1,2,3);
  9      if nt1 = nt2 then
 10          dbms_output.put_line('NT2 is the same nested table as NT1');
 11      else
 12          dbms_output.put_line('NT2 is a different nested table from NT1');
 13      end if;
 14      nt2 := nt(1,2,3,4);
 15      if nt1 = nt3 then
 16          dbms_output.put_line('NT3 is the same nested table as NT1');
 17      else
 18          dbms_output.put_line('E3 is a different nested table from NT1');
 19      end if;
 20  end;
 21  /
NT2 is the same nested table as NT1
E3 is a different nested table from NT1

PL/SQL procedure successfully completed.

SQL>
但是,完全打开对象的情况并非如此:

SQL> create or replace type new_emp as object (
  2      ename varchar2(10)
  3      , sal number
  4      , deptno number
  5      , job varchar2(10))
  6  /

Type created.

SQL> declare
  2      e1 new_emp;
  3      e2 new_emp;
  4  begin
  5      e1 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
  6      e2 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
  7      if e1 = e2 then
  8          dbms_output.put_line('E2 is the same as E1');
  9      else
 10          dbms_output.put_line('E2 is different from E1');
 11      end if;
 12  end;
 13  /
    if e1 = e2 then
          *
ERROR at line 7:
ORA-06550: line 7, column 11:
PLS-00526: A MAP or ORDER function is required for comparing objects in PL/SQL.


SQL>
我们需要显式定义一个成员函数来执行比较。这是同一个对象,有一个映射函数。示例实现生成了一个散列字符串,如果我们希望存储该值以供以后比较,这非常有用,但它可以只返回连接的字符串(特别是在默认情况下不授予在DBMS_CRYPTO上执行)。NVL()函数对于避免(null,value)和(value,null)被计算为相等是必需的。使用魔法值总是有风险的,所以我们需要仔细选择它们

SQL> create or replace type new_emp as object (
  2      ename varchar2(10)
  3      , sal number
  4      , deptno number
  5      , job varchar2(10)
  6      , map member function equals return raw)
  7  /

Type created.

SQL> create or replace type body new_emp as
  2      map member function equals return raw
  3      is
  4      begin
  5          return dbms_crypto.hash(
  6                     utl_raw.cast_to_raw(nvl(self.ename,'***')||
  7                                          nvl(self.sal,-99)||
  8                                          nvl(self.deptno,-99)||
  9                                          nvl(self.job,'***')
 10                                        )
 11                                   , 1);
 12      end equals;
 13  end;
 14  /

Type body created.

SQL>
现在我们有了比较对象实例的基础:

SQL> declare
  2      e1 new_emp;
  3      e2 new_emp;
  4  begin
  5      e1 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
  6      e2 := new_emp('KESTELYN', 3700, 30, 'MARKETING');
  7      if e1 = e2 then
  8          dbms_output.put_line('E2 is the same as E1');
  9      else
 10          dbms_output.put_line('E2 is different from E1');
 11      end if;
 12  end;
 13  /
E2 is the same as E1

PL/SQL procedure successfully completed.

SQL>    
您可能想知道为什么Oracle在默认情况下不这样做。嗯,类型实现只允许一种比较方法(如果我们有一个MAP函数,我们就不能有ORDER函数),所以我们需要有能力选择我们自己的相等定义。例如,一个名为
rectangle
的类型可能有一个名为
area()
的映射函数,该函数返回
self.width*self.length